Pseudorandom number generators use mathematical algorithms to produce a sequence of numbers with good statistical properties, but the numbers produced are not genuinely random.
The C Standard function rand() (available in stdlib.h) does not have good random number properties. The numbers generated by rand() have a comparatively short cycle, and the numbers may be predictable.
The following code generates an ID with a numeric part produced by calling the rand() function. The IDs produced are predictable and have limited randomness.
enum {len = 12};
char id[len]; /* id will hold the ID, starting with
* the characters "ID" followed by a
* random integer */
int r;
int num;
/* ... */
r = rand(); /* generate a random integer */
num = snprintf(id, len, "ID%-d", r); /* generate the ID */
/* ... */
|
A better pseudorandom number generator is the random() function. While the low dozen bits generated by rand() go through a cyclic pattern, all the bits generated by random() are usable.
enum {len = 12};
char id[len]; /* id will hold the ID, starting with
* the characters "ID" followed by a
* random integer */
int r;
int num;
/* ... */
time_t now = time(NULL);
if (now == (time_t) -1) {
/* handle error */
}
srandom(now); /* seed the PRNG with the current time */
/* ... */
r = random(); /* generate a random integer */
num = snprintf(id, len, "ID%-d", r); /* generate the ID */
/* ... */
|
The rand48 family of functions provides another alternative for pseudorandom numbers.
Although not specified by POSIX, arc4random() is an option on systems that support it. From the arc4random(3) manual page:
To achieve the best random numbers possible, an implementation-specific function must be used. When unpredictability really matters and speed is not an issue, such as in the creation of strong cryptographic keys, use a true entropy source such as
arc4random()fits into a middle ground not covered by other subsystems such as the strong, slow, and resource expensive random devices described inrandom(4)versus the fast but poor quality interfaces described inrand(3),random(3), anddrand48(3).
/dev/random or a hardware device capable of generating random numbers. Note that the /dev/random device may block for a long time if there are not enough events going on to generate sufficient entropy.
On Windows platforms, the [{{CryptGenRandom()}}|http://msdn2.microsoft.com/en-us/library/aa379942.aspx] function may be used to generate cryptographically strong random numbers. Note that the exact details of the implementation are unknown including, for example, what source of entropy {{CryptGenRandom()}} uses. From the Microsoft Developer Network {{CryptGenRandom()}} reference \[[MSDN|AA. Bibliography#MSDN]\]: |
If an application has access to a good random source, it can fill the {{pbBuffer}} buffer with some random data before calling {{CryptGenRandom()}}. The CSP \[cryptographic service provider\] then uses this data to further randomize its internal seed. It is acceptable to omit the step of initializing the {{pbBuffer}} buffer before calling {{CryptGenRandom()}}.
#include<Wincrypt.h>
HCRYPTPROV hCryptProv;
union {
BYTE bs[sizeof(long int)];
long int li;
} rand_buf;
if (!CryptGenRandom(hCryptProv, sizeof(rand_buf), &rand_buf) {
/* Handle error */
} else {
printf("Random number: %ld\n", rand_buf.li);
}
|
Using the rand() function leads to possibly predictable random numbers.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
|---|---|---|---|---|---|
MSC30-C |
medium |
unlikely |
low |
P6 |
L2 |
The LDRA tool suite V 7.6.0 can detect violations of this rule.
Fortify SCA Version 5.0 with CERT C Rule Pack can detect violations of this rule.
Compass/ROSE can detect violations of this rule.
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
This rule appears in the C++ Secure Coding Standard as MSC30-CPP. Do not use the rand() function for generating pseudorandom numbers.
This rule appears in the Java Secure Coding Standard as MSC30-J. Generate truly random numbers.
\[[ISO/IEC 9899:1999|AA. Bibliography#ISO/IEC 9899-1999]\] Section 7.20.2.1, "The rand function" \[[MITRE 07|AA. Bibliography#MITRE 07]\] [CWE ID 327|http://cwe.mitre.org/data/definitions/327.html], "Use of a Broken or Risky Cryptographic Algorithm," [CWE ID 330|http://cwe.mitre.org/data/definitions/330.html], "Use of Insufficiently Random Values" \[[MSDN|AA. Bibliography#MSDN]\] "[CryptGenRandom Function|http://msdn.microsoft.com/en-us/library/aa379942.aspx]" |
49. Miscellaneous (MSC) MSC31-C. Ensure that return values are compared against the proper type