X-Git-Url: https://git.openssl.org/gitweb/?a=blobdiff_plain;f=crypto%2Fevp%2Fe_chacha20_poly1305.c;h=9bf98f16a52caf7e9ae4e54f24317488372035bc;hb=efb8128ad56924736f50c01cde94b1716560aec7;hp=e3a0bef8c5896c7cadab4548d04c63fec1855148;hpb=6286757141a8c6e14d647ec733634ae0c83d9887;p=openssl.git diff --git a/crypto/evp/e_chacha20_poly1305.c b/crypto/evp/e_chacha20_poly1305.c index e3a0bef8c5..9bf98f16a5 100644 --- a/crypto/evp/e_chacha20_poly1305.c +++ b/crypto/evp/e_chacha20_poly1305.c @@ -127,7 +127,7 @@ static const EVP_CIPHER chacha20 = { 1, /* block_size */ CHACHA_KEY_SIZE, /* key_len */ CHACHA_CTR_SIZE, /* iv_len, 128-bit counter in the context */ - 0, /* flags */ + EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT, chacha_init_key, chacha_cipher, NULL, @@ -140,7 +140,7 @@ static const EVP_CIPHER chacha20 = { const EVP_CIPHER *EVP_chacha20(void) { - return (&chacha20); + return &chacha20; } # ifndef OPENSSL_NO_POLY1305 @@ -164,7 +164,6 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *iv, int enc) { EVP_CHACHA_AEAD_CTX *actx = aead_data(ctx); - unsigned char temp[CHACHA_CTR_SIZE]; if (!inkey && !iv) return 1; @@ -175,16 +174,21 @@ static int chacha20_poly1305_init_key(EVP_CIPHER_CTX *ctx, actx->mac_inited = 0; actx->tls_payload_length = NO_TLS_PAYLOAD_LENGTH; - /* pad on the left */ - memset(temp, 0, sizeof(temp)); - if (actx->nonce_len <= CHACHA_CTR_SIZE) - memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, actx->nonce_len); + if (iv != NULL) { + unsigned char temp[CHACHA_CTR_SIZE] = { 0 }; - chacha_init_key(ctx, inkey, temp, enc); + /* pad on the left */ + if (actx->nonce_len <= CHACHA_CTR_SIZE) + memcpy(temp + CHACHA_CTR_SIZE - actx->nonce_len, iv, actx->nonce_len); - actx->nonce[0] = actx->key.counter[1]; - actx->nonce[1] = actx->key.counter[2]; - actx->nonce[2] = actx->key.counter[3]; + 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; } @@ -295,7 +299,7 @@ static int chacha20_poly1305_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, memcpy(out, actx->tag, POLY1305_BLOCK_SIZE); } else { if (CRYPTO_memcmp(temp, in, POLY1305_BLOCK_SIZE)) { - memset(out, 0, plen); + memset(out - plen, 0, plen); return -1; } } @@ -312,7 +316,7 @@ 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(*ctx) + Poly1305_ctx_size()); + OPENSSL_cleanse(ctx->cipher_data, sizeof(*actx) + Poly1305_ctx_size()); return 1; } @@ -341,9 +345,11 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, case EVP_CTRL_COPY: if (actx) { - if ((((EVP_CIPHER_CTX *)ptr)->cipher_data = - OPENSSL_memdup(actx,sizeof(*actx) + Poly1305_ctx_size())) - == NULL) { + EVP_CIPHER_CTX *dst = (EVP_CIPHER_CTX *)ptr; + + dst->cipher_data = + OPENSSL_memdup(actx, sizeof(*actx) + Poly1305_ctx_size()); + if (dst->cipher_data == NULL) { EVPerr(EVP_F_CHACHA20_POLY1305_CTRL, EVP_R_COPY_ERROR); return 0; } @@ -392,6 +398,8 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, len = aad[EVP_AEAD_TLS1_AAD_LEN - 2] << 8 | aad[EVP_AEAD_TLS1_AAD_LEN - 1]; if (!ctx->encrypt) { + if (len < POLY1305_BLOCK_SIZE) + return 0; len -= POLY1305_BLOCK_SIZE; /* discount attached tag */ memcpy(temp, aad, EVP_AEAD_TLS1_AAD_LEN - 2); aad = temp; @@ -401,8 +409,7 @@ static int chacha20_poly1305_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, actx->tls_payload_length = len; /* - * merge record sequence number as per - * draft-ietf-tls-chacha20-poly1305-03 + * merge record sequence number as per RFC7905 */ actx->key.counter[1] = actx->nonce[0]; actx->key.counter[2] = actx->nonce[1] ^ CHACHA_U8TOU32(aad);