diff options
author | slontis <shane.lontis@oracle.com> | 2023-01-27 13:18:17 +1000 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2023-01-30 09:48:50 +0100 |
commit | a01152370676e7e11fb461cff8628eb50fa41b81 (patch) | |
tree | d455f9b1995ccc694a6d771701bd674dd7447bd7 /providers/implementations | |
parent | 2477e99f1055194902dc4864124316ea57ac3efa (diff) |
ChaCha20-Poly1305 no longer supports truncated IV's.
Fixes #20084
In the 3.0 provider implementation the generic code that handles IV's
only allows a 12 byte IV. Older code intentionally added the ability for
the IV to be truncated.
As this truncation is unsafe, the documentation has been updated to
state that this in no longer allowed. The code has been updated to
produce an error when the iv length is set to any value other than 12.
NOTE: It appears that this additional padding may have originated from the code
which uses a 12 byte IV, that is then passed to CHACHA which zero pads it to 16 bytes.
Note that legacy behaviour in e_chacha20_poly1305.c has not been
updated.
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20151)
Diffstat (limited to 'providers/implementations')
3 files changed, 18 insertions, 23 deletions
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; } |