srtp_init() randomly fails to initialize. If libsrtp.a
and test program is compiled with profiling enabled,
failures happen much more often.
System information:
Linux, Fedora Core 4, gcc-4.0.2 (compiling libsrtp with
gcc-3.2 does not help)
libsrtp-1.4.1 (similar problems also with recent CVS
version)
Test script (sources inside it) is included below
------------------------------------------
#! /bin/sh
echo '#include <srtp/srtp.h>
#include <stdio.h>
int main(void)
{
err_status_t status;
status = srtp_init();
printf ("srtp_init %s\n", status ? "failed" :
"suceeded");
return status;
}' | gcc -O2 -x c - -lsrtp -o srtp_bad || exit 1
tests=0
bad=0
while true; do
tests=$(($tests+1))
if ./srtp_bad | grep -q failed ; then
bad=$(($bad+1))
echo "$bad errors of $tests tests"
fi
done
Logged In: YES
user_id=42491
Here is sample of output of script:
bash-3.00$ sh 1.sh
1 errors of 30 tests
2 errors of 115 tests
3 errors of 454 tests
Logged In: YES
user_id=438614
Originator: NO
Hi,
I've seen something similar that I assume may be related. I'm using srtp-1.4.2, but the same issue likely applies to the CVS HEAD.
Symptoms:
Initializing the ciphers does fail randomly (FC1, 2.4.22 kernel), resulting in either crypto_kernel_init() to fail (running the crypto_kernel test) or cipher self-tests (when running cipher_driver test).
I tracked it down to the handling of the /dev/urandom device (srtp/crypto/rng/rand_source.c).
rand_source_get_octet_string() tries to read a specific number of random bytes from the /dev/urandom device (ok, the actual device depends on what ./configure spits out).
Reading data from /dev/urandom does not guarantee to return exactly the amount of bytes as requested in the read() call, it may be less. rand_source_get_octet_string() does exit with failure in such a case.
Not getting all random bytes in first attempt is actually not a failure, it just means that the PRNG is currently out of random bytes. A subsequent read should be made to fetch the missing amount of data until finished.
original code fragment:
if (read(dev_random_fdes, dest, len) != len) return err_status_fail;
proposed new code fragment:
int num=0;
int total=0;
while (len > 0) {
num = read(dev_random_fdes, &dest[total], len);
if (num > 0) { total += num; len -= num; }
if (num <=0) { return err_status_fail; }
}
After that, the self test runs properly with stable success results.
/Thomas
This should now be fixed in CVS.