exponenta event banner

Отсутствует последний шаг шифра

Вы не выполняете последний шаг после шагов обновления для шифрования или дешифрования данных

Описание

Этот дефект возникает, когда вы не выполняете последний шаг после шагов обновления для шифрования или дешифрования данных.

Например, выполняется следующее:

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

Риск

Блочные шифры разбивают данные на блоки фиксированного размера. Во время шифрования или дешифрования операция обновления шифрует или дешифрует данные в блоках. Любые оставшиеся данные шифруются или дешифруются на заключительном этапе. Последний шаг добавляет заполнение к оставшимся данным, так что он занимает один блок, а затем шифрует или дешифрует дополненные данные.

Если последний шаг не выполнен, оставшиеся в частичном блоке данные не шифруются и не расшифровываются. Вы можете столкнуться с неполным или неожиданным выводом.

Зафиксировать

После выполнения шагов обновления для шифрования или дешифрования выполните последний шаг для шифрования или дешифрования оставшихся данных.

/* 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);
...
/* Cleanup of cipher context */
EVP_CIPHER_CTX_cleanup(ctx);

Примеры

развернуть все


#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);   
    
    /* Missing final encryption step */
    
    /* Cleanup of cipher context */
    EVP_CIPHER_CTX_cleanup(ctx); 
}

В этом примере контекст шифра ctx очищается перед завершающим этапом шифрования. На заключительном этапе предполагается шифрование оставшихся данных. Без последнего шага шифрование является неполным.

Исправление - Выполнение финального шага шифрования

После выполнения шагов обновления для шифрования выполните заключительный этап шифрования, чтобы зашифровать оставшиеся данные. В приведенном ниже исправленном коде подпрограмма EVP_EncryptFinal_ex используется для выполнения последнего шага.


#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);
    
    /* Cleanup of cipher context */
    EVP_CIPHER_CTX_cleanup(ctx); 
}

Информация о результатах

Группа: Криптография
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: CRYPTO_CIPHER_NO_FINAL
Воздействие: среднее
CWE ID: 311, 325, 372, 664
Представлен в R2017a