-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Description
When HMAC_Init_ex() returned, the secret key for HMAC was kept in the key[HMAC_MAX_MD_CBLOCK_SIZE] inside HMAC_CTX (aka 'hmac_ctx_st') in plaintext, which is a security hole: hackers can obtain the secret key for HMAC by dumping the memory. In fact, this key buffer in HMAC_CTX was not used any more after the secretKey was supplied to HMAC_Init_ex().
In OpenSSL_1.0.2, we cleaned up the key buffer ourselves:
HMAC_CTX_init(&m_ctx);
HMAC_Init_ex( &m_ctx, (const void*)(secretKey), keyLength, HashAlgo(), NULL);
// erase key buffer inside hmac ctx
memset(m_ctx.key, 0, m_ctx.key_length);
m_ctx.key_length = 0;
However, because OpenSSL_1.1.1 makes the HMAC_CTX opaque, we cannot access the key buffer in HMAC_CTX like below,
m_ctx = HMAC_CTX_new();
HMAC_Init_ex(m_ctx, (const void*)(secretKey), keyLength, HashAlgo(), NULL);
// erase key buffer inside hmac ctx
memset(m_ctx->key, 0, m_ctx->key_length);
m_ctx->key_length = 0;
we got compilation error: member access into incomplete type 'HMAC_CTX' (aka 'hmac_ctx_st') memset(m_ctx->key, 0, m_ctx->key_length);
Our experiments show that to complete 100million HMAC digests using the same key, init HMAC_CTX with secret key only once will be much faster.
Therefore, the key buffer in 'HMAC_CTX' (aka 'hmac_ctx_st') should be cleared up before HMAC_Init_ex() returns to keep good performance and avoid leaking the secret key.