Main Content

Vulnerable pseudo-random number generator

Using a cryptographically weak pseudo-random number generator

Description

This defect occurs when you use cryptographically weak pseudo-random number generator (PRNG) routines.

The list of cryptographically weak routines flagged by this checker include:

  • rand, random

  • drand48, lrand48, mrand48, erand48, nrand48, jrand48, and their _r equivalents such as drand48_r

  • RAND_pseudo_bytes

Risk

These cryptographically weak routines are predictable and must not be used for security purposes. When a predictable random value controls the execution flow, your program is vulnerable to malicious attacks.

Fix

Use more cryptographically sound random number generators, such as CryptGenRandom (Windows), OpenSSL/RAND_bytes(Linux/UNIX).

Examples

expand all

#include <stdio.h>
#include <stdlib.h>

volatile int rd = 1;
int main(int argc, char *argv[])
{   
    int j, r, nloops;
    struct random_data buf;
    int i = 0;
    
    nloops = rand();
    
    for (j = 0; j < nloops; j++) {
        if (random_r(&buf, &i))
            exit(1);
        printf("random_r: %ld\n", (long)i);
    }
    return 0;
}

This example uses the functions rand() and random_r() to generate random numbers. If you use these functions for security purposes, these PRNGs can be the source of malicious attacks.

Correction — Use Stronger PRNG

One possible correction is to replace the vulnerable PRNG with a stronger random number generator.

#include <stdio.h>
#include <stdlib.h>
#include <openssl/rand.h>

volatile int rd = 1;
int main(int argc, char* argv[])
{   
    int j, r, nloops;
    unsigned char buf;
    unsigned int seed;
    int i = 0;
    
    if (argc != 3) 
    {
        fprintf(stderr, "Usage: %s <seed> <nloops>\n", argv[0]);
        exit(EXIT_FAILURE);
    }
    
    seed = atoi(argv[1]);
    nloops = atoi(argv[2]);
    
    for (j = 0; j < nloops; j++) {
        if (RAND_bytes(&buf, i) != 1)
            exit(1);
        printf("RAND_bytes: %u\n", (unsigned)buf);
    }
    return 0;
}

Result Information

Group: Security
Language: C | C++
Default: Off
Command-Line Syntax: VULNERABLE_PRNG
Impact: Medium

Version History

Introduced in R2015b