Move AES_KEY into GCM128_KEY, GCM128_KEY out of GCM128_CONTEXT AES_KEY was separate from GCM128_KEY because crypto/modes was originally written as if there were non-AES 128-bit block ciphers to worry about. This has long since stopped being the case for BoringSSL. This avoids some duplicate key setup logic in EVP_CIPHER and EVP_AEAD. GCM128_KEY was embedded into GCM128_CONTEXT because OpenSSL assembly once relied on the exact order of a bunch of the fields, some of which we per-operation and some of which were per-key. See https://boringssl-review.googlesource.com/c/boringssl/+/13122 This assumption has since been removed. See https://boringssl-review.googlesource.com/c/boringssl/+/59526 Now that that is done, we can pull it out and instead pass it in as a separate pointer, like how AES_KEY used to. (I made the key the first argument because key than op seems more natural to me than op than key. Also I didn't noticed I'd flipped them until I was done with the CL.) By pulling it out, we avoid a pointless 500-ish byte memcpy before every AES-GCM operation, which actually speeds up shorter inputs non-trivially. See below. A nice bonus to cleaner code. This doesn't do all the things in crbug.com/382503563, but gets us partway towards it. It also gets the GCM128_* functions slightly closer to being a self-contained abstraction. As part of this, move aes_ctr_set_key into crypto/fipsmodule/aes instead of crypto/fipsmodule/cipher. It was previously in cipher because it depended on modes and modes already depends on aes, but now the GCM dependency is moved out, I think aes makes more sense for it. On an Intel(R) Xeon(R) Gold 6154 CPU @ 3.00GHz Before: Did 22847000 AES-128-GCM (16 bytes) seal operations in 2000070us (182.8 MB/sec) Did 13704000 AES-128-GCM (256 bytes) seal operations in 2000025us (1754.1 MB/sec) Did 5856000 AES-128-GCM (1350 bytes) seal operations in 2000107us (3952.6 MB/sec) Did 1323000 AES-128-GCM (8192 bytes) seal operations in 2001392us (5415.2 MB/sec) Did 683000 AES-128-GCM (16384 bytes) seal operations in 2000266us (5594.4 MB/sec) Did 20866750 AES-256-GCM (16 bytes) seal operations in 2000005us (166.9 MB/sec) Did 12114000 AES-256-GCM (256 bytes) seal operations in 2000109us (1550.5 MB/sec) Did 4572000 AES-256-GCM (1350 bytes) seal operations in 2000142us (3085.9 MB/sec) Did 972000 AES-256-GCM (8192 bytes) seal operations in 2000988us (3979.3 MB/sec) Did 497000 AES-256-GCM (16384 bytes) seal operations in 2000832us (4069.7 MB/sec) After: Did 25786000 AES-128-GCM (16 bytes) seal operations in 2000050us (206.3 MB/sec) [+12.9%] Did 14489000 AES-128-GCM (256 bytes) seal operations in 2000004us (1854.6 MB/sec) [+5.7%] Did 5927000 AES-128-GCM (1350 bytes) seal operations in 2000248us (4000.2 MB/sec) [+1.2%] Did 1316000 AES-128-GCM (8192 bytes) seal operations in 2000236us (5389.7 MB/sec) [-0.5%] Did 679000 AES-128-GCM (16384 bytes) seal operations in 2001792us (5557.4 MB/sec) [-0.7%] Did 23180500 AES-256-GCM (16 bytes) seal operations in 2000016us (185.4 MB/sec) [+11.1%] Did 12703000 AES-256-GCM (256 bytes) seal operations in 2000070us (1625.9 MB/sec) [+4.9%] Did 4668000 AES-256-GCM (1350 bytes) seal operations in 2000238us (3150.5 MB/sec) [+2.1%] Did 976000 AES-256-GCM (8192 bytes) seal operations in 2000115us (3997.5 MB/sec) [+0.5%] Did 500000 AES-256-GCM (16384 bytes) seal operations in 2001380us (4093.2 MB/sec) [+0.6%] The difference is even more pronounced on GCC: Before: Did 19500000 AES-128-GCM (16 bytes) seal operations in 2000077us (156.0 MB/sec) Did 12833000 AES-128-GCM (256 bytes) seal operations in 2000040us (1642.6 MB/sec) Did 5544000 AES-128-GCM (1350 bytes) seal operations in 2000325us (3741.6 MB/sec) Did 1305000 AES-128-GCM (8192 bytes) seal operations in 2000029us (5345.2 MB/sec) Did 677000 AES-128-GCM (16384 bytes) seal operations in 2002554us (5538.9 MB/sec) Did 18222000 AES-256-GCM (16 bytes) seal operations in 2000026us (145.8 MB/sec) Did 11351750 AES-256-GCM (256 bytes) seal operations in 2000036us (1453.0 MB/sec) Did 4431000 AES-256-GCM (1350 bytes) seal operations in 2000278us (2990.5 MB/sec) Did 965000 AES-256-GCM (8192 bytes) seal operations in 2000617us (3951.4 MB/sec) Did 497000 AES-256-GCM (16384 bytes) seal operations in 2003070us (4065.2 MB/sec) After: Did 25878000 AES-128-GCM (16 bytes) seal operations in 2000001us (207.0 MB/sec) [+32.7%] Did 14510250 AES-128-GCM (256 bytes) seal operations in 2000034us (1857.3 MB/sec) [+13.1%] Did 5936000 AES-128-GCM (1350 bytes) seal operations in 2000273us (4006.3 MB/sec) [+7.1%] Did 1314000 AES-128-GCM (8192 bytes) seal operations in 2000033us (5382.1 MB/sec) [+0.7%] Did 677000 AES-128-GCM (16384 bytes) seal operations in 2002827us (5538.2 MB/sec) [-0.0%] Did 23281000 AES-256-GCM (16 bytes) seal operations in 2000048us (186.2 MB/sec) [+27.8%] Did 12750000 AES-256-GCM (256 bytes) seal operations in 2000008us (1632.0 MB/sec) [+12.3%] Did 4685000 AES-256-GCM (1350 bytes) seal operations in 2000205us (3162.1 MB/sec) [+5.7%] Did 977000 AES-256-GCM (8192 bytes) seal operations in 2001842us (3998.1 MB/sec) [+1.2%] Did 501000 AES-256-GCM (16384 bytes) seal operations in 2003419us (4097.2 MB/sec) [+0.8%] Bug: 382503563, 42290602 Change-Id: I4690b79212242084cbcde49aa59979344012e5f6 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/74268 Reviewed-by: Adam Langley <agl@google.com> Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/cipher_extra/e_aesctrhmac.cc b/crypto/cipher_extra/e_aesctrhmac.cc index be94d73..f9845a4 100644 --- a/crypto/cipher_extra/e_aesctrhmac.cc +++ b/crypto/cipher_extra/e_aesctrhmac.cc
@@ -21,6 +21,7 @@ #include <openssl/err.h> #include <openssl/sha.h> +#include "../fipsmodule/aes/internal.h" #include "../fipsmodule/cipher/internal.h"
diff --git a/crypto/cipher_extra/e_aesgcmsiv.cc b/crypto/cipher_extra/e_aesgcmsiv.cc index 9574b3b..036c7a1 100644 --- a/crypto/cipher_extra/e_aesgcmsiv.cc +++ b/crypto/cipher_extra/e_aesgcmsiv.cc
@@ -20,6 +20,7 @@ #include <openssl/crypto.h> #include <openssl/err.h> +#include "../fipsmodule/aes/internal.h" #include "../fipsmodule/cipher/internal.h" #include "../internal.h"
diff --git a/crypto/fipsmodule/aes/aes.cc.inc b/crypto/fipsmodule/aes/aes.cc.inc index 05f7a2b..152f76a 100644 --- a/crypto/fipsmodule/aes/aes.cc.inc +++ b/crypto/fipsmodule/aes/aes.cc.inc
@@ -144,3 +144,83 @@ } } #endif + +#if defined(BSAES) +void vpaes_ctr32_encrypt_blocks_with_bsaes(const uint8_t *in, uint8_t *out, + size_t blocks, const AES_KEY *key, + const uint8_t ivec[16]) { + // |bsaes_ctr32_encrypt_blocks| is faster than |vpaes_ctr32_encrypt_blocks|, + // but it takes at least one full 8-block batch to amortize the conversion. + if (blocks < 8) { + vpaes_ctr32_encrypt_blocks(in, out, blocks, key, ivec); + return; + } + + size_t bsaes_blocks = blocks; + if (bsaes_blocks % 8 < 6) { + // |bsaes_ctr32_encrypt_blocks| internally works in 8-block batches. If the + // final batch is too small (under six blocks), it is faster to loop over + // |vpaes_encrypt|. Round |bsaes_blocks| down to a multiple of 8. + bsaes_blocks -= bsaes_blocks % 8; + } + + AES_KEY bsaes; + vpaes_encrypt_key_to_bsaes(&bsaes, key); + bsaes_ctr32_encrypt_blocks(in, out, bsaes_blocks, &bsaes, ivec); + OPENSSL_cleanse(&bsaes, sizeof(bsaes)); + + in += 16 * bsaes_blocks; + out += 16 * bsaes_blocks; + blocks -= bsaes_blocks; + + uint8_t new_ivec[16]; + memcpy(new_ivec, ivec, 12); + uint32_t ctr = CRYPTO_load_u32_be(ivec + 12) + bsaes_blocks; + CRYPTO_store_u32_be(new_ivec + 12, ctr); + + // Finish any remaining blocks with |vpaes_ctr32_encrypt_blocks|. + vpaes_ctr32_encrypt_blocks(in, out, blocks, key, new_ivec); +} +#endif // BSAES + +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, int *out_is_hwaes, + block128_f *out_block, const uint8_t *key, + size_t key_bytes) { + // This function assumes the key length was previously validated. + assert(key_bytes == 128 / 8 || key_bytes == 192 / 8 || key_bytes == 256 / 8); + if (hwaes_capable()) { + aes_hw_set_encrypt_key(key, (int)key_bytes * 8, aes_key); + if (out_is_hwaes) { + *out_is_hwaes = 1; + } + if (out_block) { + *out_block = aes_hw_encrypt; + } + return aes_hw_ctr32_encrypt_blocks; + } + + if (vpaes_capable()) { + vpaes_set_encrypt_key(key, (int)key_bytes * 8, aes_key); + if (out_block) { + *out_block = vpaes_encrypt; + } + if (out_is_hwaes) { + *out_is_hwaes = 0; + } +#if defined(BSAES) + assert(bsaes_capable()); + return vpaes_ctr32_encrypt_blocks_with_bsaes; +#else + return vpaes_ctr32_encrypt_blocks; +#endif + } + + aes_nohw_set_encrypt_key(key, (int)key_bytes * 8, aes_key); + if (out_is_hwaes) { + *out_is_hwaes = 0; + } + if (out_block) { + *out_block = aes_nohw_encrypt; + } + return aes_nohw_ctr32_encrypt_blocks; +}
diff --git a/crypto/fipsmodule/aes/internal.h b/crypto/fipsmodule/aes/internal.h index 7730b00..fa5ba87 100644 --- a/crypto/fipsmodule/aes/internal.h +++ b/crypto/fipsmodule/aes/internal.h
@@ -24,6 +24,34 @@ extern "C" { +// block128_f is the type of an AES block cipher implementation. +// +// Unlike upstream OpenSSL, it and the other functions in this file hard-code +// |AES_KEY|. It is undefined in C to call a function pointer with anything +// other than the original type. Thus we either must match |block128_f| to the +// type signature of |AES_encrypt| and friends or pass in |void*| wrapper +// functions. +// +// These functions are called exclusively with AES, so we use the former. +typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16], + const AES_KEY *key); + +// ctr128_f is the type of a function that performs CTR-mode encryption. +typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks, + const AES_KEY *key, const uint8_t ivec[16]); + +// aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|, +// where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is +// set to a function that encrypts single blocks. If not NULL, |*out_is_hwaes| +// is set to whether the hardware AES implementation was used. It returns a +// function for optimised CTR-mode. +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, int *out_is_hwaes, + block128_f *out_block, const uint8_t *key, + size_t key_bytes); + + +// AES implementations. + #if !defined(OPENSSL_NO_ASM) #if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) @@ -152,6 +180,9 @@ // VPAES to BSAES conversions are available on all BSAES platforms. void vpaes_encrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes); void vpaes_decrypt_key_to_bsaes(AES_KEY *out_bsaes, const AES_KEY *vpaes); +void vpaes_ctr32_encrypt_blocks_with_bsaes(const uint8_t *in, uint8_t *out, + size_t blocks, const AES_KEY *key, + const uint8_t ivec[16]); #else OPENSSL_INLINE char bsaes_capable(void) { return 0; }
diff --git a/crypto/fipsmodule/cipher/e_aes.cc.inc b/crypto/fipsmodule/cipher/e_aes.cc.inc index 30957f0..346cd8b 100644 --- a/crypto/fipsmodule/cipher/e_aes.cc.inc +++ b/crypto/fipsmodule/cipher/e_aes.cc.inc
@@ -71,45 +71,6 @@ #define AES_GCM_NONCE_LENGTH 12 -#if defined(BSAES) -static void vpaes_ctr32_encrypt_blocks_with_bsaes(const uint8_t *in, - uint8_t *out, size_t blocks, - const AES_KEY *key, - const uint8_t ivec[16]) { - // |bsaes_ctr32_encrypt_blocks| is faster than |vpaes_ctr32_encrypt_blocks|, - // but it takes at least one full 8-block batch to amortize the conversion. - if (blocks < 8) { - vpaes_ctr32_encrypt_blocks(in, out, blocks, key, ivec); - return; - } - - size_t bsaes_blocks = blocks; - if (bsaes_blocks % 8 < 6) { - // |bsaes_ctr32_encrypt_blocks| internally works in 8-block batches. If the - // final batch is too small (under six blocks), it is faster to loop over - // |vpaes_encrypt|. Round |bsaes_blocks| down to a multiple of 8. - bsaes_blocks -= bsaes_blocks % 8; - } - - AES_KEY bsaes; - vpaes_encrypt_key_to_bsaes(&bsaes, key); - bsaes_ctr32_encrypt_blocks(in, out, bsaes_blocks, &bsaes, ivec); - OPENSSL_cleanse(&bsaes, sizeof(bsaes)); - - in += 16 * bsaes_blocks; - out += 16 * bsaes_blocks; - blocks -= bsaes_blocks; - - uint8_t new_ivec[16]; - memcpy(new_ivec, ivec, 12); - uint32_t ctr = CRYPTO_load_u32_be(ivec + 12) + bsaes_blocks; - CRYPTO_store_u32_be(new_ivec + 12, ctr); - - // Finish any remaining blocks with |vpaes_ctr32_encrypt_blocks|. - vpaes_ctr32_encrypt_blocks(in, out, blocks, key, new_ivec); -} -#endif // BSAES - typedef struct { union { double align; @@ -123,11 +84,8 @@ } EVP_AES_KEY; typedef struct { + GCM128_KEY key; GCM128_CONTEXT gcm; - union { - double align; - AES_KEY ks; - } ks; // AES key schedule to use int key_set; // Set if key initialised int iv_set; // Set if an iv is set uint8_t *iv; // Temporary IV store @@ -283,48 +241,6 @@ return 1; } -ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, - block128_f *out_block, const uint8_t *key, - size_t key_bytes) { - // This function assumes the key length was previously validated. - assert(key_bytes == 128 / 8 || key_bytes == 192 / 8 || key_bytes == 256 / 8); - if (hwaes_capable()) { - aes_hw_set_encrypt_key(key, (int)key_bytes * 8, aes_key); - if (gcm_key != NULL) { - CRYPTO_gcm128_init_key(gcm_key, aes_key, aes_hw_encrypt, 1); - } - if (out_block) { - *out_block = aes_hw_encrypt; - } - return aes_hw_ctr32_encrypt_blocks; - } - - if (vpaes_capable()) { - vpaes_set_encrypt_key(key, (int)key_bytes * 8, aes_key); - if (out_block) { - *out_block = vpaes_encrypt; - } - if (gcm_key != NULL) { - CRYPTO_gcm128_init_key(gcm_key, aes_key, vpaes_encrypt, 0); - } -#if defined(BSAES) - assert(bsaes_capable()); - return vpaes_ctr32_encrypt_blocks_with_bsaes; -#else - return vpaes_ctr32_encrypt_blocks; -#endif - } - - aes_nohw_set_encrypt_key(key, (int)key_bytes * 8, aes_key); - if (gcm_key != NULL) { - CRYPTO_gcm128_init_key(gcm_key, aes_key, aes_nohw_encrypt, 0); - } - if (out_block) { - *out_block = aes_nohw_encrypt; - } - return aes_nohw_ctr32_encrypt_blocks; -} - #if defined(OPENSSL_32_BIT) #define EVP_AES_GCM_CTX_PADDING (4 + 8) #else @@ -368,24 +284,25 @@ break; } + // We must configure first the key, then the IV, but the caller may pass both + // together, or separately in either order. if (key) { OPENSSL_memset(&gctx->gcm, 0, sizeof(gctx->gcm)); - gctx->ctr = aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm.gcm_key, NULL, key, - ctx->key_len); - // If we have an iv can set it directly, otherwise use saved IV. + CRYPTO_gcm128_init_aes_key(&gctx->key, key, ctx->key_len); + // Use the IV if specified. Otherwise, use the saved IV, if any. if (iv == NULL && gctx->iv_set) { iv = gctx->iv; } if (iv) { - CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen); + CRYPTO_gcm128_init_ctx(&gctx->key, &gctx->gcm, iv, gctx->ivlen); gctx->iv_set = 1; } gctx->key_set = 1; } else { - // If key set use IV, otherwise copy if (gctx->key_set) { - CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen); + CRYPTO_gcm128_init_ctx(&gctx->key, &gctx->gcm, iv, gctx->ivlen); } else { + // The caller specified the IV before the key. Save the IV for later. OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen); } gctx->iv_set = 1; @@ -396,6 +313,7 @@ static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) { EVP_AES_GCM_CTX *gctx = aes_gcm_from_cipher_ctx(c); + OPENSSL_cleanse(&gctx->key, sizeof(gctx->key)); OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); if (gctx->iv != c->iv) { OPENSSL_free(gctx->iv); @@ -479,7 +397,7 @@ if (gctx->iv_gen == 0 || gctx->key_set == 0) { return 0; } - CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen); + CRYPTO_gcm128_init_ctx(&gctx->key, &gctx->gcm, gctx->iv, gctx->ivlen); if (arg <= 0 || arg > gctx->ivlen) { arg = gctx->ivlen; } @@ -497,7 +415,7 @@ return 0; } OPENSSL_memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); - CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen); + CRYPTO_gcm128_init_ctx(&gctx->key, &gctx->gcm, gctx->iv, gctx->ivlen); gctx->iv_set = 1; return 1; @@ -546,31 +464,29 @@ if (in) { if (out == NULL) { - if (!CRYPTO_gcm128_aad(&gctx->gcm, in, len)) { + if (!CRYPTO_gcm128_aad(&gctx->key, &gctx->gcm, in, len)) { return -1; } } else if (ctx->encrypt) { - if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, - gctx->ctr)) { + if (!CRYPTO_gcm128_encrypt(&gctx->key, &gctx->gcm, in, out, len)) { return -1; } } else { - if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, - gctx->ctr)) { + if (!CRYPTO_gcm128_decrypt(&gctx->key, &gctx->gcm, in, out, len)) { return -1; } } return (int)len; } else { if (!ctx->encrypt) { - if (gctx->taglen < 0 || - !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) { + if (gctx->taglen < 0 || !CRYPTO_gcm128_finish(&gctx->key, &gctx->gcm, + ctx->buf, gctx->taglen)) { return -1; } gctx->iv_set = 0; return 0; } - CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); + CRYPTO_gcm128_tag(&gctx->key, &gctx->gcm, ctx->buf, 16); gctx->taglen = 16; // Don't reuse the IV gctx->iv_set = 0; @@ -860,12 +776,7 @@ #define EVP_AEAD_AES_GCM_TAG_LEN 16 struct aead_aes_gcm_ctx { - union { - double align; - AES_KEY ks; - } ks; - GCM128_KEY gcm_key; - ctr128_f ctr; + GCM128_KEY key; }; static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx, @@ -897,8 +808,7 @@ return 0; } - gcm_ctx->ctr = - aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm_key, NULL, key, key_len); + CRYPTO_gcm128_init_aes_key(&gcm_ctx->key, key, key_len); *out_tag_len = tag_len; return 1; } @@ -944,28 +854,24 @@ return 0; } - const AES_KEY *key = &gcm_ctx->ks.ks; - + const GCM128_KEY *key = &gcm_ctx->key; GCM128_CONTEXT gcm; - OPENSSL_memset(&gcm, 0, sizeof(gcm)); - OPENSSL_memcpy(&gcm.gcm_key, &gcm_ctx->gcm_key, sizeof(gcm.gcm_key)); - CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + CRYPTO_gcm128_init_ctx(key, &gcm, nonce, nonce_len); - if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + if (ad_len > 0 && !CRYPTO_gcm128_aad(key, &gcm, ad, ad_len)) { return 0; } - if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len, gcm_ctx->ctr)) { + if (!CRYPTO_gcm128_encrypt(key, &gcm, in, out, in_len)) { return 0; } if (extra_in_len > 0 && - !CRYPTO_gcm128_encrypt_ctr32(&gcm, key, extra_in, out_tag, extra_in_len, - gcm_ctx->ctr)) { + !CRYPTO_gcm128_encrypt(key, &gcm, extra_in, out_tag, extra_in_len)) { return 0; } - CRYPTO_gcm128_tag(&gcm, out_tag + extra_in_len, tag_len); + CRYPTO_gcm128_tag(key, &gcm, out_tag + extra_in_len, tag_len); *out_tag_len = tag_len + extra_in_len; return 1; @@ -1001,22 +907,19 @@ return 0; } - const AES_KEY *key = &gcm_ctx->ks.ks; - + const GCM128_KEY *key = &gcm_ctx->key; GCM128_CONTEXT gcm; - OPENSSL_memset(&gcm, 0, sizeof(gcm)); - OPENSSL_memcpy(&gcm.gcm_key, &gcm_ctx->gcm_key, sizeof(gcm.gcm_key)); - CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + CRYPTO_gcm128_init_ctx(key, &gcm, nonce, nonce_len); - if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + if (!CRYPTO_gcm128_aad(key, &gcm, ad, ad_len)) { return 0; } - if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out, in_len, gcm_ctx->ctr)) { + if (!CRYPTO_gcm128_decrypt(key, &gcm, in, out, in_len)) { return 0; } - CRYPTO_gcm128_tag(&gcm, tag, tag_len); + CRYPTO_gcm128_tag(key, &gcm, tag, tag_len); if (CRYPTO_memcmp(tag, in_tag, tag_len) != 0) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0;
diff --git a/crypto/fipsmodule/cipher/e_aesccm.cc.inc b/crypto/fipsmodule/cipher/e_aesccm.cc.inc index e1682b6..ede2988 100644 --- a/crypto/fipsmodule/cipher/e_aesccm.cc.inc +++ b/crypto/fipsmodule/cipher/e_aesccm.cc.inc
@@ -55,6 +55,7 @@ #include <openssl/mem.h> #include "../delocate.h" +#include "../aes/internal.h" #include "../modes/internal.h" #include "../service_indicator/internal.h" #include "internal.h"
diff --git a/crypto/fipsmodule/cipher/internal.h b/crypto/fipsmodule/cipher/internal.h index e9709f0..6e9e73b 100644 --- a/crypto/fipsmodule/cipher/internal.h +++ b/crypto/fipsmodule/cipher/internal.h
@@ -148,15 +148,6 @@ int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); }; -// aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|, -// where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is -// set to a function that encrypts single blocks. If not NULL, |*gcm_key| is -// initialised to do GHASH with the given key. It returns a function for -// optimised CTR-mode. -ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_KEY *gcm_key, - block128_f *out_block, const uint8_t *key, - size_t key_bytes); - #if defined(__cplusplus) } // extern C #endif
diff --git a/crypto/fipsmodule/modes/gcm.cc.inc b/crypto/fipsmodule/modes/gcm.cc.inc index cbd1858..10ec1be 100644 --- a/crypto/fipsmodule/modes/gcm.cc.inc +++ b/crypto/fipsmodule/modes/gcm.cc.inc
@@ -48,13 +48,13 @@ #include <openssl/base.h> -#include <assert.h> #include <string.h> #include <openssl/mem.h> -#include "internal.h" #include "../../internal.h" +#include "../aes/internal.h" +#include "internal.h" // kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four @@ -62,9 +62,9 @@ static const size_t kSizeTWithoutLower4Bits = (size_t) -16; -#define GCM_MUL(ctx, Xi) gcm_gmult_nohw((ctx)->Xi, (ctx)->gcm_key.Htable) -#define GHASH(ctx, in, len) \ - gcm_ghash_nohw((ctx)->Xi, (ctx)->gcm_key.Htable, in, len) +#define GCM_MUL(key, ctx, Xi) gcm_gmult_nohw((ctx)->Xi, (key)->Htable) +#define GHASH(key, ctx, in, len) \ + gcm_ghash_nohw((ctx)->Xi, (key)->Htable, in, len) // GHASH_CHUNK is "stride parameter" missioned to mitigate cache // trashing effect. In other words idea is to hash data while it's // still in L1 cache after encryption pass... @@ -126,10 +126,10 @@ #ifdef GCM_FUNCREF #undef GCM_MUL -#define GCM_MUL(ctx, Xi) (*gcm_gmult_p)((ctx)->Xi, (ctx)->gcm_key.Htable) +#define GCM_MUL(key, ctx, Xi) (*gcm_gmult_p)((ctx)->Xi, (key)->Htable) #undef GHASH -#define GHASH(ctx, in, len) \ - (*gcm_ghash_p)((ctx)->Xi, (ctx)->gcm_key.Htable, in, len) +#define GHASH(key, ctx, in, len) \ + (*gcm_ghash_p)((ctx)->Xi, (key)->Htable, in, len) #endif // GCM_FUNCREF #if defined(HW_GCM) && defined(OPENSSL_X86_64) @@ -272,14 +272,16 @@ *out_hash = gcm_ghash_nohw; } -void CRYPTO_gcm128_init_key(GCM128_KEY *gcm_key, const AES_KEY *aes_key, - block128_f block, int block_is_hwaes) { +void CRYPTO_gcm128_init_aes_key(GCM128_KEY *gcm_key, const uint8_t *key, + size_t key_bytes) { OPENSSL_memset(gcm_key, 0, sizeof(*gcm_key)); - gcm_key->block = block; + int is_hwaes; + gcm_key->ctr = aes_ctr_set_key(&gcm_key->aes, &is_hwaes, &gcm_key->block, key, + key_bytes); uint8_t ghash_key[16]; OPENSSL_memset(ghash_key, 0, sizeof(ghash_key)); - (*block)(ghash_key, ghash_key, aes_key); + gcm_key->block(ghash_key, ghash_key, &gcm_key->aes); CRYPTO_ghash_init(&gcm_key->gmult, &gcm_key->ghash, gcm_key->Htable, ghash_key); @@ -292,22 +294,21 @@ } else if (gcm_key->ghash == gcm_ghash_vpclmulqdq_avx10_512 && CRYPTO_is_VAES_capable()) { gcm_key->impl = gcm_x86_vaes_avx10_512; - } else if (gcm_key->ghash == gcm_ghash_avx && block_is_hwaes) { + } else if (gcm_key->ghash == gcm_ghash_avx && is_hwaes) { gcm_key->impl = gcm_x86_aesni; } #elif defined(OPENSSL_AARCH64) - if (gcm_pmull_capable() && block_is_hwaes) { + if (gcm_pmull_capable() && is_hwaes) { gcm_key->impl = gcm_arm64_aes; } #endif #endif } -void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const AES_KEY *key, - const uint8_t *iv, size_t len) { +void CRYPTO_gcm128_init_ctx(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *iv, size_t iv_len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = - ctx->gcm_key.gmult; + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult; #endif OPENSSL_memset(&ctx->Yi, 0, sizeof(ctx->Yi)); @@ -318,24 +319,24 @@ ctx->mres = 0; uint32_t ctr; - if (len == 12) { + if (iv_len == 12) { OPENSSL_memcpy(ctx->Yi, iv, 12); ctx->Yi[15] = 1; ctr = 1; } else { - uint64_t len0 = len; + uint64_t len0 = iv_len; - while (len >= 16) { + while (iv_len >= 16) { CRYPTO_xor16(ctx->Yi, ctx->Yi, iv); - GCM_MUL(ctx, Yi); + GCM_MUL(key, ctx, Yi); iv += 16; - len -= 16; + iv_len -= 16; } - if (len) { - for (size_t i = 0; i < len; ++i) { + if (iv_len) { + for (size_t i = 0; i < iv_len; ++i) { ctx->Yi[i] ^= iv[i]; } - GCM_MUL(ctx, Yi); + GCM_MUL(key, ctx, Yi); } uint8_t len_block[16]; @@ -343,21 +344,21 @@ CRYPTO_store_u64_be(len_block + 8, len0 << 3); CRYPTO_xor16(ctx->Yi, ctx->Yi, len_block); - GCM_MUL(ctx, Yi); + GCM_MUL(key, ctx, Yi); ctr = CRYPTO_load_u32_be(ctx->Yi + 12); } - (*ctx->gcm_key.block)(ctx->Yi, ctx->EK0, key); + key->block(ctx->Yi, ctx->EK0, &key->aes); ++ctr; CRYPTO_store_u32_be(ctx->Yi + 12, ctr); } -int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) { +int CRYPTO_gcm128_aad(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *aad, size_t aad_len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = - ctx->gcm_key.gmult; + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult; void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, - size_t len) = ctx->gcm_key.ghash; + size_t len) = key->ghash; #endif if (ctx->len.msg != 0) { @@ -365,21 +366,21 @@ return 0; } - uint64_t alen = ctx->len.aad + len; - if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) { + uint64_t alen = ctx->len.aad + aad_len; + if (alen > (UINT64_C(1) << 61) || (sizeof(aad_len) == 8 && alen < aad_len)) { return 0; } ctx->len.aad = alen; unsigned n = ctx->ares; if (n) { - while (n && len) { + while (n && aad_len) { ctx->Xi[n] ^= *(aad++); - --len; + --aad_len; n = (n + 1) % 16; } if (n == 0) { - GCM_MUL(ctx, Xi); + GCM_MUL(key, ctx, Xi); } else { ctx->ares = n; return 1; @@ -387,17 +388,17 @@ } // Process a whole number of blocks. - size_t len_blocks = len & kSizeTWithoutLower4Bits; + size_t len_blocks = aad_len & kSizeTWithoutLower4Bits; if (len_blocks != 0) { - GHASH(ctx, aad, len_blocks); + GHASH(key, ctx, aad, len_blocks); aad += len_blocks; - len -= len_blocks; + aad_len -= len_blocks; } // Process the remainder. - if (len != 0) { - n = (unsigned int)len; - for (size_t i = 0; i < len; ++i) { + if (aad_len != 0) { + n = (unsigned int)aad_len; + for (size_t i = 0; i < aad_len; ++i) { ctx->Xi[i] ^= aad[i]; } } @@ -406,14 +407,12 @@ return 1; } -int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, - const uint8_t *in, uint8_t *out, size_t len, - ctr128_f stream) { +int CRYPTO_gcm128_encrypt(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *in, uint8_t *out, size_t len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = - ctx->gcm_key.gmult; + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult; void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, - size_t len) = ctx->gcm_key.ghash; + size_t len) = key->ghash; #endif uint64_t mlen = ctx->len.msg + len; @@ -425,7 +424,7 @@ if (ctx->ares) { // First call to encrypt finalizes GHASH(AAD) - GCM_MUL(ctx, Xi); + GCM_MUL(key, ctx, Xi); ctx->ares = 0; } @@ -437,7 +436,7 @@ n = (n + 1) % 16; } if (n == 0) { - GCM_MUL(ctx, Xi); + GCM_MUL(key, ctx, Xi); } else { ctx->mres = n; return 1; @@ -446,11 +445,11 @@ #if defined(HW_GCM) // Check |len| to work around a C language bug. See https://crbug.com/1019588. - if (ctx->gcm_key.impl != gcm_separate && len > 0) { + if (key->impl != gcm_separate && len > 0) { // |hw_gcm_encrypt| may not process all the input given to it. It may // not process *any* of its input if it is deemed too small. - size_t bulk = hw_gcm_encrypt(in, out, len, key, ctx->Yi, ctx->Xi, - ctx->gcm_key.Htable, ctx->gcm_key.impl); + size_t bulk = hw_gcm_encrypt(in, out, len, &key->aes, ctx->Yi, ctx->Xi, + key->Htable, key->impl); in += bulk; out += bulk; len -= bulk; @@ -458,29 +457,31 @@ #endif uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12); + ctr128_f stream = key->ctr; while (len >= GHASH_CHUNK) { - (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi); + (*stream)(in, out, GHASH_CHUNK / 16, &key->aes, ctx->Yi); ctr += GHASH_CHUNK / 16; CRYPTO_store_u32_be(ctx->Yi + 12, ctr); - GHASH(ctx, out, GHASH_CHUNK); + GHASH(key, ctx, out, GHASH_CHUNK); out += GHASH_CHUNK; in += GHASH_CHUNK; len -= GHASH_CHUNK; } + size_t len_blocks = len & kSizeTWithoutLower4Bits; if (len_blocks != 0) { size_t j = len_blocks / 16; - - (*stream)(in, out, j, key, ctx->Yi); - ctr += (unsigned int)j; + (*stream)(in, out, j, &key->aes, ctx->Yi); + ctr += (uint32_t)j; CRYPTO_store_u32_be(ctx->Yi + 12, ctr); in += len_blocks; len -= len_blocks; - GHASH(ctx, out, len_blocks); + GHASH(key, ctx, out, len_blocks); out += len_blocks; } + if (len) { - (*ctx->gcm_key.block)(ctx->Yi, ctx->EKi, key); + key->block(ctx->Yi, ctx->EKi, &key->aes); ++ctr; CRYPTO_store_u32_be(ctx->Yi + 12, ctr); while (len--) { @@ -493,14 +494,12 @@ return 1; } -int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, - const uint8_t *in, uint8_t *out, size_t len, - ctr128_f stream) { +int CRYPTO_gcm128_decrypt(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *in, uint8_t *out, size_t len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = - ctx->gcm_key.gmult; + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult; void (*gcm_ghash_p)(uint8_t Xi[16], const u128 Htable[16], const uint8_t *inp, - size_t len) = ctx->gcm_key.ghash; + size_t len) = key->ghash; #endif uint64_t mlen = ctx->len.msg + len; @@ -512,7 +511,7 @@ if (ctx->ares) { // First call to decrypt finalizes GHASH(AAD) - GCM_MUL(ctx, Xi); + GCM_MUL(key, ctx, Xi); ctx->ares = 0; } @@ -526,7 +525,7 @@ n = (n + 1) % 16; } if (n == 0) { - GCM_MUL(ctx, Xi); + GCM_MUL(key, ctx, Xi); } else { ctx->mres = n; return 1; @@ -535,11 +534,11 @@ #if defined(HW_GCM) // Check |len| to work around a C language bug. See https://crbug.com/1019588. - if (ctx->gcm_key.impl != gcm_separate && len > 0) { + if (key->impl != gcm_separate && len > 0) { // |hw_gcm_decrypt| may not process all the input given to it. It may // not process *any* of its input if it is deemed too small. - size_t bulk = hw_gcm_decrypt(in, out, len, key, ctx->Yi, ctx->Xi, - ctx->gcm_key.Htable, ctx->gcm_key.impl); + size_t bulk = hw_gcm_decrypt(in, out, len, &key->aes, ctx->Yi, ctx->Xi, + key->Htable, key->impl); in += bulk; out += bulk; len -= bulk; @@ -547,29 +546,31 @@ #endif uint32_t ctr = CRYPTO_load_u32_be(ctx->Yi + 12); + ctr128_f stream = key->ctr; while (len >= GHASH_CHUNK) { - GHASH(ctx, in, GHASH_CHUNK); - (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi); + GHASH(key, ctx, in, GHASH_CHUNK); + (*stream)(in, out, GHASH_CHUNK / 16, &key->aes, ctx->Yi); ctr += GHASH_CHUNK / 16; CRYPTO_store_u32_be(ctx->Yi + 12, ctr); out += GHASH_CHUNK; in += GHASH_CHUNK; len -= GHASH_CHUNK; } + size_t len_blocks = len & kSizeTWithoutLower4Bits; if (len_blocks != 0) { size_t j = len_blocks / 16; - - GHASH(ctx, in, len_blocks); - (*stream)(in, out, j, key, ctx->Yi); - ctr += (unsigned int)j; + GHASH(key, ctx, in, len_blocks); + (*stream)(in, out, j, &key->aes, ctx->Yi); + ctr += (uint32_t)j; CRYPTO_store_u32_be(ctx->Yi + 12, ctr); out += len_blocks; in += len_blocks; len -= len_blocks; } + if (len) { - (*ctx->gcm_key.block)(ctx->Yi, ctx->EKi, key); + key->block(ctx->Yi, ctx->EKi, &key->aes); ++ctr; CRYPTO_store_u32_be(ctx->Yi + 12, ctr); while (len--) { @@ -584,21 +585,21 @@ return 1; } -int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len) { +int CRYPTO_gcm128_finish(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *tag, size_t len) { #ifdef GCM_FUNCREF - void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = - ctx->gcm_key.gmult; + void (*gcm_gmult_p)(uint8_t Xi[16], const u128 Htable[16]) = key->gmult; #endif if (ctx->mres || ctx->ares) { - GCM_MUL(ctx, Xi); + GCM_MUL(key, ctx, Xi); } uint8_t len_block[16]; CRYPTO_store_u64_be(len_block, ctx->len.aad << 3); CRYPTO_store_u64_be(len_block + 8, ctx->len.msg << 3); CRYPTO_xor16(ctx->Xi, ctx->Xi, len_block); - GCM_MUL(ctx, Xi); + GCM_MUL(key, ctx, Xi); CRYPTO_xor16(ctx->Xi, ctx->Xi, ctx->EK0); if (tag && len <= sizeof(ctx->Xi)) { @@ -608,8 +609,9 @@ } } -void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) { - CRYPTO_gcm128_finish(ctx, NULL, 0); +void CRYPTO_gcm128_tag(const GCM128_KEY *key, GCM128_CONTEXT *ctx, uint8_t *tag, + size_t len) { + CRYPTO_gcm128_finish(key, ctx, NULL, 0); OPENSSL_memcpy(tag, ctx->Xi, len <= sizeof(ctx->Xi) ? len : sizeof(ctx->Xi)); }
diff --git a/crypto/fipsmodule/modes/internal.h b/crypto/fipsmodule/modes/internal.h index 263b314..1878121 100644 --- a/crypto/fipsmodule/modes/internal.h +++ b/crypto/fipsmodule/modes/internal.h
@@ -58,24 +58,13 @@ #include <string.h> #include "../../internal.h" +#include "../aes/internal.h" #if defined(__cplusplus) extern "C" { #endif -// block128_f is the type of an AES block cipher implementation. -// -// Unlike upstream OpenSSL, it and the other functions in this file hard-code -// |AES_KEY|. It is undefined in C to call a function pointer with anything -// other than the original type. Thus we either must match |block128_f| to the -// type signature of |AES_encrypt| and friends or pass in |void*| wrapper -// functions. -// -// These functions are called exclusively with AES, so we use the former. -typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16], - const AES_KEY *key); - OPENSSL_INLINE void CRYPTO_xor16(uint8_t out[16], const uint8_t a[16], const uint8_t b[16]) { // TODO(davidben): Ideally we'd leave this to the compiler, which could use @@ -93,10 +82,6 @@ // CTR. -// ctr128_f is the type of a function that performs CTR-mode encryption. -typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks, - const AES_KEY *key, const uint8_t ivec[16]); - // CRYPTO_ctr128_encrypt_ctr32 encrypts (or decrypts, it's the same in CTR mode) // |len| bytes from |in| to |out| using |block| in counter mode. There's no // requirement that |len| be a multiple of any value and any partial blocks are @@ -148,7 +133,9 @@ u128 Htable[16]; gmult_func gmult; ghash_func ghash; + AES_KEY aes; + ctr128_f ctr; block128_f block; enum gcm_impl_t impl; } GCM128_KEY; @@ -165,11 +152,6 @@ uint64_t msg; } len; uint8_t Xi[16]; - - // |gcm_*_ssse3| require |Htable| to be 16-byte-aligned. - // TODO(crbug.com/boringssl/604): Revisit this. - alignas(16) GCM128_KEY gcm_key; - unsigned mres, ares; } GCM128_CONTEXT; @@ -185,46 +167,44 @@ void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, u128 out_table[16], const uint8_t gcm_key[16]); -// CRYPTO_gcm128_init_key initialises |gcm_key| to use |block| (typically AES) -// with the given key. |block_is_hwaes| is one if |block| is |aes_hw_encrypt|. -void CRYPTO_gcm128_init_key(GCM128_KEY *gcm_key, const AES_KEY *key, - block128_f block, int block_is_hwaes); +// CRYPTO_gcm128_init_aes_key initialises |gcm_key| to with AES key |key|. +void CRYPTO_gcm128_init_aes_key(GCM128_KEY *gcm_key, const uint8_t *key, + size_t key_bytes); -// CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. The |key| must be the -// same key that was passed to |CRYPTO_gcm128_init|. -void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const AES_KEY *key, - const uint8_t *iv, size_t iv_len); +// CRYPTO_gcm128_init_ctx initializes |ctx| to encrypt with |key| and |iv|. +void CRYPTO_gcm128_init_ctx(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *iv, size_t iv_len); -// CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM. -// This must be called before and data is encrypted. It returns one on success +// CRYPTO_gcm128_aad adds to the authenticated data for an instance of GCM. +// This must be called before and data is encrypted. |key| must be the same +// value that was passed to |CRYPTO_gcm128_init_ctx|. It returns one on success // and zero otherwise. -int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len); +int CRYPTO_gcm128_aad(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *aad, size_t aad_len); -// CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using -// a CTR function that only handles the bottom 32 bits of the nonce, like -// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was -// passed to |CRYPTO_gcm128_init|. It returns one on success and zero -// otherwise. -int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, - const uint8_t *in, uint8_t *out, size_t len, - ctr128_f stream); +// CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. |key| must be +// the same value that was passed to |CRYPTO_gcm128_init_ctx|. It returns one on +// success and zero otherwise. +int CRYPTO_gcm128_encrypt(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *in, uint8_t *out, size_t len); -// CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using -// a CTR function that only handles the bottom 32 bits of the nonce, like -// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was -// passed to |CRYPTO_gcm128_init|. It returns one on success and zero -// otherwise. -int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const AES_KEY *key, - const uint8_t *in, uint8_t *out, size_t len, - ctr128_f stream); +// CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. |key| must be +// the same value that was passed to |CRYPTO_gcm128_init_ctx|. It returns one on +// success and zero otherwise. +int CRYPTO_gcm128_decrypt(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *in, uint8_t *out, size_t len); // CRYPTO_gcm128_finish calculates the authenticator and compares it against -// |len| bytes of |tag|. It returns one on success and zero otherwise. -int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len); +// |len| bytes of |tag|. |key| must be the same value that was passed to +// |CRYPTO_gcm128_init_ctx|. It returns one on success and zero otherwise. +int CRYPTO_gcm128_finish(const GCM128_KEY *key, GCM128_CONTEXT *ctx, + const uint8_t *tag, size_t len); // CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|. -// The minimum of |len| and 16 bytes are copied into |tag|. -void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag, size_t len); +// The minimum of |len| and 16 bytes are copied into |tag|. |key| must be the +// same value that was passed to |CRYPTO_gcm128_init_ctx|. +void CRYPTO_gcm128_tag(const GCM128_KEY *key, GCM128_CONTEXT *ctx, uint8_t *tag, + size_t len); // GCM assembly.
diff --git a/crypto/fipsmodule/rand/ctrdrbg.cc.inc b/crypto/fipsmodule/rand/ctrdrbg.cc.inc index c60eb8d..0f10a21 100644 --- a/crypto/fipsmodule/rand/ctrdrbg.cc.inc +++ b/crypto/fipsmodule/rand/ctrdrbg.cc.inc
@@ -18,7 +18,7 @@ #include <openssl/mem.h> -#include "../cipher/internal.h" +#include "../aes/internal.h" #include "../service_indicator/internal.h" #include "internal.h"