From 0ab86cf6f900a594187469ff5d546e5be203a480 Mon Sep 17 00:00:00 2001 From: Adam Langley Date: Thu, 25 Jan 2018 15:43:48 -0800 Subject: [PATCH] Require only that the nonce be strictly monotonic in TLS's AES-GCM Previously we required that the calls to TLS's AES-GCM use an incrementing nonce. This change relaxes that requirement so that nonces need only be strictly monotonic (i.e. values can now be skipped). This still meets the uniqueness requirements of a nonce. Change-Id: Ib649a58bb93bf4dc0e081de8a5971daefffe9c70 Reviewed-on: https://boringssl-review.googlesource.com/25384 Commit-Queue: David Benjamin Reviewed-by: David Benjamin CQ-Verified: CQ bot account: commit-bot@chromium.org --- crypto/fipsmodule/cipher/e_aes.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/crypto/fipsmodule/cipher/e_aes.c b/crypto/fipsmodule/cipher/e_aes.c index b4692767..8377f0c1 100644 --- a/crypto/fipsmodule/cipher/e_aes.c +++ b/crypto/fipsmodule/cipher/e_aes.c @@ -1148,7 +1148,7 @@ struct aead_aes_gcm_ctx { struct aead_aes_gcm_tls12_ctx { struct aead_aes_gcm_ctx gcm_ctx; - uint64_t counter; + uint64_t min_next_nonce; }; static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx, @@ -1349,7 +1349,7 @@ static int aead_aes_gcm_tls12_init(EVP_AEAD_CTX *ctx, const uint8_t *key, return 0; } - gcm_ctx->counter = 0; + gcm_ctx->min_next_nonce = 0; size_t actual_tag_len; if (!aead_aes_gcm_init_impl(&gcm_ctx->gcm_ctx, &actual_tag_len, key, key_len, @@ -1373,23 +1373,23 @@ static int aead_aes_gcm_tls12_seal_scatter( size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, size_t extra_in_len, const uint8_t *ad, size_t ad_len) { struct aead_aes_gcm_tls12_ctx *gcm_ctx = ctx->aead_state; - if (gcm_ctx->counter == UINT64_MAX) { - OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); - return 0; - } - if (nonce_len != 12) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); return 0; } - const uint64_t be_counter = CRYPTO_bswap8(gcm_ctx->counter); - if (OPENSSL_memcmp((uint8_t *)&be_counter, nonce + nonce_len - 8, 8) != 0) { + // The given nonces must be strictly monotonically increasing. + uint64_t given_counter; + OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), + sizeof(given_counter)); + given_counter = CRYPTO_bswap8(given_counter); + if (given_counter == UINT64_MAX || + given_counter < gcm_ctx->min_next_nonce) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); return 0; } - gcm_ctx->counter++; + gcm_ctx->min_next_nonce = given_counter + 1; return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, max_out_tag_len, nonce, nonce_len, in,