Main Content

Predictable block cipher initialization vector

Initialization vector is generated from a weak random number generator

Description

This defect occurs when you use a weak random number generator for the block cipher initialization vector.

Risk

If you use a weak random number generator for the initiation vector, your data is vulnerable to dictionary attacks.

Block ciphers break your data into blocks of fixed size. Block cipher modes such as CBC (Cipher Block Chaining) protect against dictionary attacks by XOR-ing each block with the encrypted output from the previous block. To protect the first block, these modes use a random initialization vector (IV). If you use a weak random number generator for your IV, your data becomes vulnerable to dictionary attacks.

Fix

Use a strong pseudo-random number generator (PRNG) for the initialization vector. For instance, use:

  • OS-level PRNG such as /dev/random on UNIX® or CryptGenRandom() on Windows®

  • Application-level PRNG such as Advanced Encryption Standard (AES) in Counter (CTR) mode, HMAC-SHA1, etc.

For a list of random number generators that are cryptographically weak, see Vulnerable pseudo-random number generator.

Examples

expand all

#include <openssl/evp.h>
#include <openssl/rand.h>
#include <stdlib.h>
#define SIZE16 16

int func(EVP_CIPHER_CTX *ctx, unsigned char *key){
    unsigned char iv[SIZE16];
    RAND_pseudo_bytes(iv, 16);
    return EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1); 
}

In this example, the function RAND_pseudo_bytes declared in openssl/rand.h produces the initialization vector. The byte sequences that RAND_pseudo_bytes generates are not necessarily unpredictable.

Correction — Use Strong Random Number Generator

Use a strong random number generator to produce the initialization vector. The corrected code here uses the function RAND_bytes declared in openssl/rand.h.


#include <openssl/evp.h>
#include <openssl/rand.h>
#include <stdlib.h>
#define SIZE16 16

int func(EVP_CIPHER_CTX *ctx, unsigned char *key){
    unsigned char iv[SIZE16];
    RAND_bytes(iv, 16);
    return EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv, 1); 
}

Result Information

Group: Cryptography
Language: C | C++
Default: Off
Command-Line Syntax: CRYPTO_CIPHER_PREDICTABLE_IV
Impact: Medium

Version History

Introduced in R2017a