Hi,
I searched around for similar posts and did find some helpful hints regarding how wolfSSL expects wc_AesGcmDecrypt to be used (per the test implementation).
However, in my case I'm porting a library from OpenSSL to WolfSSL, and I want to double check that I preserve the expected behavior being that I am quite new to cryptography.
OpenSSL Example:
// Initializes the EVP ctx
ret = EVP_DecryptInit_ex(ctx->evp_ctx, NULL, NULL, NULL, iv);
// Provides the AAD data
ret = EVP_DecryptUpdate(ctx->evp_ctx, NULL, &blocklen, aad, (int)aadlen);
// Provide the message to be decrypted and obtain plaintext
ret = EVP_DecryptUpdate(ctx->evp_ctx, output + off, &blocklen, input, (int)(inlen - tag_size));
// Set expected tag value. Works in OpenSSL 1.0.1d and later. In this case it looks as though the tag is appended to the input.
EVP_CIPHER_CTX_ctrl(ctx->evp_ctx, EVP_CTRL_GCM_SET_TAG, (int)tag_size, (void *)((uint8_t *)input + inlen - tag_size));
// Finalize the decryption
EVP_DecryptFinal_ex(ctx->evp_ctx, output + off, &blocklen);
Now, it does appear that WolfSSL has implemented some form of support for this usage in evpCipherBlock here:
if (out){
/* decrypt confidential data*/
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, out, in, inl,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
NULL, 0);
}
else {
/* authenticated, non-confidential data*/
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
in, inl);
/* Reset partial authTag error for AAD*/
if (ret == AES_GCM_AUTH_E)
ret = 0;
}
It would seem that the correct way to go about this is to call EVP_CIPHER_CTX_ctrl with EVP_CTRL_GCM_SET_TAG before the second call to DecryptUpdate, else ctx->authTag is not set and we continue to fail the ConstantCompare in AES_GCM_decrypt_C. Is this correct?