mirror of
https://github.com/wolfSSL/wolfssl.git
synced 2025-07-29 18:27:29 +02:00
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:
18
tests/api.c
18
tests/api.c
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
|
Reference in New Issue
Block a user