No data added into context

Выполнение хэш- операция в пустом контексте может привести к ошибкам времени выполнения

Описание

Дефект возникает, когда вы только обновляете контекст дайджеста сообщений с помощью нулевых данных или вы выполняете последний шаг в контексте дайджеста сообщений, не выполняя никакого шага обновления.

Когда вы используете функции дайджеста сообщений, вы обычно инициализируете контекст дайджеста сообщений и выполняете по крайней мере один шаг обновления, чтобы добавить данные в контекст. Затем вы подписываете, проверяете или извлекаете данные в контексте в качестве последнего шага.

Проверка не поднимает дефект, если нет доступной информации о контексте. Например, если контекст передается как аргумент функции, которая вызывает операцию хеширования, или если контекст объявлен вне возможностей функции. Для примера в этом фрагменте кода дефект не возникает.

void bar(unsigned char* src, int len, EVP_MD_CTX *ctx) {
    //ctx passed as argument of bar()
    EVP_DigestFinal(ctx, out_buf, &out_len); //no defect
}
EVP_MD_CTX glob_ctx;
void foo(unsigned char* src, int len) {
    //glob_ctx declared outside scope of foo()
    EVP_DigestFinal(&glob_ctx, out_buf, &out_len); //no defect
}

Риск

Выполнение шага обновления для контекста с нулевыми данными может привести к ошибке времени выполнения.

Выполнение последнего шага в контексте без данных может привести к неожиданному поведению.

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

Выполните по крайней мере одну операцию обновления с ненулевыми данными в контексте дайджеста сообщений, прежде чем подписывать, проверять или извлекать данные в контексте.

Примеры

расширить все

#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);


    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, len);
    EVP_MD_CTX_init(&ctx);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
}

В этом примере контекст дайджеста сообщений ctx инициализируется, и выполняется операция обновления, чтобы добавить данные src в контекст. Контекст затем инициализируется повторно, но данные не добавляются в ctx перед EVP_DigestFinal попытка извлечь данные из ctx, что приводит к ошибке.

Коррекция - Выполните заключительный шаг перед повторной инициализацией контекста

Одной из возможных коррекций является выполнение последнего шага, который извлекает данные из контекста перед повторной инициализацией контекста.

#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);


    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, len);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
    EVP_MD_CTX_init(&ctx);
} 
#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);
    size_t cnt = 0;

    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, cnt);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
}

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

Коррекция - добавление ненулевых данных в контекст

Возможной коррекцией является добавление данных в контекст во время шага обновления перед извлечением данных из контекста.

#include <openssl/evp.h>
#include <stdio.h>

unsigned char out_buf[EVP_MAX_MD_SIZE];
unsigned int out_len;

void func(unsigned char* src, int len)
{
    EVP_MD_CTX ctx;
    EVP_MD_CTX_init(&ctx);

    EVP_DigestInit(&ctx, EVP_sha256());
    EVP_DigestUpdate(&ctx, src, len);
    EVP_DigestFinal(&ctx, out_buf, &out_len);
}

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

Группа: Криптография
Язык: C | C++
По умолчанию: Off
Синтаксис командной строки : CRYPTO_MD_NO_DATA
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 325
Введенный в R2020a