Main Content

Missing cipher data to process

Final encryption or decryption step is performed without previous update steps

Description

This defect occurs when you perform the final step of a block cipher encryption or decryption incorrectly.

For instance, you do one of the following:

  • You do not perform update steps for encrypting or decrypting the data before performing a final step.

    /* Initialization of cipher context */
    ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    ...
    /* Missing update step */
    ...
    /* Final step */
    ret = EVP_EncryptFinal_ex(ctx, out_buf, &out_len);
  • You perform consecutive final steps without intermediate initialization and update steps.

    /* Initialization of cipher context */
    ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    ...
    /* Update step(s) */
    ret = EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);
    ...
    /* Final step */
    ret = EVP_EncryptFinal_ex(ctx, out_buf, &out_len);
    ...
    /* Missing initialization and update */
    ...
    /* Second final step */
    ret = EVP_EncryptFinal_ex(ctx, out_buf, &out_len);
  • You perform a cleanup of the cipher context and then perform a final step.

    /* Initialization of cipher context */
    ret = EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    ...
    /* Update step(s) */
    ret = EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);
    ...
    /* Cleanup of cipher context */
    EVP_CIPHER_CTX_cleanup(ctx);
    ...
    /* Second final step */
    ret = EVP_EncryptFinal_ex(ctx, out_buf, &out_len);

Risk

Block ciphers break your data into blocks of fixed size. During encryption or decryption, the update step encrypts or decrypts your data in blocks. Any leftover data is encrypted or decrypted by the final step. The final step adds padding to the leftover data so that it occupies one block, and then encrypts or decrypts the padded data.

If you perform the final step before performing the update steps, or perform the final step when there is no data to process, the behavior is undefined. You can also encounter run-time errors.

Fix

Perform encryption or decryption in this sequence:

  • Initialization of cipher context

  • Update steps

  • Final step

  • Cleanup of context

Examples

expand all


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

unsigned char *out_buf;
int out_len;
unsigned char key[SIZE16];
unsigned char iv[SIZE16];

void func(void) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    /* Initialization of cipher context */
    EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    /* Missing update steps for encryption */
    
    /* Final encryption step */
    EVP_EncryptFinal_ex(ctx, out_buf, &out_len);           
}

In this example, after the cipher context is initialized, there are no update steps for encrypting the data. The update steps are supposed to encrypt one or more blocks of data, leaving the final step to encrypt data that is left over in a partial block. If you perform the final step without previous update steps, the behavior is undefined.

Correction — Perform Update Steps for Encryption Before Final Step

Perform update steps for encryption before the final step. In the corrected code below, the routine EVP_EncryptUpdate performs the update steps.


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

unsigned char *out_buf;
int out_len;
unsigned char key[SIZE16];
unsigned char iv[SIZE16];

void func(unsigned char *src, int len) {
    EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
    EVP_CIPHER_CTX_init(ctx);

    /* Initialization of cipher context */
    EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv);
    
    /* Update steps for encryption */
    EVP_EncryptUpdate(ctx, out_buf, &out_len, src, len);   
    
    /* Final encryption step */
    EVP_EncryptFinal_ex(ctx, out_buf, &out_len);           
}

Result Information

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

Version History

Introduced in R2017a