QAT_Engine
QAT_Engine copied to clipboard
division by zero when qat_get_sha3_data_size returns zero
In function qat_sha3_update() in source qat_hw_sha3.c there is a division by zero on the corner case where qat_get_sha3_data_size() returns zero when using an unsupported hash algorithm:
- The function can return 0:
static int qat_get_sha3_data_size(int nid)
{
switch (nid) {
case NID_sha3_224:
return QAT_SHA3_224_OFFLOAD_THRESHOLD;
case NID_sha3_256:
return QAT_SHA3_256_OFFLOAD_THRESHOLD;
case NID_sha3_384:
return QAT_SHA3_384_OFFLOAD_THRESHOLD;
case NID_sha3_512:
return QAT_SHA3_512_OFFLOAD_THRESHOLD;
default:
WARN("Unsupported Hash Algorithm\n");
return 0;
}
}
- The data_size variable can potentially be assigned zero from the call to the qat_get_sha3_data_size() call:
#ifdef QAT_OPENSSL_PROVIDER
data_size = qat_get_sha3_data_size(ctx->md_type);
#else
data_size = qat_get_sha3_data_size(EVP_MD_CTX_type(ctx));
#endif
n = sha3_ctx->num;
#ifndef QAT_OPENSSL_PROVIDER
# ifndef ENABLE_QAT_SMALL_PKT_OFFLOAD
if (sha3_ctx->sw_offload ||
(len <= CRYPTO_SMALL_PACKET_OFFLOAD_THRESHOLD_DEFAULT)) {
DEBUG("Packet size < 2048, Using OpenSSL SW\n");
sha3_ctx->sw_offload = 1;
return EVP_MD_meth_get_update(GET_SW_SHA3_DIGEST(ctx))
(ctx, in, len);
}
# endif
#endif
/* Packets left from previous process */
if (n != 0) {
p = (unsigned char *)sha3_ctx->data;
/* Offload threshold met */
if (len >= data_size || len + n >= data_size) {
/* Use part of new packet filling the packet buffer */
memcpy(p + n, data, data_size - n);
qat_hw_sha3_offload(ctx, p, data_size, CPA_CY_SYM_PACKET_TYPE_PARTIAL);
/* The data left of new input */
n = data_size - n;
data += n;
len -= n;
sha3_ctx->num = 0;
/*
* We use memset rather than OPENSSL_cleanse() here deliberately.
* Using OPENSSL_cleanse() here could be a performance issue. It
* will get properly cleansed on finalisation so this isn't a
* security problem.
*/
memset(p, 0, data_size); /* keep it zeroed */
} else {
/* Append the new packets to buffer */
memcpy(p + n, data, len);
sha3_ctx->num += (unsigned int)len;
return 1;
}
}
n = len / data_size;
The assignment to n may be dividing by a zero data_size value.
Let me check on this and fix it