diff options
-rw-r--r-- | doc/man3/EVP_EncryptInit.pod | 9 | ||||
-rw-r--r-- | doc/man7/migration_guide.pod | 8 | ||||
-rw-r--r-- | providers/implementations/ciphers/cipher_chacha20_poly1305.c | 7 | ||||
-rw-r--r-- | providers/implementations/ciphers/cipher_chacha20_poly1305.h | 2 | ||||
-rw-r--r-- | providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c | 32 | ||||
-rw-r--r-- | test/recipes/30-test_evp_data/evpciph_chacha.txt | 10 |
6 files changed, 40 insertions, 28 deletions
diff --git a/doc/man3/EVP_EncryptInit.pod b/doc/man3/EVP_EncryptInit.pod index 63b42ddc51..8e5c0b50fc 100644 --- a/doc/man3/EVP_EncryptInit.pod +++ b/doc/man3/EVP_EncryptInit.pod @@ -1433,11 +1433,10 @@ The following I<ctrl>s are supported for the ChaCha20-Poly1305 AEAD algorithm. =item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, ivlen, NULL) -Sets the nonce length. This call can only be made before specifying the nonce. -If not called a default nonce length of 12 (i.e. 96 bits) is used. The maximum -nonce length is 12 bytes (i.e. 96-bits). If a nonce of less than 12 bytes is set -then the nonce is automatically padded with leading 0 bytes to make it 12 bytes -in length. +Sets the nonce length. This call is now redundant since the only valid value +is the default length of 12 (i.e. 96 bits). +Prior to OpenSSL 3.0 a nonce of less than 12 bytes could be used to automatically +pad the iv with leading 0 bytes to make it 12 bytes in length. =item EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, taglen, tag) diff --git a/doc/man7/migration_guide.pod b/doc/man7/migration_guide.pod index e82471370f..ddfa81e13e 100644 --- a/doc/man7/migration_guide.pod +++ b/doc/man7/migration_guide.pod @@ -490,6 +490,14 @@ The function code part of the error code is now always set to 0. For that reason the ERR_GET_FUNC() macro was removed. Applications must resolve the error codes only using the library number and the reason code. +=head4 ChaCha20-Poly1305 cipher does not allow a truncated IV length to be used + +In OpenSSL 3.0 setting the IV length to any value other than 12 will result in an +error. +Prior to OpenSSL 3.0 the ivlen could be smaller that the required 12 byte length, +using EVP_CIPHER_CTX_ctrl(ctx, EVP_CRTL_AEAD_SET_IVLEN, ivlen, NULL). This resulted +in an IV that had leading zero padding. + =head2 Installation and Compilation Please refer to the INSTALL.md file in the top of the distribution for diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.c b/providers/implementations/ciphers/cipher_chacha20_poly1305.c index 0ba7483780..8cbaa50d95 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.c @@ -14,7 +14,6 @@ #include "prov/implementations.h" #include "prov/providercommon.h" - #define CHACHA20_POLY1305_KEYLEN CHACHA_KEY_SIZE #define CHACHA20_POLY1305_BLKLEN 1 #define CHACHA20_POLY1305_MAX_IVLEN 12 @@ -53,7 +52,6 @@ static void *chacha20_poly1305_newctx(void *provctx) ossl_prov_cipher_hw_chacha20_poly1305( CHACHA20_POLY1305_KEYLEN * 8), NULL); - ctx->nonce_len = CHACHA20_POLY1305_IVLEN; ctx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; ossl_chacha20_initctx(&ctx->chacha); } @@ -85,7 +83,7 @@ static int chacha20_poly1305_get_ctx_params(void *vctx, OSSL_PARAM params[]) p = OSSL_PARAM_locate(params, OSSL_CIPHER_PARAM_IVLEN); if (p != NULL) { - if (!OSSL_PARAM_set_size_t(p, ctx->nonce_len)) { + if (!OSSL_PARAM_set_size_t(p, CHACHA20_POLY1305_IVLEN)) { ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SET_PARAMETER); return 0; } @@ -169,11 +167,10 @@ static int chacha20_poly1305_set_ctx_params(void *vctx, ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_GET_PARAMETER); return 0; } - if (len == 0 || len > CHACHA20_POLY1305_MAX_IVLEN) { + if (len != CHACHA20_POLY1305_MAX_IVLEN) { ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_IV_LENGTH); return 0; } - ctx->nonce_len = len; } p = OSSL_PARAM_locate_const(params, OSSL_CIPHER_PARAM_AEAD_TAG); diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305.h b/providers/implementations/ciphers/cipher_chacha20_poly1305.h index 1f6f0066dc..9a5ce34e7b 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305.h +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305.h @@ -25,7 +25,7 @@ typedef struct { struct { uint64_t aad, text; } len; unsigned int aad : 1; unsigned int mac_inited : 1; - size_t tag_len, nonce_len; + size_t tag_len; size_t tls_payload_length; size_t tls_aad_pad_sz; } PROV_CHACHA20_POLY1305_CTX; diff --git a/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c b/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c index 1533a3869b..421380e86e 100644 --- a/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c +++ b/providers/implementations/ciphers/cipher_chacha20_poly1305_hw.c @@ -55,7 +55,6 @@ static int chacha_poly1305_tls_iv_set_fixed(PROV_CIPHER_CTX *bctx, return 1; } - static int chacha20_poly1305_initkey(PROV_CIPHER_CTX *bctx, const unsigned char *key, size_t keylen) { @@ -78,6 +77,7 @@ static int chacha20_poly1305_initiv(PROV_CIPHER_CTX *bctx) PROV_CHACHA20_POLY1305_CTX *ctx = (PROV_CHACHA20_POLY1305_CTX *)bctx; unsigned char tempiv[CHACHA_CTR_SIZE] = { 0 }; int ret = 1; + size_t noncelen = CHACHA20_POLY1305_IVLEN; ctx->len.aad = 0; ctx->len.text = 0; @@ -85,22 +85,20 @@ static int chacha20_poly1305_initiv(PROV_CIPHER_CTX *bctx) ctx->mac_inited = 0; ctx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; - /* pad on the left */ - if (ctx->nonce_len <= CHACHA_CTR_SIZE) { - memcpy(tempiv + CHACHA_CTR_SIZE - ctx->nonce_len, bctx->oiv, - ctx->nonce_len); - - if (bctx->enc) - ret = ossl_chacha20_einit(&ctx->chacha, NULL, 0, - tempiv, sizeof(tempiv), NULL); - else - ret = ossl_chacha20_dinit(&ctx->chacha, NULL, 0, - tempiv, sizeof(tempiv), NULL); - ctx->nonce[0] = ctx->chacha.counter[1]; - ctx->nonce[1] = ctx->chacha.counter[2]; - ctx->nonce[2] = ctx->chacha.counter[3]; - bctx->iv_set = 1; - } + /* pad on the left */ + memcpy(tempiv + CHACHA_CTR_SIZE - noncelen, bctx->oiv, + noncelen); + + if (bctx->enc) + ret = ossl_chacha20_einit(&ctx->chacha, NULL, 0, + tempiv, sizeof(tempiv), NULL); + else + ret = ossl_chacha20_dinit(&ctx->chacha, NULL, 0, + tempiv, sizeof(tempiv), NULL); + ctx->nonce[0] = ctx->chacha.counter[1]; + ctx->nonce[1] = ctx->chacha.counter[2]; + ctx->nonce[2] = ctx->chacha.counter[3]; + bctx->iv_set = 1; return ret; } diff --git a/test/recipes/30-test_evp_data/evpciph_chacha.txt b/test/recipes/30-test_evp_data/evpciph_chacha.txt index 3315a66f33..f283b240f3 100644 --- a/test/recipes/30-test_evp_data/evpciph_chacha.txt +++ b/test/recipes/30-test_evp_data/evpciph_chacha.txt @@ -153,6 +153,16 @@ Tag = eead9d67890cbb22392336fea1851f38 Plaintext = 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d Ciphertext = 64a0861575861af460f062c79be643bd5e805cfd345cf389f108670ac76c8cb24c6cfc18755d43eea09ee94e382d26b0bdb7b73c321b0100d4f03b7f355894cf332f830e710b97ce98c8a84abd0b948114ad176e008d33bd60f982b1ff37c8559797a06ef4f0ef61c186324e2b3506383606907b6a7c02b0f9f6157b53c867e4b9166c767b804d46a59b5216cde7a4e99040c5a40433225ee282a1b0a06c523eaf4534d7f83fa1155b0047718cbc546a0d072b04b3564eea1b422273f548271a0bb2316053fa76991955ebd63159434ecebb4e466dae5a1073a6727627097a1049e617d91d361094fa68f0ff77987130305beaba2eda04df997b714d6c6f2c29a6ad5cb4022b02709b +# Test that a truncated IV is no longer allowed (since 3.0) +# This is the same test as above with the leading zeros stripped from the IV +Cipher = chacha20-poly1305 +Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0 +IV = 0102030405060708 +AAD = f33388860000000000004e91 +Tag = eead9d67890cbb22392336fea1851f38 +Plaintext = 496e7465726e65742d4472616674732061726520647261667420646f63756d656e74732076616c696420666f722061206d6178696d756d206f6620736978206d6f6e74687320616e64206d617920626520757064617465642c207265706c616365642c206f72206f62736f6c65746564206279206f7468657220646f63756d656e747320617420616e792074696d652e20497420697320696e617070726f70726961746520746f2075736520496e7465726e65742d447261667473206173207265666572656e6365206d6174657269616c206f7220746f2063697465207468656d206f74686572207468616e206173202fe2809c776f726b20696e2070726f67726573732e2fe2809d +Result = INVALID_IV_LENGTH + Cipher = chacha20-poly1305 Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0 IV = 000000000102030405060708 |