e_aesctrhmac.c
Go to the documentation of this file.
1 /* Copyright (c) 2017, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <openssl/aead.h>
16 #include <openssl/cipher.h>
17 #include <openssl/crypto.h>
18 #include <openssl/err.h>
19 #include <openssl/sha.h>
20 
21 #include "../fipsmodule/cipher/internal.h"
22 
23 
24 #define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH
25 #define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12
26 
28  union {
29  double align;
31  } ks;
36 };
37 
38 OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *)NULL)->state) >=
39  sizeof(struct aead_aes_ctr_hmac_sha256_ctx),
40  "AEAD state is too small");
41 #if defined(__GNUC__) || defined(__clang__)
43  alignof(struct aead_aes_ctr_hmac_sha256_ctx),
44  "AEAD state has insufficient alignment");
45 #endif
46 
47 static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer,
48  const uint8_t hmac_key[32]) {
49  static const size_t hmac_key_len = 32;
51  OPENSSL_memcpy(block, hmac_key, hmac_key_len);
52  OPENSSL_memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len);
53 
54  unsigned i;
55  for (i = 0; i < hmac_key_len; i++) {
56  block[i] ^= 0x36;
57  }
58 
59  SHA256_Init(out_inner);
60  SHA256_Update(out_inner, block, sizeof(block));
61 
62  OPENSSL_memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len);
63  for (i = 0; i < hmac_key_len; i++) {
64  block[i] ^= (0x36 ^ 0x5c);
65  }
66 
67  SHA256_Init(out_outer);
68  SHA256_Update(out_outer, block, sizeof(block));
69 }
70 
72  size_t key_len, size_t tag_len) {
73  struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx =
74  (struct aead_aes_ctr_hmac_sha256_ctx *)&ctx->state;
75  static const size_t hmac_key_len = 32;
76 
77  if (key_len < hmac_key_len) {
79  return 0; // EVP_AEAD_CTX_init should catch this.
80  }
81 
82  const size_t aes_key_len = key_len - hmac_key_len;
83  if (aes_key_len != 16 && aes_key_len != 32) {
85  return 0; // EVP_AEAD_CTX_init should catch this.
86  }
87 
88  if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
90  }
91 
94  return 0;
95  }
96 
97  aes_ctx->ctr =
98  aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len);
99  ctx->tag_len = tag_len;
100  hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state,
101  key + aes_key_len);
102 
103  return 1;
104 }
105 
107 
109  unsigned i;
110  uint8_t bytes[8];
111 
112  for (i = 0; i < sizeof(bytes); i++) {
113  bytes[i] = value & 0xff;
114  value >>= 8;
115  }
116  SHA256_Update(sha256, bytes, sizeof(bytes));
117 }
118 
122  const uint8_t *ad, size_t ad_len,
123  const uint8_t *nonce, const uint8_t *ciphertext,
124  size_t ciphertext_len) {
127  hmac_update_uint64(&sha256, ad_len);
128  hmac_update_uint64(&sha256, ciphertext_len);
130  SHA256_Update(&sha256, ad, ad_len);
131 
132  // Pad with zeros to the end of the SHA-256 block.
133  const unsigned num_padding =
134  (SHA256_CBLOCK - ((sizeof(uint64_t)*2 +
136  SHA256_CBLOCK)) %
138  uint8_t padding[SHA256_CBLOCK];
139  OPENSSL_memset(padding, 0, num_padding);
140  SHA256_Update(&sha256, padding, num_padding);
141 
142  SHA256_Update(&sha256, ciphertext, ciphertext_len);
143 
144  uint8_t inner_digest[SHA256_DIGEST_LENGTH];
145  SHA256_Final(inner_digest, &sha256);
146 
148  SHA256_Update(&sha256, inner_digest, sizeof(inner_digest));
150 }
151 
153  const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out,
154  const uint8_t *in, size_t len, const uint8_t *nonce) {
155  // Since the AEAD operation is one-shot, keeping a buffer of unused keystream
156  // bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it.
157  uint8_t partial_block_buffer[AES_BLOCK_SIZE];
158  unsigned partial_block_offset = 0;
159  OPENSSL_memset(partial_block_buffer, 0, sizeof(partial_block_buffer));
160 
164 
165  if (aes_ctx->ctr) {
166  CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter,
167  partial_block_buffer, &partial_block_offset,
168  aes_ctx->ctr);
169  } else {
170  CRYPTO_ctr128_encrypt(in, out, len, &aes_ctx->ks.ks, counter,
171  partial_block_buffer, &partial_block_offset,
172  aes_ctx->block);
173  }
174 }
175 
177  const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag,
178  size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce,
179  size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in,
180  size_t extra_in_len, const uint8_t *ad, size_t ad_len) {
181  const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx =
182  (struct aead_aes_ctr_hmac_sha256_ctx *) &ctx->state;
183  const uint64_t in_len_64 = in_len;
184 
185  if (in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) {
186  // This input is so large it would overflow the 32-bit block counter.
188  return 0;
189  }
190 
191  if (max_out_tag_len < ctx->tag_len) {
193  return 0;
194  }
195 
196  if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
198  return 0;
199  }
200 
201  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce);
202 
203  uint8_t hmac_result[SHA256_DIGEST_LENGTH];
204  hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
205  &aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len);
206  OPENSSL_memcpy(out_tag, hmac_result, ctx->tag_len);
207  *out_tag_len = ctx->tag_len;
208 
209  return 1;
210 }
211 
213  const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce,
214  size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag,
215  size_t in_tag_len, const uint8_t *ad, size_t ad_len) {
216  const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx =
217  (struct aead_aes_ctr_hmac_sha256_ctx *) &ctx->state;
218 
219  if (in_tag_len != ctx->tag_len) {
221  return 0;
222  }
223 
224  if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
226  return 0;
227  }
228 
229  uint8_t hmac_result[SHA256_DIGEST_LENGTH];
230  hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
231  &aes_ctx->outer_init_state, ad, ad_len, nonce, in,
232  in_len);
233  if (CRYPTO_memcmp(hmac_result, in_tag, ctx->tag_len) != 0) {
235  return 0;
236  }
237 
238  aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce);
239 
240  return 1;
241 }
242 
244  16 /* AES key */ + 32 /* HMAC key */,
245  12, // nonce length
247  EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length
248  0, // seal_scatter_supports_extra_in
249 
251  NULL /* init_with_direction */,
253  NULL /* open */,
256  NULL /* get_iv */,
257  NULL /* tag_len */,
258 };
259 
261  32 /* AES key */ + 32 /* HMAC key */,
262  12, // nonce length
264  EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length
265  0, // seal_scatter_supports_extra_in
266 
268  NULL /* init_with_direction */,
270  NULL /* open */,
273  NULL /* get_iv */,
274  NULL /* tag_len */,
275 };
276 
279 }
280 
283 }
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
ctx
Definition: benchmark-async.c:30
hmac_init
static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer, const uint8_t hmac_key[32])
Definition: e_aesctrhmac.c:47
EVP_aead_aes_128_ctr_hmac_sha256
const EVP_AEAD * EVP_aead_aes_128_ctr_hmac_sha256(void)
Definition: e_aesctrhmac.c:277
SHA256_CBLOCK
#define SHA256_CBLOCK
Definition: sha.h:152
aead_aes_ctr_hmac_sha256_ctx::align
double align
Definition: e_aesctrhmac.c:29
OPENSSL_PUT_ERROR
#define OPENSSL_PUT_ERROR(library, reason)
Definition: err.h:423
EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN
#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN
Definition: e_aesctrhmac.c:24
OPENSSL_STATIC_ASSERT
OPENSSL_STATIC_ASSERT(sizeof(((EVP_AEAD_CTX *) NULL) ->state) >=sizeof(struct aead_aes_ctr_hmac_sha256_ctx), "AEAD state is too small")
ciphertext
const char * ciphertext
Definition: protobuf/src/google/protobuf/stubs/strutil_unittest.cc:86
aead_aes_ctr_hmac_sha256_ctx::inner_init_state
SHA256_CTX inner_init_state
Definition: e_aesctrhmac.c:34
CIPHER_R_BAD_KEY_LENGTH
#define CIPHER_R_BAD_KEY_LENGTH
Definition: cipher.h:648
CRYPTO_ctr128_encrypt_ctr32
#define CRYPTO_ctr128_encrypt_ctr32
Definition: boringssl_prefix_symbols.h:1148
uint8_t
unsigned char uint8_t
Definition: stdint-msvc2008.h:78
OPENSSL_memset
static void * OPENSSL_memset(void *dst, int c, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:835
aead_aes_ctr_hmac_sha256_init
static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len)
Definition: e_aesctrhmac.c:71
aead_aes_ctr_hmac_sha256_seal_scatter
static int aead_aes_ctr_hmac_sha256_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, 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)
Definition: e_aesctrhmac.c:176
AES_BLOCK_SIZE
#define AES_BLOCK_SIZE
Definition: aes.h:68
block
Block * block
Definition: protobuf/src/google/protobuf/descriptor.cc:1041
EVP_AEAD_DEFAULT_TAG_LENGTH
#define EVP_AEAD_DEFAULT_TAG_LENGTH
Definition: aead.h:240
in
const char * in
Definition: third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc:391
aead_aes_ctr_hmac_sha256_ctx::ctr
ctr128_f ctr
Definition: e_aesctrhmac.c:32
aead_aes_ctr_hmac_sha256_open_gather
static int aead_aes_ctr_hmac_sha256_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, size_t in_tag_len, const uint8_t *ad, size_t ad_len)
Definition: e_aesctrhmac.c:212
evp_aead_ctx_st_state
Definition: aead.h:210
ctr128_f
void(* ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks, const AES_KEY *key, const uint8_t ivec[16])
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/internal.h:83
CIPHER_R_UNSUPPORTED_NONCE_SIZE
#define CIPHER_R_UNSUPPORTED_NONCE_SIZE
Definition: cipher.h:667
sha.h
evp_aead_ctx_st
Definition: aead.h:217
CIPHER_R_TAG_TOO_LARGE
#define CIPHER_R_TAG_TOO_LARGE
Definition: cipher.h:662
aes_ctr_set_key
#define aes_ctr_set_key
Definition: boringssl_prefix_symbols.h:2807
uint64_t
unsigned __int64 uint64_t
Definition: stdint-msvc2008.h:90
OPENSSL_memcpy
static void * OPENSSL_memcpy(void *dst, const void *src, size_t n)
Definition: third_party/boringssl-with-bazel/src/crypto/internal.h:819
err.h
counter
static int counter
Definition: abseil-cpp/absl/flags/reflection_test.cc:131
crypto.h
cipher.h
sha256
static const MD sha256
Definition: digest_test.cc:53
aead.h
aead_aes_ctr_hmac_sha256_ctx
Definition: e_aesctrhmac.c:27
UINT64_C
#define UINT64_C(val)
Definition: stdint-msvc2008.h:238
CIPHER_R_BUFFER_TOO_SMALL
#define CIPHER_R_BUFFER_TOO_SMALL
Definition: cipher.h:649
hmac_update_uint64
static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value)
Definition: e_aesctrhmac.c:108
aead_aes_ctr_hmac_sha256_ctx::ks
AES_KEY ks
Definition: e_aesctrhmac.c:30
value
const char * value
Definition: hpack_parser_table.cc:165
evp_aead_st
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/cipher/internal.h:77
sha256_state_st
Definition: sha.h:189
hmac_calculate
static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH], const SHA256_CTX *inner_init_state, const SHA256_CTX *outer_init_state, const uint8_t *ad, size_t ad_len, const uint8_t *nonce, const uint8_t *ciphertext, size_t ciphertext_len)
Definition: e_aesctrhmac.c:119
CRYPTO_ctr128_encrypt
#define CRYPTO_ctr128_encrypt
Definition: boringssl_prefix_symbols.h:1147
key
const char * key
Definition: hpack_parser_table.cc:164
bytes
uint8 bytes[10]
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/coded_stream_unittest.cc:153
aead_aes_ctr_hmac_sha256_ctx::outer_init_state
SHA256_CTX outer_init_state
Definition: e_aesctrhmac.c:35
aead_aes_ctr_hmac_sha256_crypt
static void aead_aes_ctr_hmac_sha256_crypt(const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out, const uint8_t *in, size_t len, const uint8_t *nonce)
Definition: e_aesctrhmac.c:152
SHA256_Init
#define SHA256_Init
Definition: boringssl_prefix_symbols.h:2156
SHA256_DIGEST_LENGTH
#define SHA256_DIGEST_LENGTH
Definition: sha.h:155
state
Definition: bloaty/third_party/zlib/contrib/blast/blast.c:41
CIPHER_R_TOO_LARGE
#define CIPHER_R_TOO_LARGE
Definition: cipher.h:663
aead_aes_128_ctr_hmac_sha256
static const EVP_AEAD aead_aes_128_ctr_hmac_sha256
Definition: e_aesctrhmac.c:243
aead_aes_ctr_hmac_sha256_ctx::block
block128_f block
Definition: e_aesctrhmac.c:33
EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN
#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN
Definition: e_aesctrhmac.c:25
EVP_aead_aes_256_ctr_hmac_sha256
const EVP_AEAD * EVP_aead_aes_256_ctr_hmac_sha256(void)
Definition: e_aesctrhmac.c:281
len
int len
Definition: abseil-cpp/absl/base/internal/low_level_alloc_test.cc:46
aead_aes_256_ctr_hmac_sha256
static const EVP_AEAD aead_aes_256_ctr_hmac_sha256
Definition: e_aesctrhmac.c:260
SHA256_Final
#define SHA256_Final
Definition: boringssl_prefix_symbols.h:2155
aes_key_st
Definition: aes.h:72
if
if(p->owned &&p->wrapped !=NULL)
Definition: call.c:42
CRYPTO_memcmp
#define CRYPTO_memcmp
Definition: boringssl_prefix_symbols.h:1178
aead_aes_ctr_hmac_sha256_cleanup
static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx)
Definition: e_aesctrhmac.c:106
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
block128_f
void(* block128_f)(const uint8_t in[16], uint8_t out[16], const AES_KEY *key)
Definition: third_party/boringssl-with-bazel/src/crypto/fipsmodule/modes/internal.h:76
CIPHER_R_BAD_DECRYPT
#define CIPHER_R_BAD_DECRYPT
Definition: cipher.h:647
SHA256_Update
#define SHA256_Update
Definition: boringssl_prefix_symbols.h:2159


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:18