Improve EVP support for CHACHA20_POLY1305 (#5527)

* Add test case for OpenSSLs capability to init a evp context partially in several calls.
* EVP handling of CHACHA20_POLY1305 improvment
- save key at ctx for Init()s without IV
- reuse stored key for Init()s with new IV, reusing ctx
- free and zero key on ctx clenaup
* Adding type cast to XMALLOC to force compiler compatibility.
* EVP: using same DYNAMIC_TYPE in alloc and free of chacha20_poly1305 key.
Co-authored-by: Stefan Eissing <stefan.eissing@greenbytes.de>
This commit is contained in:
Stefan Eissing
2022-09-01 22:23:42 +02:00
committed by GitHub
parent ba8ffc765d
commit 65ca72c5a2
3 changed files with 45 additions and 2 deletions

View File

@ -52049,6 +52049,24 @@ static int test_wolfssl_EVP_chacha20_poly1305(void)
AssertIntEQ(outSz, 0);
EVP_CIPHER_CTX_free(ctx);
/* Test partial Inits. CipherInit() allow setting of key and iv
* in separate calls. */
AssertNotNull((ctx = EVP_CIPHER_CTX_new()));
AssertIntEQ(wolfSSL_EVP_CipherInit(ctx, EVP_chacha20_poly1305(),
key, NULL, 1), WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_EVP_CipherInit(ctx, NULL, NULL, iv, 1),
WOLFSSL_SUCCESS);
AssertIntEQ(wolfSSL_EVP_CipherUpdate(ctx, NULL, &outSz,
aad, sizeof(aad)), WOLFSSL_SUCCESS);
AssertIntEQ(outSz, sizeof(aad));
AssertIntEQ(EVP_DecryptUpdate(ctx, decryptedText, &outSz, cipherText,
sizeof(cipherText)), WOLFSSL_SUCCESS);
AssertIntEQ(outSz, sizeof(cipherText));
AssertIntEQ(EVP_DecryptFinal_ex(ctx, decryptedText, &outSz),
WOLFSSL_SUCCESS);
AssertIntEQ(outSz, 0);
EVP_CIPHER_CTX_free(ctx);
printf(resultFmt, passed);
#endif

View File

@ -5625,6 +5625,13 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
#endif /* HAVE_AESGCM && WOLFSSL_AESGCM_STREAM */
#endif /* not FIPS or FIPS v2+ */
ctx->cipherType = WOLFSSL_EVP_CIPH_TYPE_INIT; /* not yet initialized */
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
if (ctx->key) {
ForceZero(ctx->key, ctx->keyLen);
XFREE(ctx->key, NULL, DYNAMIC_TYPE_OPENSSL);
ctx->key = NULL;
}
#endif
ctx->keyLen = 0;
#ifdef HAVE_AESGCM
if (ctx->gcmBuffer) {
@ -6619,8 +6626,23 @@ int wolfSSL_EVP_MD_type(const WOLFSSL_EVP_MD* type)
ctx->enc = (byte) enc;
}
if (key != NULL && iv != NULL && wc_ChaCha20Poly1305_Init(
&ctx->cipher.chachaPoly, key, iv, enc) != 0) {
/* wolfSSL_EVP_CipherInit() may be called multiple times to
* set key or iv alone. A common use case is to set key
* and then init with another iv again and again after
* update/finals. We need to preserve the key for those calls
* since wc_ChaCha20Poly1305_Init() does not. */
if (key != NULL) {
if (!ctx->key) {
ctx->key = (byte*)XMALLOC(ctx->keyLen, NULL,
DYNAMIC_TYPE_OPENSSL);
if (!ctx->key) {
return MEMORY_E;
}
}
XMEMCPY(ctx->key, key, ctx->keyLen);
}
if ((ctx->key != NULL && iv != NULL) && wc_ChaCha20Poly1305_Init(
&ctx->cipher.chachaPoly, ctx->key, iv, ctx->enc) != 0) {
WOLFSSL_MSG("wc_ChaCha20Poly1305_Init() failed");
return WOLFSSL_FAILURE;
}

View File

@ -431,6 +431,9 @@ struct WOLFSSL_EVP_CIPHER_CTX {
byte* gcmAuthIn;
int gcmAuthInSz;
#endif
#if defined(HAVE_CHACHA) && defined(HAVE_POLY1305)
byte* key; /* used in partial Init()s */
#endif
#if defined(HAVE_AESGCM) || (defined(HAVE_CHACHA) && defined(HAVE_POLY1305))
#ifdef HAVE_AESGCM
ALIGN16 unsigned char authTag[AES_BLOCK_SIZE];