Skip to content

Commit

Permalink
Fix another AES-GCM EVP control command issue.
Browse files Browse the repository at this point in the history
With PR 5170, I added logic that requires a EVP_CTRL_GCM_SET_IV_FIXED command be
issued before a EVP_CTRL_GCM_IV_GEN command. This matches OpenSSL's behavior.
However, OpenSSL also clears the flag enabling EVP_CTRL_GCM_IV_GEN after
EVP_CTRL_GCM_SET_IV_FIXED if EVP_CipherInit is called with a NULL key.
Otherwise, the flag retains its value. We didn't mirror this logic, and that
caused problems in OpenSSH unit testing. This commit aligns our logic with
OpenSSL's and adds a regression test to test_evp_cipher_aes_gcm for this case.
  • Loading branch information
haydenroche5 committed Jun 2, 2022
1 parent 56c48b3 commit fb3c611
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 9 deletions.
12 changes: 12 additions & 0 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -45319,8 +45319,20 @@ static void test_evp_cipher_aes_gcm(void)
if (i == 0) {
AssertIntEQ(EVP_CipherInit(encCtx, EVP_aes_256_gcm(), key, NULL, 1),
SSL_SUCCESS);

/*
* The call to EVP_CipherInit below (with NULL key) should clear the
* gcmIvGenEnable flag set by EVP_CTRL_GCM_SET_IV_FIXED. As such, a
* subsequent EVP_CTRL_GCM_IV_GEN should fail. This matches OpenSSL
* behavior.
*/
AssertIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_SET_IV_FIXED, -1,
(void*)iv), SSL_SUCCESS);
AssertIntEQ(EVP_CipherInit(encCtx, NULL, NULL, iv, 1),
SSL_SUCCESS);
AssertIntEQ(EVP_CIPHER_CTX_ctrl(encCtx, EVP_CTRL_GCM_IV_GEN, -1,
currentIv), SSL_FAILURE);

AssertIntEQ(EVP_CipherInit(decCtx, EVP_aes_256_gcm(), key, NULL, 0),
SSL_SUCCESS);
AssertIntEQ(EVP_CipherInit(decCtx, NULL, NULL, iv, 0),
Expand Down
24 changes: 15 additions & 9 deletions wolfcrypt/src/evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -5702,6 +5702,12 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
{
int ret = WOLFSSL_SUCCESS;

if (ctx->gcmAuthIn) {
XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmAuthIn = NULL;
}
ctx->gcmAuthInSz = 0;

ctx->block_size = AES_BLOCK_SIZE;
ctx->authTagSz = AES_BLOCK_SIZE;
if (ctx->ivSz == 0) {
Expand Down Expand Up @@ -5766,6 +5772,15 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
}
#endif /* WOLFSSL_AESGCM_STREAM */

/*
* OpenSSL clears this flag, which permits subsequent use of
* EVP_CTRL_GCM_IV_GEN, when EVP_CipherInit is called with no key.
* If a key is provided, the flag retains its value.
*/
if (ret == WOLFSSL_SUCCESS && key == NULL) {
ctx->gcmIvGenEnable = 0;
}

return ret;
}

Expand Down Expand Up @@ -5912,15 +5927,6 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
iv = ctx->iv;
}
#endif
#ifdef HAVE_AESGCM
if (ctx->gcmAuthIn) {
XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmAuthIn = NULL;
}
ctx->gcmAuthInSz = 0;
ctx->gcmIvGenEnable = 0;
ctx->gcmIncIv = 0;
#endif

#ifndef NO_AES
#if defined(HAVE_AES_CBC) || defined(WOLFSSL_AES_DIRECT)
Expand Down

0 comments on commit fb3c611

Please sign in to comment.