blob: 5556ff35eb44bba927965e8970d18878f365dd52 [file] [log] [blame]
Adam Langleyd9e397b2015-01-22 14:27:53 -08001/* ====================================================================
2 * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in
13 * the documentation and/or other materials provided with the
14 * distribution.
15 *
16 * 3. All advertising materials mentioning features or use of this
17 * software must display the following acknowledgment:
18 * "This product includes software developed by the OpenSSL Project
19 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
20 *
21 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For written permission, please contact
24 * openssl-core@openssl.org.
25 *
26 * 5. Products derived from this software may not be called "OpenSSL"
27 * nor may "OpenSSL" appear in their names without prior written
28 * permission of the OpenSSL Project.
29 *
30 * 6. Redistributions of any form whatsoever must retain the following
31 * acknowledgment:
32 * "This product includes software developed by the OpenSSL Project
33 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
34 *
35 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
36 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
37 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
38 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
41 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
42 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
43 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
44 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
45 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
46 * OF THE POSSIBILITY OF SUCH DAMAGE.
47 * ==================================================================== */
48
49#include <string.h>
50
51#include <openssl/aead.h>
52#include <openssl/aes.h>
53#include <openssl/cipher.h>
54#include <openssl/cpu.h>
55#include <openssl/err.h>
56#include <openssl/mem.h>
David Benjamin4969cc92016-04-22 15:02:23 -040057#include <openssl/nid.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080058#include <openssl/rand.h>
59
60#include "internal.h"
Robert Sloan8ff03552017-06-14 12:40:58 -070061#include "../../internal.h"
62#include "../aes/internal.h"
63#include "../modes/internal.h"
64#include "../delocate.h"
Adam Langleyd9e397b2015-01-22 14:27:53 -080065
66#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
Kenny Rootb8494592015-09-25 02:29:14 +000067#include <openssl/arm_arch.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080068#endif
69
70
David Benjamin6e899c72016-06-09 18:02:18 -040071OPENSSL_MSVC_PRAGMA(warning(disable: 4702)) /* Unreachable code. */
David Benjamin4969cc92016-04-22 15:02:23 -040072
Adam Langleyd9e397b2015-01-22 14:27:53 -080073typedef struct {
74 union {
75 double align;
76 AES_KEY ks;
77 } ks;
78 block128_f block;
79 union {
80 cbc128_f cbc;
81 ctr128_f ctr;
82 } stream;
83} EVP_AES_KEY;
84
85typedef struct {
86 union {
87 double align;
88 AES_KEY ks;
89 } ks; /* AES key schedule to use */
90 int key_set; /* Set if key initialised */
91 int iv_set; /* Set if an iv is set */
92 GCM128_CONTEXT gcm;
93 uint8_t *iv; /* Temporary IV store */
94 int ivlen; /* IV length */
95 int taglen;
96 int iv_gen; /* It is OK to generate IVs */
97 ctr128_f ctr;
98} EVP_AES_GCM_CTX;
99
100#if !defined(OPENSSL_NO_ASM) && \
101 (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
102#define VPAES
Adam Langleyd9e397b2015-01-22 14:27:53 -0800103static char vpaes_capable(void) {
104 return (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) != 0;
105}
106
107#if defined(OPENSSL_X86_64)
108#define BSAES
109static char bsaes_capable(void) {
110 return vpaes_capable();
111}
112#endif
113
114#elif !defined(OPENSSL_NO_ASM) && \
115 (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800116
Adam Langleyf4e42722015-06-04 17:45:09 -0700117#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
Adam Langleyd9e397b2015-01-22 14:27:53 -0800118#define BSAES
119static char bsaes_capable(void) {
120 return CRYPTO_is_NEON_capable();
121}
122#endif
123
Robert Sloan8ff03552017-06-14 12:40:58 -0700124#endif
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400125
Adam Langleyd9e397b2015-01-22 14:27:53 -0800126
127#if defined(BSAES)
128/* On platforms where BSAES gets defined (just above), then these functions are
129 * provided by asm. */
130void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
131 const AES_KEY *key, uint8_t ivec[16], int enc);
132void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
133 const AES_KEY *key, const uint8_t ivec[16]);
134#else
135static char bsaes_capable(void) {
136 return 0;
137}
138
139/* On other platforms, bsaes_capable() will always return false and so the
140 * following will never be called. */
Kenny Roote99801b2015-11-06 15:31:15 -0800141static void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
142 const AES_KEY *key, uint8_t ivec[16], int enc) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800143 abort();
144}
145
Kenny Roote99801b2015-11-06 15:31:15 -0800146static void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
147 size_t len, const AES_KEY *key,
148 const uint8_t ivec[16]) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800149 abort();
150}
151#endif
152
153#if defined(VPAES)
154/* On platforms where VPAES gets defined (just above), then these functions are
155 * provided by asm. */
156int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
157int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
158
159void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
160void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
161
162void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
163 const AES_KEY *key, uint8_t *ivec, int enc);
164#else
165static char vpaes_capable(void) {
166 return 0;
167}
168
169/* On other platforms, vpaes_capable() will always return false and so the
170 * following will never be called. */
Kenny Roote99801b2015-11-06 15:31:15 -0800171static int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
172 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800173 abort();
174}
Kenny Roote99801b2015-11-06 15:31:15 -0800175static int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
176 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800177 abort();
178}
Kenny Roote99801b2015-11-06 15:31:15 -0800179static void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800180 abort();
181}
Kenny Roote99801b2015-11-06 15:31:15 -0800182static void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800183 abort();
184}
Kenny Roote99801b2015-11-06 15:31:15 -0800185static void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
186 const AES_KEY *key, uint8_t *ivec, int enc) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800187 abort();
188}
189#endif
190
Adam Langleyd9e397b2015-01-22 14:27:53 -0800191#if !defined(OPENSSL_NO_ASM) && \
192 (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
193int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
194int aesni_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
195
196void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
197void aesni_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
198
199void aesni_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
200 const AES_KEY *key, int enc);
201void aesni_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
202 const AES_KEY *key, uint8_t *ivec, int enc);
203
Adam Langleyd9e397b2015-01-22 14:27:53 -0800204#else
205
206/* On other platforms, aesni_capable() will always return false and so the
207 * following will never be called. */
Kenny Roote99801b2015-11-06 15:31:15 -0800208static void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800209 abort();
210}
Kenny Roote99801b2015-11-06 15:31:15 -0800211static int aesni_set_encrypt_key(const uint8_t *userKey, int bits,
212 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800213 abort();
214}
Kenny Roote99801b2015-11-06 15:31:15 -0800215static void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
216 size_t blocks, const void *key,
217 const uint8_t *ivec) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800218 abort();
219}
220
221#endif
222
223static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
David Benjamin4969cc92016-04-22 15:02:23 -0400224 const uint8_t *iv, int enc) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800225 int ret, mode;
226 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
227
228 mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK;
229 if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) {
230 if (hwaes_capable()) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400231 ret = aes_hw_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
232 dat->block = (block128_f)aes_hw_decrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800233 dat->stream.cbc = NULL;
234 if (mode == EVP_CIPH_CBC_MODE) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400235 dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800236 }
237 } else if (bsaes_capable() && mode == EVP_CIPH_CBC_MODE) {
238 ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
239 dat->block = (block128_f)AES_decrypt;
240 dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
241 } else if (vpaes_capable()) {
242 ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
243 dat->block = (block128_f)vpaes_decrypt;
244 dat->stream.cbc =
245 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)vpaes_cbc_encrypt : NULL;
246 } else {
247 ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
248 dat->block = (block128_f)AES_decrypt;
249 dat->stream.cbc =
250 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)AES_cbc_encrypt : NULL;
251 }
252 } else if (hwaes_capable()) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400253 ret = aes_hw_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
254 dat->block = (block128_f)aes_hw_encrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800255 dat->stream.cbc = NULL;
256 if (mode == EVP_CIPH_CBC_MODE) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400257 dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800258 } else if (mode == EVP_CIPH_CTR_MODE) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400259 dat->stream.ctr = (ctr128_f)aes_hw_ctr32_encrypt_blocks;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800260 }
261 } else if (bsaes_capable() && mode == EVP_CIPH_CTR_MODE) {
262 ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
263 dat->block = (block128_f)AES_encrypt;
264 dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
265 } else if (vpaes_capable()) {
266 ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
267 dat->block = (block128_f)vpaes_encrypt;
268 dat->stream.cbc =
269 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)vpaes_cbc_encrypt : NULL;
270 } else {
271 ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
272 dat->block = (block128_f)AES_encrypt;
273 dat->stream.cbc =
274 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)AES_cbc_encrypt : NULL;
275 }
276
277 if (ret < 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000278 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800279 return 0;
280 }
281
282 return 1;
283}
284
Adam Langleye9ada862015-05-11 17:20:37 -0700285static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
286 size_t len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800287 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
288
289 if (dat->stream.cbc) {
290 (*dat->stream.cbc)(in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
291 } else if (ctx->encrypt) {
292 CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
293 } else {
294 CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
295 }
296
297 return 1;
298}
299
Adam Langleye9ada862015-05-11 17:20:37 -0700300static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
301 size_t len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800302 size_t bl = ctx->cipher->block_size;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800303 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
304
305 if (len < bl) {
306 return 1;
307 }
308
David Benjamin7c0d06c2016-08-11 13:26:41 -0400309 len -= bl;
310 for (size_t i = 0; i <= len; i += bl) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800311 (*dat->block)(in + i, out + i, &dat->ks);
312 }
313
314 return 1;
315}
316
Adam Langleye9ada862015-05-11 17:20:37 -0700317static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
318 size_t len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800319 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
320
321 if (dat->stream.ctr) {
David Benjamin4969cc92016-04-22 15:02:23 -0400322 CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf,
323 &ctx->num, dat->stream.ctr);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800324 } else {
David Benjamin4969cc92016-04-22 15:02:23 -0400325 CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &ctx->num,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800326 dat->block);
327 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800328 return 1;
329}
330
Adam Langleye9ada862015-05-11 17:20:37 -0700331static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
332 size_t len) {
333 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
334
335 CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num, dat->block);
336 return 1;
337}
338
339static char aesni_capable(void);
340
Robert Sloan572a4e22017-04-17 10:52:19 -0700341ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
342 block128_f *out_block, const uint8_t *key,
343 size_t key_bytes) {
Adam Langleye9ada862015-05-11 17:20:37 -0700344 if (aesni_capable()) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700345 aesni_set_encrypt_key(key, key_bytes * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700346 if (gcm_ctx != NULL) {
Robert Sloan9254e682017-04-24 09:42:06 -0700347 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aesni_encrypt, 1);
Adam Langleye9ada862015-05-11 17:20:37 -0700348 }
349 if (out_block) {
350 *out_block = (block128_f) aesni_encrypt;
351 }
352 return (ctr128_f)aesni_ctr32_encrypt_blocks;
353 }
354
Adam Langleyd9e397b2015-01-22 14:27:53 -0800355 if (hwaes_capable()) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700356 aes_hw_set_encrypt_key(key, key_bytes * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700357 if (gcm_ctx != NULL) {
Robert Sloan9254e682017-04-24 09:42:06 -0700358 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aes_hw_encrypt, 0);
Adam Langleye9ada862015-05-11 17:20:37 -0700359 }
360 if (out_block) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400361 *out_block = (block128_f) aes_hw_encrypt;
Adam Langleye9ada862015-05-11 17:20:37 -0700362 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400363 return (ctr128_f)aes_hw_ctr32_encrypt_blocks;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800364 }
365
366 if (bsaes_capable()) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700367 AES_set_encrypt_key(key, key_bytes * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700368 if (gcm_ctx != NULL) {
Robert Sloan9254e682017-04-24 09:42:06 -0700369 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt, 0);
Adam Langleye9ada862015-05-11 17:20:37 -0700370 }
371 if (out_block) {
372 *out_block = (block128_f) AES_encrypt;
373 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800374 return (ctr128_f)bsaes_ctr32_encrypt_blocks;
375 }
376
377 if (vpaes_capable()) {
Robert Sloan572a4e22017-04-17 10:52:19 -0700378 vpaes_set_encrypt_key(key, key_bytes * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700379 if (out_block) {
380 *out_block = (block128_f) vpaes_encrypt;
381 }
382 if (gcm_ctx != NULL) {
Robert Sloan9254e682017-04-24 09:42:06 -0700383 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt, 0);
Adam Langleye9ada862015-05-11 17:20:37 -0700384 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800385 return NULL;
386 }
387
Robert Sloan572a4e22017-04-17 10:52:19 -0700388 AES_set_encrypt_key(key, key_bytes * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700389 if (gcm_ctx != NULL) {
Robert Sloan9254e682017-04-24 09:42:06 -0700390 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt, 0);
Adam Langleye9ada862015-05-11 17:20:37 -0700391 }
392 if (out_block) {
393 *out_block = (block128_f) AES_encrypt;
394 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800395 return NULL;
396}
397
398static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
399 const uint8_t *iv, int enc) {
400 EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
401 if (!iv && !key) {
402 return 1;
403 }
404 if (key) {
Adam Langleye9ada862015-05-11 17:20:37 -0700405 gctx->ctr =
406 aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm, NULL, key, ctx->key_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800407 /* If we have an iv can set it directly, otherwise use saved IV. */
408 if (iv == NULL && gctx->iv_set) {
409 iv = gctx->iv;
410 }
411 if (iv) {
Kenny Roote99801b2015-11-06 15:31:15 -0800412 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800413 gctx->iv_set = 1;
414 }
415 gctx->key_set = 1;
416 } else {
417 /* If key set use IV, otherwise copy */
418 if (gctx->key_set) {
Kenny Roote99801b2015-11-06 15:31:15 -0800419 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800420 } else {
Robert Sloan69939df2017-01-09 10:53:07 -0800421 OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800422 }
423 gctx->iv_set = 1;
424 gctx->iv_gen = 0;
425 }
426 return 1;
427}
428
Adam Langleye9ada862015-05-11 17:20:37 -0700429static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800430 EVP_AES_GCM_CTX *gctx = c->cipher_data;
431 OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
432 if (gctx->iv != c->iv) {
433 OPENSSL_free(gctx->iv);
434 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800435}
436
437/* increment counter (64-bit int) by 1 */
438static void ctr64_inc(uint8_t *counter) {
439 int n = 8;
440 uint8_t c;
441
442 do {
443 --n;
444 c = counter[n];
445 ++c;
446 counter[n] = c;
447 if (c) {
448 return;
449 }
450 } while (n);
451}
452
453static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
454 EVP_AES_GCM_CTX *gctx = c->cipher_data;
455 switch (type) {
456 case EVP_CTRL_INIT:
457 gctx->key_set = 0;
458 gctx->iv_set = 0;
459 gctx->ivlen = c->cipher->iv_len;
460 gctx->iv = c->iv;
461 gctx->taglen = -1;
462 gctx->iv_gen = 0;
463 return 1;
464
465 case EVP_CTRL_GCM_SET_IVLEN:
466 if (arg <= 0) {
467 return 0;
468 }
469
470 /* Allocate memory for IV if needed */
471 if (arg > EVP_MAX_IV_LENGTH && arg > gctx->ivlen) {
472 if (gctx->iv != c->iv) {
473 OPENSSL_free(gctx->iv);
474 }
475 gctx->iv = OPENSSL_malloc(arg);
476 if (!gctx->iv) {
477 return 0;
478 }
479 }
480 gctx->ivlen = arg;
481 return 1;
482
483 case EVP_CTRL_GCM_SET_TAG:
484 if (arg <= 0 || arg > 16 || c->encrypt) {
485 return 0;
486 }
Robert Sloan69939df2017-01-09 10:53:07 -0800487 OPENSSL_memcpy(c->buf, ptr, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800488 gctx->taglen = arg;
489 return 1;
490
491 case EVP_CTRL_GCM_GET_TAG:
492 if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) {
493 return 0;
494 }
Robert Sloan69939df2017-01-09 10:53:07 -0800495 OPENSSL_memcpy(ptr, c->buf, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800496 return 1;
497
498 case EVP_CTRL_GCM_SET_IV_FIXED:
499 /* Special case: -1 length restores whole IV */
500 if (arg == -1) {
Robert Sloan69939df2017-01-09 10:53:07 -0800501 OPENSSL_memcpy(gctx->iv, ptr, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800502 gctx->iv_gen = 1;
503 return 1;
504 }
505 /* Fixed field must be at least 4 bytes and invocation field
506 * at least 8. */
507 if (arg < 4 || (gctx->ivlen - arg) < 8) {
508 return 0;
509 }
510 if (arg) {
Robert Sloan69939df2017-01-09 10:53:07 -0800511 OPENSSL_memcpy(gctx->iv, ptr, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800512 }
513 if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) {
514 return 0;
515 }
516 gctx->iv_gen = 1;
517 return 1;
518
519 case EVP_CTRL_GCM_IV_GEN:
520 if (gctx->iv_gen == 0 || gctx->key_set == 0) {
521 return 0;
522 }
Kenny Roote99801b2015-11-06 15:31:15 -0800523 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800524 if (arg <= 0 || arg > gctx->ivlen) {
525 arg = gctx->ivlen;
526 }
Robert Sloan69939df2017-01-09 10:53:07 -0800527 OPENSSL_memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800528 /* Invocation field will be at least 8 bytes in size and
529 * so no need to check wrap around or increment more than
530 * last 8 bytes. */
531 ctr64_inc(gctx->iv + gctx->ivlen - 8);
532 gctx->iv_set = 1;
533 return 1;
534
535 case EVP_CTRL_GCM_SET_IV_INV:
536 if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) {
537 return 0;
538 }
Robert Sloan69939df2017-01-09 10:53:07 -0800539 OPENSSL_memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
Kenny Roote99801b2015-11-06 15:31:15 -0800540 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800541 gctx->iv_set = 1;
542 return 1;
543
544 case EVP_CTRL_COPY: {
545 EVP_CIPHER_CTX *out = ptr;
546 EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800547 if (gctx->iv == c->iv) {
548 gctx_out->iv = out->iv;
549 } else {
550 gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
551 if (!gctx_out->iv) {
552 return 0;
553 }
Robert Sloan69939df2017-01-09 10:53:07 -0800554 OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800555 }
556 return 1;
557 }
558
559 default:
560 return -1;
561 }
562}
563
564static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
565 size_t len) {
566 EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
567
568 /* If not set up, return error */
569 if (!gctx->key_set) {
570 return -1;
571 }
572 if (!gctx->iv_set) {
573 return -1;
574 }
575
576 if (in) {
577 if (out == NULL) {
578 if (!CRYPTO_gcm128_aad(&gctx->gcm, in, len)) {
579 return -1;
580 }
581 } else if (ctx->encrypt) {
582 if (gctx->ctr) {
David Benjamin4969cc92016-04-22 15:02:23 -0400583 if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
584 gctx->ctr)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800585 return -1;
586 }
587 } else {
David Benjamin4969cc92016-04-22 15:02:23 -0400588 if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800589 return -1;
590 }
591 }
592 } else {
593 if (gctx->ctr) {
David Benjamin4969cc92016-04-22 15:02:23 -0400594 if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
595 gctx->ctr)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800596 return -1;
597 }
598 } else {
David Benjamin4969cc92016-04-22 15:02:23 -0400599 if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800600 return -1;
601 }
602 }
603 }
604 return len;
605 } else {
606 if (!ctx->encrypt) {
607 if (gctx->taglen < 0 ||
Kenny Rootb8494592015-09-25 02:29:14 +0000608 !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800609 return -1;
610 }
611 gctx->iv_set = 0;
612 return 0;
613 }
614 CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
615 gctx->taglen = 16;
616 /* Don't reuse the IV */
617 gctx->iv_set = 0;
618 return 0;
619 }
620}
621
Robert Sloan8ff03552017-06-14 12:40:58 -0700622DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_cbc_generic) {
623 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800624
Robert Sloan8ff03552017-06-14 12:40:58 -0700625 out->nid = NID_aes_128_cbc;
626 out->block_size = 16;
627 out->key_len = 16;
628 out->iv_len = 16;
629 out->ctx_size = sizeof(EVP_AES_KEY);
630 out->flags = EVP_CIPH_CBC_MODE;
631 out->init = aes_init_key;
632 out->cipher = aes_cbc_cipher;
633}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800634
Robert Sloan8ff03552017-06-14 12:40:58 -0700635DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ctr_generic) {
636 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800637
Robert Sloan8ff03552017-06-14 12:40:58 -0700638 out->nid = NID_aes_128_ctr;
639 out->block_size = 1;
640 out->key_len = 16;
641 out->iv_len = 16;
642 out->ctx_size = sizeof(EVP_AES_KEY);
643 out->flags = EVP_CIPH_CTR_MODE;
644 out->init = aes_init_key;
645 out->cipher = aes_ctr_cipher;
646}
Adam Langleye9ada862015-05-11 17:20:37 -0700647
Robert Sloan8ff03552017-06-14 12:40:58 -0700648DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ecb_generic) {
649 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800650
Robert Sloan8ff03552017-06-14 12:40:58 -0700651 out->nid = NID_aes_128_ecb;
652 out->block_size = 16;
653 out->key_len = 16;
654 out->ctx_size = sizeof(EVP_AES_KEY);
655 out->flags = EVP_CIPH_ECB_MODE;
656 out->init = aes_init_key;
657 out->cipher = aes_ecb_cipher;
658}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800659
Robert Sloan8ff03552017-06-14 12:40:58 -0700660DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ofb_generic) {
661 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langley13d393e2015-04-08 11:18:53 -0700662
Robert Sloan8ff03552017-06-14 12:40:58 -0700663 out->nid = NID_aes_128_ofb128;
664 out->block_size = 1;
665 out->key_len = 16;
666 out->iv_len = 16;
667 out->ctx_size = sizeof(EVP_AES_KEY);
668 out->flags = EVP_CIPH_OFB_MODE;
669 out->init = aes_init_key;
670 out->cipher = aes_ofb_cipher;
671}
Adam Langley13d393e2015-04-08 11:18:53 -0700672
Robert Sloan8ff03552017-06-14 12:40:58 -0700673DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_gcm_generic) {
674 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langley13d393e2015-04-08 11:18:53 -0700675
Robert Sloan8ff03552017-06-14 12:40:58 -0700676 out->nid = NID_aes_128_gcm;
677 out->block_size = 1;
678 out->key_len = 16;
679 out->iv_len = 12;
680 out->ctx_size = sizeof(EVP_AES_GCM_CTX);
681 out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
682 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
683 EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
684 out->init = aes_gcm_init_key;
685 out->cipher = aes_gcm_cipher;
686 out->cleanup = aes_gcm_cleanup;
687 out->ctrl = aes_gcm_ctrl;
688}
Adam Langley13d393e2015-04-08 11:18:53 -0700689
Robert Sloan8ff03552017-06-14 12:40:58 -0700690DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_cbc_generic) {
691 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langley13d393e2015-04-08 11:18:53 -0700692
Robert Sloan8ff03552017-06-14 12:40:58 -0700693 out->nid = NID_aes_192_cbc;
694 out->block_size = 16;
695 out->key_len = 24;
696 out->iv_len = 16;
697 out->ctx_size = sizeof(EVP_AES_KEY);
698 out->flags = EVP_CIPH_CBC_MODE;
699 out->init = aes_init_key;
700 out->cipher = aes_cbc_cipher;
701}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800702
Robert Sloan8ff03552017-06-14 12:40:58 -0700703DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ctr_generic) {
704 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800705
Robert Sloan8ff03552017-06-14 12:40:58 -0700706 out->nid = NID_aes_192_ctr;
707 out->block_size = 1;
708 out->key_len = 24;
709 out->iv_len = 16;
710 out->ctx_size = sizeof(EVP_AES_KEY);
711 out->flags = EVP_CIPH_CTR_MODE;
712 out->init = aes_init_key;
713 out->cipher = aes_ctr_cipher;
714}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800715
Robert Sloan8ff03552017-06-14 12:40:58 -0700716DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) {
717 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleye9ada862015-05-11 17:20:37 -0700718
Robert Sloan8ff03552017-06-14 12:40:58 -0700719 out->nid = NID_aes_192_ecb;
720 out->block_size = 16;
721 out->key_len = 24;
722 out->ctx_size = sizeof(EVP_AES_KEY);
723 out->flags = EVP_CIPH_ECB_MODE;
724 out->init = aes_init_key;
725 out->cipher = aes_ecb_cipher;
726}
727
728DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_gcm_generic) {
729 memset(out, 0, sizeof(EVP_CIPHER));
730
731 out->nid = NID_aes_192_gcm;
732 out->block_size = 1;
733 out->key_len = 24;
734 out->iv_len = 12;
735 out->ctx_size = sizeof(EVP_AES_GCM_CTX);
736 out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
737 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
738 EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
739 out->init = aes_gcm_init_key;
740 out->cipher = aes_gcm_cipher;
741 out->cleanup = aes_gcm_cleanup;
742 out->ctrl = aes_gcm_ctrl;
743}
744
745DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_cbc_generic) {
746 memset(out, 0, sizeof(EVP_CIPHER));
747
748 out->nid = NID_aes_256_cbc;
749 out->block_size = 16;
750 out->key_len = 32;
751 out->iv_len = 16;
752 out->ctx_size = sizeof(EVP_AES_KEY);
753 out->flags = EVP_CIPH_CBC_MODE;
754 out->init = aes_init_key;
755 out->cipher = aes_cbc_cipher;
756}
757
758DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ctr_generic) {
759 memset(out, 0, sizeof(EVP_CIPHER));
760
761 out->nid = NID_aes_256_ctr;
762 out->block_size = 1;
763 out->key_len = 32;
764 out->iv_len = 16;
765 out->ctx_size = sizeof(EVP_AES_KEY);
766 out->flags = EVP_CIPH_CTR_MODE;
767 out->init = aes_init_key;
768 out->cipher = aes_ctr_cipher;
769}
770
771DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ecb_generic) {
772 memset(out, 0, sizeof(EVP_CIPHER));
773
774 out->nid = NID_aes_256_ecb;
775 out->block_size = 16;
776 out->key_len = 32;
777 out->ctx_size = sizeof(EVP_AES_KEY);
778 out->flags = EVP_CIPH_ECB_MODE;
779 out->init = aes_init_key;
780 out->cipher = aes_ecb_cipher;
781}
782
783DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ofb_generic) {
784 memset(out, 0, sizeof(EVP_CIPHER));
785
786 out->nid = NID_aes_256_ofb128;
787 out->block_size = 1;
788 out->key_len = 32;
789 out->iv_len = 16;
790 out->ctx_size = sizeof(EVP_AES_KEY);
791 out->flags = EVP_CIPH_OFB_MODE;
792 out->init = aes_init_key;
793 out->cipher = aes_ofb_cipher;
794}
795
796DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_gcm_generic) {
797 memset(out, 0, sizeof(EVP_CIPHER));
798
799 out->nid = NID_aes_256_gcm;
800 out->block_size = 1;
801 out->key_len = 32;
802 out->iv_len = 12;
803 out->ctx_size = sizeof(EVP_AES_GCM_CTX);
804 out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
805 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
806 EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
807 out->init = aes_gcm_init_key;
808 out->cipher = aes_gcm_cipher;
809 out->cleanup = aes_gcm_cleanup;
810 out->ctrl = aes_gcm_ctrl;
811}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800812
813#if !defined(OPENSSL_NO_ASM) && \
814 (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
815
816/* AES-NI section. */
817
818static char aesni_capable(void) {
819 return (OPENSSL_ia32cap_P[1] & (1 << (57 - 32))) != 0;
820}
821
822static int aesni_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
823 const uint8_t *iv, int enc) {
824 int ret, mode;
825 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
826
827 mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK;
828 if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) {
829 ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
830 dat->block = (block128_f)aesni_decrypt;
831 dat->stream.cbc =
832 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)aesni_cbc_encrypt : NULL;
833 } else {
834 ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
835 dat->block = (block128_f)aesni_encrypt;
836 if (mode == EVP_CIPH_CBC_MODE) {
837 dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt;
838 } else if (mode == EVP_CIPH_CTR_MODE) {
839 dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
840 } else {
841 dat->stream.cbc = NULL;
842 }
843 }
844
845 if (ret < 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000846 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800847 return 0;
848 }
849
850 return 1;
851}
852
853static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
854 const uint8_t *in, size_t len) {
855 aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt);
856
857 return 1;
858}
859
860static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
861 const uint8_t *in, size_t len) {
862 size_t bl = ctx->cipher->block_size;
863
864 if (len < bl) {
865 return 1;
866 }
867
868 aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt);
869
870 return 1;
871}
872
873static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
874 const uint8_t *iv, int enc) {
875 EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
876 if (!iv && !key) {
877 return 1;
878 }
879 if (key) {
880 aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
Robert Sloan9254e682017-04-24 09:42:06 -0700881 CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)aesni_encrypt, 1);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800882 gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
883 /* If we have an iv can set it directly, otherwise use
884 * saved IV. */
885 if (iv == NULL && gctx->iv_set) {
886 iv = gctx->iv;
887 }
888 if (iv) {
Kenny Roote99801b2015-11-06 15:31:15 -0800889 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800890 gctx->iv_set = 1;
891 }
892 gctx->key_set = 1;
893 } else {
894 /* If key set use IV, otherwise copy */
895 if (gctx->key_set) {
Kenny Roote99801b2015-11-06 15:31:15 -0800896 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800897 } else {
Robert Sloan69939df2017-01-09 10:53:07 -0800898 OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800899 }
900 gctx->iv_set = 1;
901 gctx->iv_gen = 0;
902 }
903 return 1;
904}
905
Robert Sloan8ff03552017-06-14 12:40:58 -0700906DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_cbc) {
907 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800908
Robert Sloan8ff03552017-06-14 12:40:58 -0700909 out->nid = NID_aes_128_cbc;
910 out->block_size = 16;
911 out->key_len = 16;
912 out->iv_len = 16;
913 out->ctx_size = sizeof(EVP_AES_KEY);
914 out->flags = EVP_CIPH_CBC_MODE;
915 out->init = aesni_init_key;
916 out->cipher = aesni_cbc_cipher;
917}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800918
Robert Sloan8ff03552017-06-14 12:40:58 -0700919DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ctr) {
920 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800921
Robert Sloan8ff03552017-06-14 12:40:58 -0700922 out->nid = NID_aes_128_ctr;
923 out->block_size = 1;
924 out->key_len = 16;
925 out->iv_len = 16;
926 out->ctx_size = sizeof(EVP_AES_KEY);
927 out->flags = EVP_CIPH_CTR_MODE;
928 out->init = aesni_init_key;
929 out->cipher = aes_ctr_cipher;
930}
Adam Langleye9ada862015-05-11 17:20:37 -0700931
Robert Sloan8ff03552017-06-14 12:40:58 -0700932DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ecb) {
933 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800934
Robert Sloan8ff03552017-06-14 12:40:58 -0700935 out->nid = NID_aes_128_ecb;
936 out->block_size = 16;
937 out->key_len = 16;
938 out->ctx_size = sizeof(EVP_AES_KEY);
939 out->flags = EVP_CIPH_ECB_MODE;
940 out->init = aesni_init_key;
941 out->cipher = aesni_ecb_cipher;
942}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800943
Robert Sloan8ff03552017-06-14 12:40:58 -0700944DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ofb) {
945 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langley13d393e2015-04-08 11:18:53 -0700946
Robert Sloan8ff03552017-06-14 12:40:58 -0700947 out->nid = NID_aes_128_ofb128;
948 out->block_size = 1;
949 out->key_len = 16;
950 out->iv_len = 16;
951 out->ctx_size = sizeof(EVP_AES_KEY);
952 out->flags = EVP_CIPH_OFB_MODE;
953 out->init = aesni_init_key;
954 out->cipher = aes_ofb_cipher;
955}
Adam Langley13d393e2015-04-08 11:18:53 -0700956
Robert Sloan8ff03552017-06-14 12:40:58 -0700957DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_gcm) {
958 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langley13d393e2015-04-08 11:18:53 -0700959
Robert Sloan8ff03552017-06-14 12:40:58 -0700960 out->nid = NID_aes_128_gcm;
961 out->block_size = 1;
962 out->key_len = 16;
963 out->iv_len = 12;
964 out->ctx_size = sizeof(EVP_AES_GCM_CTX);
965 out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
966 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
967 EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
968 out->init = aesni_gcm_init_key;
969 out->cipher = aes_gcm_cipher;
970 out->cleanup = aes_gcm_cleanup;
971 out->ctrl = aes_gcm_ctrl;
972}
Adam Langley13d393e2015-04-08 11:18:53 -0700973
Robert Sloan8ff03552017-06-14 12:40:58 -0700974DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_cbc) {
975 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langley13d393e2015-04-08 11:18:53 -0700976
Robert Sloan8ff03552017-06-14 12:40:58 -0700977 out->nid = NID_aes_192_cbc;
978 out->block_size = 16;
979 out->key_len = 24;
980 out->iv_len = 16;
981 out->ctx_size = sizeof(EVP_AES_KEY);
982 out->flags = EVP_CIPH_CBC_MODE;
983 out->init = aesni_init_key;
984 out->cipher = aesni_cbc_cipher;
985}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800986
Robert Sloan8ff03552017-06-14 12:40:58 -0700987DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ctr) {
988 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleyd9e397b2015-01-22 14:27:53 -0800989
Robert Sloan8ff03552017-06-14 12:40:58 -0700990 out->nid = NID_aes_192_ctr;
991 out->block_size = 1;
992 out->key_len = 24;
993 out->iv_len = 16;
994 out->ctx_size = sizeof(EVP_AES_KEY);
995 out->flags = EVP_CIPH_CTR_MODE;
996 out->init = aesni_init_key;
997 out->cipher = aes_ctr_cipher;
998}
Adam Langleyd9e397b2015-01-22 14:27:53 -0800999
Robert Sloan8ff03552017-06-14 12:40:58 -07001000DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ecb) {
1001 memset(out, 0, sizeof(EVP_CIPHER));
Adam Langleye9ada862015-05-11 17:20:37 -07001002
Robert Sloan8ff03552017-06-14 12:40:58 -07001003 out->nid = NID_aes_192_ecb;
1004 out->block_size = 16;
1005 out->key_len = 24;
1006 out->ctx_size = sizeof(EVP_AES_KEY);
1007 out->flags = EVP_CIPH_ECB_MODE;
1008 out->init = aesni_init_key;
1009 out->cipher = aesni_ecb_cipher;
1010}
1011
1012DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_gcm) {
1013 memset(out, 0, sizeof(EVP_CIPHER));
1014
1015 out->nid = NID_aes_192_gcm;
1016 out->block_size = 1;
1017 out->key_len = 24;
1018 out->iv_len = 12;
1019 out->ctx_size = sizeof(EVP_AES_GCM_CTX);
1020 out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
1021 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
1022 EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER;
1023 out->init = aesni_gcm_init_key;
1024 out->cipher = aes_gcm_cipher;
1025 out->cleanup = aes_gcm_cleanup;
1026 out->ctrl = aes_gcm_ctrl;
1027}
1028
1029DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_cbc) {
1030 memset(out, 0, sizeof(EVP_CIPHER));
1031
1032 out->nid = NID_aes_256_cbc;
1033 out->block_size = 16;
1034 out->key_len = 32;
1035 out->iv_len = 16;
1036 out->ctx_size = sizeof(EVP_AES_KEY);
1037 out->flags = EVP_CIPH_CBC_MODE;
1038 out->init = aesni_init_key;
1039 out->cipher = aesni_cbc_cipher;
1040}
1041
1042DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ctr) {
1043 memset(out, 0, sizeof(EVP_CIPHER));
1044
1045 out->nid = NID_aes_256_ctr;
1046 out->block_size = 1;
1047 out->key_len = 32;
1048 out->iv_len = 16;
1049 out->ctx_size = sizeof(EVP_AES_KEY);
1050 out->flags = EVP_CIPH_CTR_MODE;
1051 out->init = aesni_init_key;
1052 out->cipher = aes_ctr_cipher;
1053}
1054
1055DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ecb) {
1056 memset(out, 0, sizeof(EVP_CIPHER));
1057
1058 out->nid = NID_aes_256_ecb;
1059 out->block_size = 16;
1060 out->key_len = 32;
1061 out->ctx_size = sizeof(EVP_AES_KEY);
1062 out->flags = EVP_CIPH_ECB_MODE;
1063 out->init = aesni_init_key;
1064 out->cipher = aesni_ecb_cipher;
1065}
1066
1067DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ofb) {
1068 memset(out, 0, sizeof(EVP_CIPHER));
1069
1070 out->nid = NID_aes_256_ofb128;
1071 out->block_size = 1;
1072 out->key_len = 32;
1073 out->iv_len = 16;
1074 out->ctx_size = sizeof(EVP_AES_KEY);
1075 out->flags = EVP_CIPH_OFB_MODE;
1076 out->init = aesni_init_key;
1077 out->cipher = aes_ofb_cipher;
1078}
1079
1080DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_gcm) {
1081 memset(out, 0, sizeof(EVP_CIPHER));
1082
1083 out->nid = NID_aes_256_gcm;
1084 out->block_size = 1;
1085 out->key_len = 32;
1086 out->iv_len = 12;
1087 out->ctx_size = sizeof(EVP_AES_GCM_CTX);
1088 out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV |
1089 EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT |
1090 EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY |
1091 EVP_CIPH_FLAG_AEAD_CIPHER;
1092 out->init = aesni_gcm_init_key;
1093 out->cipher = aes_gcm_cipher;
1094 out->cleanup = aes_gcm_cleanup;
1095 out->ctrl = aes_gcm_ctrl;
1096}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001097
1098#define EVP_CIPHER_FUNCTION(keybits, mode) \
1099 const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \
1100 if (aesni_capable()) { \
Robert Sloan8ff03552017-06-14 12:40:58 -07001101 return aesni_##keybits##_##mode(); \
Adam Langleyd9e397b2015-01-22 14:27:53 -08001102 } else { \
Robert Sloan8ff03552017-06-14 12:40:58 -07001103 return aes_##keybits##_##mode##_generic(); \
Adam Langleyd9e397b2015-01-22 14:27:53 -08001104 } \
1105 }
1106
1107#else /* ^^^ OPENSSL_X86_64 || OPENSSL_X86 */
1108
1109static char aesni_capable(void) {
1110 return 0;
1111}
1112
1113#define EVP_CIPHER_FUNCTION(keybits, mode) \
1114 const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \
Robert Sloan8ff03552017-06-14 12:40:58 -07001115 return aes_##keybits##_##mode##_generic(); \
Adam Langleyd9e397b2015-01-22 14:27:53 -08001116 }
1117
1118#endif
1119
1120EVP_CIPHER_FUNCTION(128, cbc)
1121EVP_CIPHER_FUNCTION(128, ctr)
1122EVP_CIPHER_FUNCTION(128, ecb)
Adam Langleye9ada862015-05-11 17:20:37 -07001123EVP_CIPHER_FUNCTION(128, ofb)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001124EVP_CIPHER_FUNCTION(128, gcm)
1125
Adam Langley13d393e2015-04-08 11:18:53 -07001126EVP_CIPHER_FUNCTION(192, cbc)
1127EVP_CIPHER_FUNCTION(192, ctr)
1128EVP_CIPHER_FUNCTION(192, ecb)
1129EVP_CIPHER_FUNCTION(192, gcm)
1130
Adam Langleyd9e397b2015-01-22 14:27:53 -08001131EVP_CIPHER_FUNCTION(256, cbc)
1132EVP_CIPHER_FUNCTION(256, ctr)
1133EVP_CIPHER_FUNCTION(256, ecb)
Adam Langleye9ada862015-05-11 17:20:37 -07001134EVP_CIPHER_FUNCTION(256, ofb)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001135EVP_CIPHER_FUNCTION(256, gcm)
1136
1137
1138#define EVP_AEAD_AES_GCM_TAG_LEN 16
1139
1140struct aead_aes_gcm_ctx {
1141 union {
1142 double align;
1143 AES_KEY ks;
1144 } ks;
1145 GCM128_CONTEXT gcm;
1146 ctr128_f ctr;
1147 uint8_t tag_len;
1148};
1149
Robert Sloan8ff03552017-06-14 12:40:58 -07001150struct aead_aes_gcm_tls12_ctx {
1151 struct aead_aes_gcm_ctx gcm_ctx;
1152 uint64_t counter;
1153};
1154
1155static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx,
1156 const uint8_t *key, size_t key_len,
1157 size_t tag_len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001158 const size_t key_bits = key_len * 8;
1159
1160 if (key_bits != 128 && key_bits != 256) {
Kenny Rootb8494592015-09-25 02:29:14 +00001161 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001162 return 0; /* EVP_AEAD_CTX_init should catch this. */
1163 }
1164
1165 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
1166 tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
1167 }
1168
1169 if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) {
Kenny Rootb8494592015-09-25 02:29:14 +00001170 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001171 return 0;
1172 }
1173
Robert Sloan8ff03552017-06-14 12:40:58 -07001174 gcm_ctx->ctr =
1175 aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, NULL, key, key_len);
1176 gcm_ctx->tag_len = tag_len;
1177 return 1;
1178}
1179
1180static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
1181 size_t key_len, size_t tag_len) {
1182 struct aead_aes_gcm_ctx *gcm_ctx;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001183 gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_ctx));
1184 if (gcm_ctx == NULL) {
1185 return 0;
1186 }
1187
Robert Sloan8ff03552017-06-14 12:40:58 -07001188 if (!aead_aes_gcm_init_impl(gcm_ctx, key, key_len, tag_len)) {
1189 OPENSSL_free(gcm_ctx);
1190 return 0;
1191 }
Adam Langleyd9e397b2015-01-22 14:27:53 -08001192
Robert Sloan8ff03552017-06-14 12:40:58 -07001193 ctx->aead_state = gcm_ctx;
1194 ctx->tag_len = gcm_ctx->tag_len;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001195 return 1;
1196}
1197
1198static void aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx) {
1199 struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1200 OPENSSL_cleanse(gcm_ctx, sizeof(struct aead_aes_gcm_ctx));
1201 OPENSSL_free(gcm_ctx);
1202}
1203
Robert Sloan8ff03552017-06-14 12:40:58 -07001204static int aead_aes_gcm_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out,
1205 uint8_t *out_tag, size_t *out_tag_len,
1206 size_t max_out_tag_len,
1207 const uint8_t *nonce, size_t nonce_len,
1208 const uint8_t *in, size_t in_len,
1209 const uint8_t *ad, size_t ad_len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001210 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1211 GCM128_CONTEXT gcm;
1212
Robert Sloan8ff03552017-06-14 12:40:58 -07001213 if (nonce_len == 0) {
1214 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001215 return 0;
1216 }
1217
Robert Sloan8ff03552017-06-14 12:40:58 -07001218 if (max_out_tag_len < gcm_ctx->tag_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001219 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001220 return 0;
1221 }
1222
Kenny Roote99801b2015-11-06 15:31:15 -08001223 const AES_KEY *key = &gcm_ctx->ks.ks;
1224
Robert Sloan69939df2017-01-09 10:53:07 -08001225 OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
Kenny Roote99801b2015-11-06 15:31:15 -08001226 CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001227
1228 if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
1229 return 0;
1230 }
1231
1232 if (gcm_ctx->ctr) {
Kenny Roote99801b2015-11-06 15:31:15 -08001233 if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len,
Adam Langleyd9e397b2015-01-22 14:27:53 -08001234 gcm_ctx->ctr)) {
1235 return 0;
1236 }
1237 } else {
Kenny Roote99801b2015-11-06 15:31:15 -08001238 if (!CRYPTO_gcm128_encrypt(&gcm, key, in, out, in_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001239 return 0;
1240 }
1241 }
1242
Robert Sloan8ff03552017-06-14 12:40:58 -07001243 CRYPTO_gcm128_tag(&gcm, out_tag, gcm_ctx->tag_len);
1244 *out_tag_len = gcm_ctx->tag_len;
Adam Langleyd9e397b2015-01-22 14:27:53 -08001245 return 1;
1246}
1247
Robert Sloan8ff03552017-06-14 12:40:58 -07001248static int aead_aes_gcm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out,
1249 const uint8_t *nonce, size_t nonce_len,
1250 const uint8_t *in, size_t in_len,
1251 const uint8_t *in_tag, size_t in_tag_len,
1252 const uint8_t *ad, size_t ad_len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001253 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1254 uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN];
Adam Langleyd9e397b2015-01-22 14:27:53 -08001255 GCM128_CONTEXT gcm;
1256
Robert Sloan8ff03552017-06-14 12:40:58 -07001257 if (nonce_len == 0) {
1258 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001259 return 0;
1260 }
1261
Robert Sloan8ff03552017-06-14 12:40:58 -07001262 if (in_tag_len != gcm_ctx->tag_len) {
1263 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001264 return 0;
1265 }
1266
Kenny Roote99801b2015-11-06 15:31:15 -08001267 const AES_KEY *key = &gcm_ctx->ks.ks;
1268
Robert Sloan69939df2017-01-09 10:53:07 -08001269 OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
Kenny Roote99801b2015-11-06 15:31:15 -08001270 CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001271
1272 if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
1273 return 0;
1274 }
1275
1276 if (gcm_ctx->ctr) {
Robert Sloan8ff03552017-06-14 12:40:58 -07001277 if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out, in_len,
1278 gcm_ctx->ctr)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001279 return 0;
1280 }
1281 } else {
Robert Sloan8ff03552017-06-14 12:40:58 -07001282 if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001283 return 0;
1284 }
1285 }
1286
1287 CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
Robert Sloan8ff03552017-06-14 12:40:58 -07001288 if (CRYPTO_memcmp(tag, in_tag, gcm_ctx->tag_len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001289 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001290 return 0;
1291 }
1292
Adam Langleyd9e397b2015-01-22 14:27:53 -08001293 return 1;
1294}
1295
Robert Sloan8ff03552017-06-14 12:40:58 -07001296DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm) {
1297 memset(out, 0, sizeof(EVP_AEAD));
Adam Langleyd9e397b2015-01-22 14:27:53 -08001298
Robert Sloan8ff03552017-06-14 12:40:58 -07001299 out->key_len = 16;
1300 out->nonce_len = 12;
1301 out->overhead = EVP_AEAD_AES_GCM_TAG_LEN;
1302 out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
1303 out->init = aead_aes_gcm_init;
1304 out->cleanup = aead_aes_gcm_cleanup;
1305 out->seal_scatter = aead_aes_gcm_seal_scatter;
1306 out->open_gather = aead_aes_gcm_open_gather;
1307}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001308
Robert Sloan8ff03552017-06-14 12:40:58 -07001309DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm) {
1310 memset(out, 0, sizeof(EVP_AEAD));
Adam Langleyd9e397b2015-01-22 14:27:53 -08001311
Robert Sloan8ff03552017-06-14 12:40:58 -07001312 out->key_len = 32;
1313 out->nonce_len = 12;
1314 out->overhead = EVP_AEAD_AES_GCM_TAG_LEN;
1315 out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
1316 out->init = aead_aes_gcm_init;
1317 out->cleanup = aead_aes_gcm_cleanup;
1318 out->seal_scatter = aead_aes_gcm_seal_scatter;
1319 out->open_gather = aead_aes_gcm_open_gather;
1320}
Adam Langleyd9e397b2015-01-22 14:27:53 -08001321
Robert Sloan8ff03552017-06-14 12:40:58 -07001322static int aead_aes_gcm_tls12_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
1323 size_t key_len, size_t tag_len) {
1324 struct aead_aes_gcm_tls12_ctx *gcm_ctx;
1325 gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_tls12_ctx));
1326 if (gcm_ctx == NULL) {
1327 return 0;
1328 }
Robert Sloan9254e682017-04-24 09:42:06 -07001329
Robert Sloan8ff03552017-06-14 12:40:58 -07001330 gcm_ctx->counter = 0;
1331
1332 if (!aead_aes_gcm_init_impl(&gcm_ctx->gcm_ctx, key, key_len, tag_len)) {
1333 OPENSSL_free(gcm_ctx);
1334 return 0;
1335 }
1336
1337 ctx->aead_state = gcm_ctx;
1338 ctx->tag_len = gcm_ctx->gcm_ctx.tag_len;
1339 return 1;
1340}
1341
1342static void aead_aes_gcm_tls12_cleanup(EVP_AEAD_CTX *ctx) {
1343 struct aead_aes_gcm_tls12_ctx *gcm_ctx = ctx->aead_state;
1344 OPENSSL_cleanse(gcm_ctx, sizeof(struct aead_aes_gcm_tls12_ctx));
1345 OPENSSL_free(gcm_ctx);
1346}
1347
1348static int aead_aes_gcm_tls12_seal_scatter(
1349 const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag,
1350 size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce,
1351 size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *ad,
1352 size_t ad_len) {
1353 struct aead_aes_gcm_tls12_ctx *gcm_ctx = ctx->aead_state;
1354 if (gcm_ctx->counter == UINT64_MAX) {
1355 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE);
1356 return 0;
1357 }
1358
1359 if (nonce_len != 12) {
Robert Sloan9254e682017-04-24 09:42:06 -07001360 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
1361 return 0;
1362 }
Robert Sloan8ff03552017-06-14 12:40:58 -07001363
1364 const uint64_t be_counter = CRYPTO_bswap8(gcm_ctx->counter);
1365 if (OPENSSL_memcmp((uint8_t *)&be_counter, nonce + nonce_len - 8, 8) != 0) {
1366 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE);
Robert Sloan9254e682017-04-24 09:42:06 -07001367 return 0;
1368 }
1369
Robert Sloan8ff03552017-06-14 12:40:58 -07001370 gcm_ctx->counter++;
Robert Sloan9254e682017-04-24 09:42:06 -07001371
Robert Sloan8ff03552017-06-14 12:40:58 -07001372 return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len,
1373 max_out_tag_len, nonce, nonce_len, in,
1374 in_len, ad, ad_len);
Robert Sloan9254e682017-04-24 09:42:06 -07001375}
1376
Robert Sloan8ff03552017-06-14 12:40:58 -07001377DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_tls12) {
1378 memset(out, 0, sizeof(EVP_AEAD));
Robert Sloan9254e682017-04-24 09:42:06 -07001379
Robert Sloan8ff03552017-06-14 12:40:58 -07001380 out->key_len = 16;
1381 out->nonce_len = 12;
1382 out->overhead = EVP_AEAD_AES_GCM_TAG_LEN;
1383 out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
1384 out->init = aead_aes_gcm_tls12_init;
1385 out->cleanup = aead_aes_gcm_tls12_cleanup;
1386 out->seal_scatter = aead_aes_gcm_tls12_seal_scatter;
1387 out->open_gather = aead_aes_gcm_open_gather;
Robert Sloan9254e682017-04-24 09:42:06 -07001388}
1389
Robert Sloan8ff03552017-06-14 12:40:58 -07001390DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_tls12) {
1391 memset(out, 0, sizeof(EVP_AEAD));
Robert Sloan9254e682017-04-24 09:42:06 -07001392
Robert Sloan8ff03552017-06-14 12:40:58 -07001393 out->key_len = 32;
1394 out->nonce_len = 12;
1395 out->overhead = EVP_AEAD_AES_GCM_TAG_LEN;
1396 out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
1397 out->init = aead_aes_gcm_tls12_init;
1398 out->cleanup = aead_aes_gcm_tls12_cleanup;
1399 out->seal_scatter = aead_aes_gcm_tls12_seal_scatter;
1400 out->open_gather = aead_aes_gcm_open_gather;
Robert Sloan9254e682017-04-24 09:42:06 -07001401}
1402
Adam Langleyd9e397b2015-01-22 14:27:53 -08001403int EVP_has_aes_hardware(void) {
1404#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
1405 return aesni_capable() && crypto_gcm_clmul_enabled();
1406#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
Kenny Roote99801b2015-11-06 15:31:15 -08001407 return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable();
Adam Langleyd9e397b2015-01-22 14:27:53 -08001408#else
1409 return 0;
1410#endif
1411}