From: Matt Caswell Date: Thu, 18 Dec 2025 15:40:35 +0000 (+0000) Subject: Remove dead EVP_chacha20_*() code X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=42371665308585be56281dc399d7f23c69162cff;p=thirdparty%2Fopenssl.git Remove dead EVP_chacha20_*() code Reviewed-by: Tomas Mraz Reviewed-by: Neil Horman (Merged from https://github.com/openssl/openssl/pull/29446) --- diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c index 4db2fd12f90..c8ba2c1175c 100644 --- a/crypto/evp/e_chacha20_poly1305.c +++ b/crypto/evp/e_chacha20_poly1305.c @@ -19,113 +19,6 @@ #include "evp_local.h" #include "crypto/chacha.h" -typedef struct { - union { - OSSL_UNION_ALIGN; /* this ensures even sizeof(EVP_CHACHA_KEY)%8==0 */ - unsigned int d[CHACHA_KEY_SIZE / 4]; - } key; - unsigned int counter[CHACHA_CTR_SIZE / 4]; - unsigned char buf[CHACHA_BLK_SIZE]; - unsigned int partial_len; -} EVP_CHACHA_KEY; - -#define data(ctx) ((EVP_CHACHA_KEY *)(ctx)->cipher_data) - -#define CHACHA20_POLY1305_MAX_IVLEN 12 - -static int chacha_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char user_key[CHACHA_KEY_SIZE], - const unsigned char iv[CHACHA_CTR_SIZE], int enc) -{ - EVP_CHACHA_KEY *key = data(ctx); - unsigned int i; - - if (user_key) - for (i = 0; i < CHACHA_KEY_SIZE; i += 4) { - key->key.d[i / 4] = CHACHA_U8TOU32(user_key + i); - } - - if (iv) - for (i = 0; i < CHACHA_CTR_SIZE; i += 4) { - key->counter[i / 4] = CHACHA_U8TOU32(iv + i); - } - - key->partial_len = 0; - - return 1; -} - -static int chacha_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *inp, size_t len) -{ - EVP_CHACHA_KEY *key = data(ctx); - unsigned int n, rem, ctr32; - - if ((n = key->partial_len)) { - while (len && n < CHACHA_BLK_SIZE) { - *out++ = *inp++ ^ key->buf[n++]; - len--; - } - key->partial_len = n; - - if (len == 0) - return 1; - - if (n == CHACHA_BLK_SIZE) { - key->partial_len = 0; - key->counter[0]++; - if (key->counter[0] == 0) - key->counter[1]++; - } - } - - rem = (unsigned int)(len % CHACHA_BLK_SIZE); - len -= rem; - ctr32 = key->counter[0]; - while (len >= CHACHA_BLK_SIZE) { - size_t blocks = len / CHACHA_BLK_SIZE; - /* - * 1<<28 is just a not-so-small yet not-so-large number... - * Below condition is practically never met, but it has to - * be checked for code correctness. - */ - if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28)) - blocks = (1U << 28); - - /* - * As ChaCha20_ctr32 operates on 32-bit counter, caller - * has to handle overflow. 'if' below detects the - * overflow, which is then handled by limiting the - * amount of blocks to the exact overflow point... - */ - ctr32 += (unsigned int)blocks; - if (ctr32 < blocks) { - blocks -= ctr32; - ctr32 = 0; - } - blocks *= CHACHA_BLK_SIZE; - ChaCha20_ctr32(out, inp, blocks, key->key.d, key->counter); - len -= blocks; - inp += blocks; - out += blocks; - - key->counter[0] = ctr32; - if (ctr32 == 0) - key->counter[1]++; - } - - if (rem) { - memset(key->buf, 0, sizeof(key->buf)); - ChaCha20_ctr32(key->buf, key->buf, CHACHA_BLK_SIZE, - key->key.d, key->counter); - for (n = 0; n < rem; n++) - out[n] = inp[n] ^ key->buf[n]; - key->partial_len = rem; - } - - return 1; -} - static const EVP_CIPHER chacha20 = { NID_chacha20, 1, /* block_size */ @@ -133,10 +26,10 @@ static const EVP_CIPHER chacha20 = { CHACHA_CTR_SIZE, /* iv_len, 128-bit counter in the context */ EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT, EVP_ORIG_GLOBAL, - chacha_init_key, - chacha_cipher, NULL, - sizeof(EVP_CHACHA_KEY), + NULL, + NULL, + 0, NULL, NULL, NULL, @@ -149,461 +42,6 @@ const EVP_CIPHER *EVP_chacha20(void) } #ifndef OPENSSL_NO_POLY1305 -#include "crypto/poly1305.h" - -typedef struct { - EVP_CHACHA_KEY key; - unsigned int nonce[12 / 4]; - unsigned char tag[POLY1305_BLOCK_SIZE]; - unsigned char tls_aad[POLY1305_BLOCK_SIZE]; - struct { - uint64_t aad, text; - } len; - int aad, mac_inited, tag_len, nonce_len; - size_t tls_payload_length; -} EVP_CHACHA_AEAD_CTX; - -#define NO_TLS_PAYLOAD_LENGTH ((size_t)-1) -#define aead_data(ctx) ((EVP_CHACHA_AEAD_CTX *)(ctx)->cipher_data) -#define POLY1305_ctx(actx) ((POLY1305 *)(actx + 1)) - -static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx, - const unsigned char *inkey, - const unsigned char *iv, int enc) -{ - EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); - - if (!inkey && !iv) - return 1; - - actx->len.aad = 0; - actx->len.text = 0; - actx->aad = 0; - actx->mac_inited = 0; - actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; - - if (iv != NULL) { - unsigned char temp[CHACHA_CTR_SIZE] = { 0 }; - - /* pad on the left */ - if (actx->nonce_len <= CHACHA_CTR_SIZE) - memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, - actx->nonce_len); - - chacha_init_key(ctx, inkey, temp, enc); - - actx->nonce[0] = actx->key.counter[1]; - actx->nonce[1] = actx->key.counter[2]; - actx->nonce[2] = actx->key.counter[3]; - } else { - chacha_init_key(ctx, inkey, NULL, enc); - } - - return 1; -} - -#if !defined(OPENSSL_SMALL_FOOTPRINT) - -#if defined(POLY1305_ASM) && (defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64)) -#define XOR128_HELPERS -void *xor128_encrypt_n_pad(void *out, const void *inp, void *otp, size_t len); -void *xor128_decrypt_n_pad(void *out, const void *inp, void *otp, size_t len); -static const unsigned char zero[4 * CHACHA_BLK_SIZE] = { 0 }; -#else -static const unsigned char zero[2 * CHACHA_BLK_SIZE] = { 0 }; -#endif - -static int chacha20_poly1305_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); - size_t tail, tohash_len, buf_len, plen = actx->tls_payload_length; - unsigned char *buf, *tohash, *ctr, storage[sizeof(zero) + 32]; - - if (len != plen + POLY1305_BLOCK_SIZE) - return -1; - - buf = storage + ((0 - (size_t)storage) & 15); /* align */ - ctr = buf + CHACHA_BLK_SIZE; - tohash = buf + CHACHA_BLK_SIZE - POLY1305_BLOCK_SIZE; - -#ifdef XOR128_HELPERS - if (plen <= 3 * CHACHA_BLK_SIZE) { - actx->key.counter[0] = 0; - buf_len = (plen + 2 * CHACHA_BLK_SIZE - 1) & (0 - CHACHA_BLK_SIZE); - ChaCha20_ctr32(buf, zero, buf_len, actx->key.key.d, - actx->key.counter); - Poly1305_Init(POLY1305_ctx(actx), buf); - actx->key.partial_len = 0; - memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE); - tohash_len = POLY1305_BLOCK_SIZE; - actx->len.aad = EVP_AEAD_TLS1_AAD_LEN; - actx->len.text = plen; - - if (plen) { - if (EVP_CIPHER_CTX_is_encrypting(ctx)) - ctr = xor128_encrypt_n_pad(out, in, ctr, plen); - else - ctr = xor128_decrypt_n_pad(out, in, ctr, plen); - - in += plen; - out += plen; - tohash_len = (size_t)(ctr - tohash); - } - } -#else - if (plen <= CHACHA_BLK_SIZE) { - size_t i; - - actx->key.counter[0] = 0; - ChaCha20_ctr32(buf, zero, (buf_len = 2 * CHACHA_BLK_SIZE), - actx->key.key.d, actx->key.counter); - Poly1305_Init(POLY1305_ctx(actx), buf); - actx->key.partial_len = 0; - memcpy(tohash, actx->tls_aad, POLY1305_BLOCK_SIZE); - tohash_len = POLY1305_BLOCK_SIZE; - actx->len.aad = EVP_AEAD_TLS1_AAD_LEN; - actx->len.text = plen; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - for (i = 0; i < plen; i++) { - out[i] = ctr[i] ^= in[i]; - } - } else { - for (i = 0; i < plen; i++) { - unsigned char c = in[i]; - out[i] = ctr[i] ^ c; - ctr[i] = c; - } - } - - in += i; - out += i; - - tail = (0 - i) & (POLY1305_BLOCK_SIZE - 1); - memset(ctr + i, 0, tail); - ctr += i + tail; - tohash_len += i + tail; - } -#endif - else { - actx->key.counter[0] = 0; - ChaCha20_ctr32(buf, zero, (buf_len = CHACHA_BLK_SIZE), - actx->key.key.d, actx->key.counter); - Poly1305_Init(POLY1305_ctx(actx), buf); - actx->key.counter[0] = 1; - actx->key.partial_len = 0; - Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad, POLY1305_BLOCK_SIZE); - tohash = ctr; - tohash_len = 0; - actx->len.aad = EVP_AEAD_TLS1_AAD_LEN; - actx->len.text = plen; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter); - Poly1305_Update(POLY1305_ctx(actx), out, plen); - } else { - Poly1305_Update(POLY1305_ctx(actx), in, plen); - ChaCha20_ctr32(out, in, plen, actx->key.key.d, actx->key.counter); - } - - in += plen; - out += plen; - tail = (0 - plen) & (POLY1305_BLOCK_SIZE - 1); - Poly1305_Update(POLY1305_ctx(actx), zero, tail); - } - - { - DECLARE_IS_ENDIAN; - - if (IS_LITTLE_ENDIAN) { - memcpy(ctr, (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE); - } else { - ctr[0] = (unsigned char)(actx->len.aad); - ctr[1] = (unsigned char)(actx->len.aad >> 8); - ctr[2] = (unsigned char)(actx->len.aad >> 16); - ctr[3] = (unsigned char)(actx->len.aad >> 24); - ctr[4] = (unsigned char)(actx->len.aad >> 32); - ctr[5] = (unsigned char)(actx->len.aad >> 40); - ctr[6] = (unsigned char)(actx->len.aad >> 48); - ctr[7] = (unsigned char)(actx->len.aad >> 56); - - ctr[8] = (unsigned char)(actx->len.text); - ctr[9] = (unsigned char)(actx->len.text >> 8); - ctr[10] = (unsigned char)(actx->len.text >> 16); - ctr[11] = (unsigned char)(actx->len.text >> 24); - ctr[12] = (unsigned char)(actx->len.text >> 32); - ctr[13] = (unsigned char)(actx->len.text >> 40); - ctr[14] = (unsigned char)(actx->len.text >> 48); - ctr[15] = (unsigned char)(actx->len.text >> 56); - } - tohash_len += POLY1305_BLOCK_SIZE; - } - - Poly1305_Update(POLY1305_ctx(actx), tohash, tohash_len); - OPENSSL_cleanse(buf, buf_len); - Poly1305_Final(POLY1305_ctx(actx), - EVP_CIPHER_CTX_is_encrypting(ctx) ? actx->tag : tohash); - - actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - memcpy(out, actx->tag, POLY1305_BLOCK_SIZE); - } else { - if (CRYPTO_memcmp(tohash, in, POLY1305_BLOCK_SIZE)) { - memset(out - (len - POLY1305_BLOCK_SIZE), 0, - len - POLY1305_BLOCK_SIZE); - return -1; - } - } - - return (int)len; -} -#else -static const unsigned char zero[CHACHA_BLK_SIZE] = { 0 }; -#endif - -static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, - const unsigned char *in, size_t len) -{ - EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); - size_t rem, plen = actx->tls_payload_length; - - if (!actx->mac_inited) { -#if !defined(OPENSSL_SMALL_FOOTPRINT) - if (plen != NO_TLS_PAYLOAD_LENGTH && out != NULL) - return chacha20_poly1305_tls_cipher(ctx, out, in, len); -#endif - actx->key.counter[0] = 0; - ChaCha20_ctr32(actx->key.buf, zero, CHACHA_BLK_SIZE, - actx->key.key.d, actx->key.counter); - Poly1305_Init(POLY1305_ctx(actx), actx->key.buf); - actx->key.counter[0] = 1; - actx->key.partial_len = 0; - actx->len.aad = actx->len.text = 0; - actx->mac_inited = 1; - if (plen != NO_TLS_PAYLOAD_LENGTH) { - Poly1305_Update(POLY1305_ctx(actx), actx->tls_aad, - EVP_AEAD_TLS1_AAD_LEN); - actx->len.aad = EVP_AEAD_TLS1_AAD_LEN; - actx->aad = 1; - } - } - - if (in) { /* aad or text */ - if (out == NULL) { /* aad */ - Poly1305_Update(POLY1305_ctx(actx), in, len); - actx->len.aad += len; - actx->aad = 1; - return (int)len; - } else { /* plain- or ciphertext */ - if (actx->aad) { /* wrap up aad */ - if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE)) - Poly1305_Update(POLY1305_ctx(actx), zero, - POLY1305_BLOCK_SIZE - rem); - actx->aad = 0; - } - - actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; - if (plen == NO_TLS_PAYLOAD_LENGTH) - plen = len; - else if (len != plen + POLY1305_BLOCK_SIZE) - return -1; - - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { /* plaintext */ - chacha_cipher(ctx, out, in, plen); - Poly1305_Update(POLY1305_ctx(actx), out, plen); - in += plen; - out += plen; - actx->len.text += plen; - } else { /* ciphertext */ - Poly1305_Update(POLY1305_ctx(actx), in, plen); - chacha_cipher(ctx, out, in, plen); - in += plen; - out += plen; - actx->len.text += plen; - } - } - } - if (in == NULL /* explicit final */ - || plen != len) { /* or tls mode */ - DECLARE_IS_ENDIAN; - unsigned char temp[POLY1305_BLOCK_SIZE]; - - if (actx->aad) { /* wrap up aad */ - if ((rem = (size_t)actx->len.aad % POLY1305_BLOCK_SIZE)) - Poly1305_Update(POLY1305_ctx(actx), zero, - POLY1305_BLOCK_SIZE - rem); - actx->aad = 0; - } - - if ((rem = (size_t)actx->len.text % POLY1305_BLOCK_SIZE)) - Poly1305_Update(POLY1305_ctx(actx), zero, - POLY1305_BLOCK_SIZE - rem); - - if (IS_LITTLE_ENDIAN) { - Poly1305_Update(POLY1305_ctx(actx), - (unsigned char *)&actx->len, POLY1305_BLOCK_SIZE); - } else { - temp[0] = (unsigned char)(actx->len.aad); - temp[1] = (unsigned char)(actx->len.aad >> 8); - temp[2] = (unsigned char)(actx->len.aad >> 16); - temp[3] = (unsigned char)(actx->len.aad >> 24); - temp[4] = (unsigned char)(actx->len.aad >> 32); - temp[5] = (unsigned char)(actx->len.aad >> 40); - temp[6] = (unsigned char)(actx->len.aad >> 48); - temp[7] = (unsigned char)(actx->len.aad >> 56); - - temp[8] = (unsigned char)(actx->len.text); - temp[9] = (unsigned char)(actx->len.text >> 8); - temp[10] = (unsigned char)(actx->len.text >> 16); - temp[11] = (unsigned char)(actx->len.text >> 24); - temp[12] = (unsigned char)(actx->len.text >> 32); - temp[13] = (unsigned char)(actx->len.text >> 40); - temp[14] = (unsigned char)(actx->len.text >> 48); - temp[15] = (unsigned char)(actx->len.text >> 56); - - Poly1305_Update(POLY1305_ctx(actx), temp, POLY1305_BLOCK_SIZE); - } - Poly1305_Final(POLY1305_ctx(actx), - EVP_CIPHER_CTX_is_encrypting(ctx) ? actx->tag : temp); - actx->mac_inited = 0; - - if (in != NULL && len != plen) { /* tls mode */ - if (EVP_CIPHER_CTX_is_encrypting(ctx)) { - memcpy(out, actx->tag, POLY1305_BLOCK_SIZE); - } else { - if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) { - memset(out - plen, 0, plen); - return -1; - } - } - } else if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { - if (CRYPTO_memcmp(temp, actx->tag, actx->tag_len)) - return -1; - } - } - return (int)len; -} - -static int chacha20_poly1305_cleanup(EVP_CIPHER_CTX *ctx) -{ - EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); - if (actx) - OPENSSL_cleanse(ctx->cipher_data, sizeof(*actx) + Poly1305_ctx_size()); - return 1; -} - -static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, - void *ptr) -{ - EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); - - switch (type) { - case EVP_CTRL_INIT: - if (actx == NULL) - actx = ctx->cipher_data - = OPENSSL_zalloc(sizeof(*actx) + Poly1305_ctx_size()); - if (actx == NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); - return 0; - } - actx->len.aad = 0; - actx->len.text = 0; - actx->aad = 0; - actx->mac_inited = 0; - actx->tag_len = 0; - actx->nonce_len = 12; - actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; - memset(actx->tls_aad, 0, POLY1305_BLOCK_SIZE); - return 1; - - case EVP_CTRL_COPY: - if (actx) { - EVP_CIPHER_CTX *dst = (EVP_CIPHER_CTX *)ptr; - - dst->cipher_data = OPENSSL_memdup(actx, sizeof(*actx) + Poly1305_ctx_size()); - if (dst->cipher_data == NULL) { - ERR_raise(ERR_LIB_EVP, EVP_R_COPY_ERROR); - return 0; - } - } - return 1; - - case EVP_CTRL_GET_IVLEN: - *(int *)ptr = actx->nonce_len; - return 1; - - case EVP_CTRL_AEAD_SET_IVLEN: - if (arg <= 0 || arg > CHACHA20_POLY1305_MAX_IVLEN) - return 0; - actx->nonce_len = arg; - return 1; - - case EVP_CTRL_AEAD_SET_IV_FIXED: - if (arg != 12) - return 0; - actx->nonce[0] = actx->key.counter[1] - = CHACHA_U8TOU32((unsigned char *)ptr); - actx->nonce[1] = actx->key.counter[2] - = CHACHA_U8TOU32((unsigned char *)ptr + 4); - actx->nonce[2] = actx->key.counter[3] - = CHACHA_U8TOU32((unsigned char *)ptr + 8); - return 1; - - case EVP_CTRL_AEAD_SET_TAG: - if (arg <= 0 || arg > POLY1305_BLOCK_SIZE) - return 0; - if (ptr != NULL) { - memcpy(actx->tag, ptr, arg); - actx->tag_len = arg; - } - return 1; - - case EVP_CTRL_AEAD_GET_TAG: - if (arg <= 0 || arg > POLY1305_BLOCK_SIZE || !EVP_CIPHER_CTX_is_encrypting(ctx)) - return 0; - memcpy(ptr, actx->tag, arg); - return 1; - - case EVP_CTRL_AEAD_TLS1_AAD: - if (arg != EVP_AEAD_TLS1_AAD_LEN) - return 0; - { - unsigned int len; - unsigned char *aad = ptr; - - memcpy(actx->tls_aad, ptr, EVP_AEAD_TLS1_AAD_LEN); - len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 | aad[EVP_AEAD_TLS1_AAD_LEN - 1]; - aad = actx->tls_aad; - if (!EVP_CIPHER_CTX_is_encrypting(ctx)) { - if (len < POLY1305_BLOCK_SIZE) - return 0; - len -= POLY1305_BLOCK_SIZE; /* discount attached tag */ - aad[EVP_AEAD_TLS1_AAD_LEN - 2] = (unsigned char)(len >> 8); - aad[EVP_AEAD_TLS1_AAD_LEN - 1] = (unsigned char)len; - } - actx->tls_payload_length = len; - - /* - * merge record sequence number as per RFC7905 - */ - actx->key.counter[1] = actx->nonce[0]; - actx->key.counter[2] = actx->nonce[1] ^ CHACHA_U8TOU32(aad); - actx->key.counter[3] = actx->nonce[2] ^ CHACHA_U8TOU32(aad + 4); - actx->mac_inited = 0; - - return POLY1305_BLOCK_SIZE; /* tag length */ - } - - case EVP_CTRL_AEAD_SET_MAC_KEY: - /* no-op */ - return 1; - - default: - return -1; - } -} static const EVP_CIPHER chacha20_poly1305 = { NID_chacha20_poly1305, @@ -612,13 +50,13 @@ static const EVP_CIPHER chacha20_poly1305 = { 12, /* iv_len, 96-bit nonce in the context */ EVP_CIPH_FLAG_AEAD_CIPHER | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY | EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_CUSTOM_IV_LENGTH, EVP_ORIG_GLOBAL, - chacha20_poly1305_init_key, - chacha20_poly1305_cipher, - chacha20_poly1305_cleanup, - 0, /* 0 moves context-specific structure allocation to ctrl */ + NULL, + NULL, + NULL, + 0, NULL, /* set_asn1_parameters */ NULL, /* get_asn1_parameters */ - chacha20_poly1305_ctrl, + NULL, NULL /* app_data */ };