Buffer AAD in wolfSSL_EVP_CipherUpdate_GCM so that whole value is hashed

This commit is contained in:
Juliusz Sosinowicz
2020-09-22 21:58:57 +02:00
parent deaf3b4b40
commit 77969ae042
3 changed files with 122 additions and 29 deletions

View File

@@ -35343,6 +35343,53 @@ static void test_wolfSSL_PEM_read(void)
#endif #endif
} }
static void test_wolfssl_EVP_aes_gcm_AAD_2_parts(void)
{
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \
!defined(HAVE_SELFTEST) && !defined(HAVE_FIPS)
const byte iv[12] = { 0 };
const byte key[16] = { 0 };
const byte cleartext[16] = { 0 };
const byte aad[] = {0x01, 0x10, 0x00, 0x2a, 0x08, 0x00, 0x04, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0xdc, 0x4d,
0xad, 0x6b, 0x06, 0x93, 0x4f};
byte out1Part[16];
byte outTag1Part[16];
byte out2Part[16];
byte outTag2Part[16];
int len;
EVP_CIPHER_CTX* ctx = NULL;
printf(testingFmt, "wolfssl_EVP_aes_gcm_AAD_2_parts");
/* Send AAD in 1 part */
AssertNotNull(ctx = EVP_CIPHER_CTX_new());
AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), 1);
AssertIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, sizeof(aad)), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, out1Part, &len, cleartext, sizeof(cleartext)), 1);
AssertIntEQ(EVP_EncryptFinal_ex(ctx, out1Part, &len), 1);
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outTag1Part), 1);
EVP_CIPHER_CTX_free(ctx);
/* Send AAD in 2 parts */
AssertNotNull(ctx = EVP_CIPHER_CTX_new());
AssertIntEQ(EVP_EncryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL), 1);
AssertIntEQ(EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad, 1), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, NULL, &len, aad + 1, sizeof(aad) - 1), 1);
AssertIntEQ(EVP_EncryptUpdate(ctx, out2Part, &len, cleartext, sizeof(cleartext)), 1);
AssertIntEQ(EVP_EncryptFinal_ex(ctx, out2Part, &len), 1);
AssertIntEQ(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, 16, outTag2Part), 1);
EVP_CIPHER_CTX_free(ctx);
AssertIntEQ(XMEMCMP(out1Part, out2Part, sizeof(out1Part)), 0);
AssertIntEQ(XMEMCMP(outTag1Part, outTag2Part, sizeof(outTag1Part)), 0);
printf(resultFmt, passed);
#endif
}
static void test_wolfssl_EVP_aes_gcm(void) static void test_wolfssl_EVP_aes_gcm(void)
{ {
#if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \ #if defined(OPENSSL_EXTRA) && !defined(NO_AES) && defined(HAVE_AESGCM) && \
@@ -36738,6 +36785,7 @@ void ApiTest(void)
test_wolfSSL_DC_cert(); test_wolfSSL_DC_cert();
test_wolfSSL_DES_ncbc(); test_wolfSSL_DES_ncbc();
test_wolfSSL_AES_cbc_encrypt(); test_wolfSSL_AES_cbc_encrypt();
test_wolfssl_EVP_aes_gcm_AAD_2_parts();
test_wolfssl_EVP_aes_gcm(); test_wolfssl_EVP_aes_gcm();
test_wolfSSL_PKEY_up_ref(); test_wolfSSL_PKEY_up_ref();
test_wolfSSL_i2d_PrivateKey(); test_wolfSSL_i2d_PrivateKey();

View File

@@ -549,6 +549,22 @@ static int evpCipherBlock(WOLFSSL_EVP_CIPHER_CTX *ctx,
} }
#if defined(HAVE_AESGCM) #if defined(HAVE_AESGCM)
static int wolfSSL_EVP_CipherUpdate_GCM_AAD(WOLFSSL_EVP_CIPHER_CTX *ctx,
const unsigned char *in, int inl) {
byte* tmp = (byte*)XREALLOC(ctx->gcmAuthIn,
ctx->gcmAuthInSz + inl, NULL, DYNAMIC_TYPE_OPENSSL);
if (tmp) {
ctx->gcmAuthIn = tmp;
XMEMCPY(ctx->gcmAuthIn + ctx->gcmAuthInSz, in, inl);
ctx->gcmAuthInSz += inl;
}
else {
WOLFSSL_MSG("realloc error");
return MEMORY_E;
}
return 0;
}
static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx, static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
unsigned char *out, int *outl, unsigned char *out, int *outl,
const unsigned char *in, int inl) const unsigned char *in, int inl)
@@ -558,25 +574,53 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
*outl = inl; *outl = inl;
if (ctx->enc) { if (ctx->enc) {
if (out) { if (out) {
if (ctx->gcmAuthIn) {
/* authenticated, non-confidential data */
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, NULL, NULL, 0,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
ctx->gcmAuthIn, ctx->gcmAuthInSz);
/* Reset partial authTag error for AAD*/
if (ret == AES_GCM_AUTH_E)
ret = 0;
if (ret == 0) {
XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmAuthIn = NULL;
ctx->gcmAuthInSz = 0;
}
}
/* encrypt confidential data*/ /* encrypt confidential data*/
if (ret == 0)
ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, in, inl, ret = wc_AesGcmEncrypt(&ctx->cipher.aes, out, in, inl,
ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz, ctx->iv, ctx->ivSz, ctx->authTag, ctx->authTagSz,
NULL, 0); NULL, 0);
} }
else { else {
/* authenticated, non-confidential data */ ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, in, inl);
XMEMSET(ctx->authTag, 0, ctx->authTagSz);
ret = wc_AesGcmEncrypt(&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;
} }
} }
else { else {
if (out) { if (out) {
byte* tmp; byte* tmp;
if (ctx->gcmAuthIn) {
/* authenticated, non-confidential data*/
ret = wc_AesGcmDecrypt(&ctx->cipher.aes, NULL, NULL, 0,
ctx->iv, ctx->ivSz,
ctx->authTag, ctx->authTagSz,
ctx->gcmAuthIn, ctx->gcmAuthInSz);
/* Reset partial authTag error for AAD*/
if (ret == AES_GCM_AUTH_E)
ret = 0;
if (ret == 0) {
XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmAuthIn = NULL;
ctx->gcmAuthInSz = 0;
}
}
if (ret == 0) {
tmp = (byte*)XREALLOC(ctx->gcmDecryptBuffer, tmp = (byte*)XREALLOC(ctx->gcmDecryptBuffer,
ctx->gcmDecryptBufferLen + inl, NULL, ctx->gcmDecryptBufferLen + inl, NULL,
DYNAMIC_TYPE_OPENSSL); DYNAMIC_TYPE_OPENSSL);
@@ -587,18 +631,12 @@ static int wolfSSL_EVP_CipherUpdate_GCM(WOLFSSL_EVP_CIPHER_CTX *ctx,
*outl = 0; *outl = 0;
} }
else { else {
ret = WOLFSSL_FAILURE; ret = MEMORY_E;
}
} }
} }
else { else {
/* authenticated, non-confidential data*/ ret = wolfSSL_EVP_CipherUpdate_GCM_AAD(ctx, in, inl);
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;
} }
} }
@@ -4123,6 +4161,11 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD *md)
ctx->gcmDecryptBuffer = NULL; ctx->gcmDecryptBuffer = NULL;
} }
ctx->gcmDecryptBufferLen = 0; ctx->gcmDecryptBufferLen = 0;
if (ctx->gcmAuthIn) {
XFREE(ctx->gcmAuthIn, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->gcmAuthIn = NULL;
}
ctx->gcmAuthInSz = 0;
#endif #endif
} }

View File

@@ -358,6 +358,8 @@ struct WOLFSSL_EVP_CIPHER_CTX {
int gcmDecryptBufferLen; int gcmDecryptBufferLen;
ALIGN16 unsigned char authTag[AES_BLOCK_SIZE]; ALIGN16 unsigned char authTag[AES_BLOCK_SIZE];
int authTagSz; int authTagSz;
byte* gcmAuthIn;
int gcmAuthInSz;
#endif #endif
#endif #endif
}; };