blob: 0e9a7cd70042c8656b7ac22519cef39c0217ed13 [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>
Adam Langleye9ada862015-05-11 17:20:37 -070059#include <openssl/sha.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080060
61#include "internal.h"
Adam Langleye9ada862015-05-11 17:20:37 -070062#include "../internal.h"
Adam Langleyd9e397b2015-01-22 14:27:53 -080063#include "../modes/internal.h"
64
65#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
Kenny Rootb8494592015-09-25 02:29:14 +000066#include <openssl/arm_arch.h>
Adam Langleyd9e397b2015-01-22 14:27:53 -080067#endif
68
69
David Benjamin6e899c72016-06-09 18:02:18 -040070OPENSSL_MSVC_PRAGMA(warning(disable: 4702)) /* Unreachable code. */
David Benjamin4969cc92016-04-22 15:02:23 -040071
Adam Langleyd9e397b2015-01-22 14:27:53 -080072typedef struct {
73 union {
74 double align;
75 AES_KEY ks;
76 } ks;
77 block128_f block;
78 union {
79 cbc128_f cbc;
80 ctr128_f ctr;
81 } stream;
82} EVP_AES_KEY;
83
84typedef struct {
85 union {
86 double align;
87 AES_KEY ks;
88 } ks; /* AES key schedule to use */
89 int key_set; /* Set if key initialised */
90 int iv_set; /* Set if an iv is set */
91 GCM128_CONTEXT gcm;
92 uint8_t *iv; /* Temporary IV store */
93 int ivlen; /* IV length */
94 int taglen;
95 int iv_gen; /* It is OK to generate IVs */
96 ctr128_f ctr;
97} EVP_AES_GCM_CTX;
98
99#if !defined(OPENSSL_NO_ASM) && \
100 (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
101#define VPAES
Adam Langleyd9e397b2015-01-22 14:27:53 -0800102static char vpaes_capable(void) {
103 return (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) != 0;
104}
105
106#if defined(OPENSSL_X86_64)
107#define BSAES
108static char bsaes_capable(void) {
109 return vpaes_capable();
110}
111#endif
112
113#elif !defined(OPENSSL_NO_ASM) && \
114 (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
Adam Langleyd9e397b2015-01-22 14:27:53 -0800115
Adam Langleyf4e42722015-06-04 17:45:09 -0700116#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
Adam Langleyd9e397b2015-01-22 14:27:53 -0800117#define BSAES
118static char bsaes_capable(void) {
119 return CRYPTO_is_NEON_capable();
120}
121#endif
122
123#define HWAES
Kenny Roote99801b2015-11-06 15:31:15 -0800124static int hwaes_capable(void) {
125 return CRYPTO_is_ARMv8_AES_capable();
Adam Langleyd9e397b2015-01-22 14:27:53 -0800126}
127
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400128#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_PPC64LE)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800129
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400130#define HWAES
131static int hwaes_capable(void) {
132 return CRYPTO_is_PPC64LE_vcrypto_capable();
133}
134
135#endif /* OPENSSL_PPC64LE */
136
Adam Langleyd9e397b2015-01-22 14:27:53 -0800137
138#if defined(BSAES)
139/* On platforms where BSAES gets defined (just above), then these functions are
140 * provided by asm. */
141void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
142 const AES_KEY *key, uint8_t ivec[16], int enc);
143void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
144 const AES_KEY *key, const uint8_t ivec[16]);
145#else
146static char bsaes_capable(void) {
147 return 0;
148}
149
150/* On other platforms, bsaes_capable() will always return false and so the
151 * following will never be called. */
Kenny Roote99801b2015-11-06 15:31:15 -0800152static void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
153 const AES_KEY *key, uint8_t ivec[16], int enc) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800154 abort();
155}
156
Kenny Roote99801b2015-11-06 15:31:15 -0800157static void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
158 size_t len, const AES_KEY *key,
159 const uint8_t ivec[16]) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800160 abort();
161}
162#endif
163
164#if defined(VPAES)
165/* On platforms where VPAES gets defined (just above), then these functions are
166 * provided by asm. */
167int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
168int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
169
170void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
171void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
172
173void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
174 const AES_KEY *key, uint8_t *ivec, int enc);
175#else
176static char vpaes_capable(void) {
177 return 0;
178}
179
180/* On other platforms, vpaes_capable() will always return false and so the
181 * following will never be called. */
Kenny Roote99801b2015-11-06 15:31:15 -0800182static int vpaes_set_encrypt_key(const uint8_t *userKey, int bits,
183 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800184 abort();
185}
Kenny Roote99801b2015-11-06 15:31:15 -0800186static int vpaes_set_decrypt_key(const uint8_t *userKey, int bits,
187 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800188 abort();
189}
Kenny Roote99801b2015-11-06 15:31:15 -0800190static void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800191 abort();
192}
Kenny Roote99801b2015-11-06 15:31:15 -0800193static void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800194 abort();
195}
Kenny Roote99801b2015-11-06 15:31:15 -0800196static void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
197 const AES_KEY *key, uint8_t *ivec, int enc) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800198 abort();
199}
200#endif
201
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400202#if defined(HWAES)
203int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits,
204 AES_KEY *key);
205int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits,
206 AES_KEY *key);
207void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
208void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
209void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
210 const AES_KEY *key, uint8_t *ivec, const int enc);
211void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len,
212 const AES_KEY *key, const uint8_t ivec[16]);
213#else
Adam Langleyd9e397b2015-01-22 14:27:53 -0800214/* If HWAES isn't defined then we provide dummy functions for each of the hwaes
215 * functions. */
Kenny Roote99801b2015-11-06 15:31:15 -0800216static int hwaes_capable(void) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800217 return 0;
218}
219
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400220static int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits,
Kenny Roote99801b2015-11-06 15:31:15 -0800221 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800222 abort();
223}
224
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400225static int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits,
Kenny Roote99801b2015-11-06 15:31:15 -0800226 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800227 abort();
228}
229
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400230static void aes_hw_encrypt(const uint8_t *in, uint8_t *out,
Kenny Roote99801b2015-11-06 15:31:15 -0800231 const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800232 abort();
233}
234
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400235static void aes_hw_decrypt(const uint8_t *in, uint8_t *out,
Kenny Roote99801b2015-11-06 15:31:15 -0800236 const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800237 abort();
238}
239
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400240static void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
Kenny Roote99801b2015-11-06 15:31:15 -0800241 const AES_KEY *key, uint8_t *ivec, int enc) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800242 abort();
243}
244
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400245static void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
Kenny Roote99801b2015-11-06 15:31:15 -0800246 size_t len, const AES_KEY *key,
247 const uint8_t ivec[16]) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800248 abort();
249}
250#endif
251
252#if !defined(OPENSSL_NO_ASM) && \
253 (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
254int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
255int aesni_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key);
256
257void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
258void aesni_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key);
259
260void aesni_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length,
261 const AES_KEY *key, int enc);
262void aesni_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length,
263 const AES_KEY *key, uint8_t *ivec, int enc);
264
Adam Langleyd9e397b2015-01-22 14:27:53 -0800265#else
266
267/* On other platforms, aesni_capable() will always return false and so the
268 * following will never be called. */
Kenny Roote99801b2015-11-06 15:31:15 -0800269static void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800270 abort();
271}
Kenny Roote99801b2015-11-06 15:31:15 -0800272static int aesni_set_encrypt_key(const uint8_t *userKey, int bits,
273 AES_KEY *key) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800274 abort();
275}
Kenny Roote99801b2015-11-06 15:31:15 -0800276static void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
277 size_t blocks, const void *key,
278 const uint8_t *ivec) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800279 abort();
280}
281
282#endif
283
284static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
David Benjamin4969cc92016-04-22 15:02:23 -0400285 const uint8_t *iv, int enc) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800286 int ret, mode;
287 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
288
289 mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK;
290 if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) {
291 if (hwaes_capable()) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400292 ret = aes_hw_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
293 dat->block = (block128_f)aes_hw_decrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800294 dat->stream.cbc = NULL;
295 if (mode == EVP_CIPH_CBC_MODE) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400296 dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800297 }
298 } else if (bsaes_capable() && mode == EVP_CIPH_CBC_MODE) {
299 ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
300 dat->block = (block128_f)AES_decrypt;
301 dat->stream.cbc = (cbc128_f)bsaes_cbc_encrypt;
302 } else if (vpaes_capable()) {
303 ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
304 dat->block = (block128_f)vpaes_decrypt;
305 dat->stream.cbc =
306 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)vpaes_cbc_encrypt : NULL;
307 } else {
308 ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
309 dat->block = (block128_f)AES_decrypt;
310 dat->stream.cbc =
311 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)AES_cbc_encrypt : NULL;
312 }
313 } else if (hwaes_capable()) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400314 ret = aes_hw_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
315 dat->block = (block128_f)aes_hw_encrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800316 dat->stream.cbc = NULL;
317 if (mode == EVP_CIPH_CBC_MODE) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400318 dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800319 } else if (mode == EVP_CIPH_CTR_MODE) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400320 dat->stream.ctr = (ctr128_f)aes_hw_ctr32_encrypt_blocks;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800321 }
322 } else if (bsaes_capable() && mode == EVP_CIPH_CTR_MODE) {
323 ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
324 dat->block = (block128_f)AES_encrypt;
325 dat->stream.ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
326 } else if (vpaes_capable()) {
327 ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
328 dat->block = (block128_f)vpaes_encrypt;
329 dat->stream.cbc =
330 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)vpaes_cbc_encrypt : NULL;
331 } else {
332 ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks);
333 dat->block = (block128_f)AES_encrypt;
334 dat->stream.cbc =
335 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)AES_cbc_encrypt : NULL;
336 }
337
338 if (ret < 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000339 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800340 return 0;
341 }
342
343 return 1;
344}
345
Adam Langleye9ada862015-05-11 17:20:37 -0700346static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
347 size_t len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800348 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
349
350 if (dat->stream.cbc) {
351 (*dat->stream.cbc)(in, out, len, &dat->ks, ctx->iv, ctx->encrypt);
352 } else if (ctx->encrypt) {
353 CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
354 } else {
355 CRYPTO_cbc128_decrypt(in, out, len, &dat->ks, ctx->iv, dat->block);
356 }
357
358 return 1;
359}
360
Adam Langleye9ada862015-05-11 17:20:37 -0700361static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
362 size_t len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800363 size_t bl = ctx->cipher->block_size;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800364 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
365
366 if (len < bl) {
367 return 1;
368 }
369
David Benjamin7c0d06c2016-08-11 13:26:41 -0400370 len -= bl;
371 for (size_t i = 0; i <= len; i += bl) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800372 (*dat->block)(in + i, out + i, &dat->ks);
373 }
374
375 return 1;
376}
377
Adam Langleye9ada862015-05-11 17:20:37 -0700378static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
379 size_t len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800380 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
381
382 if (dat->stream.ctr) {
David Benjamin4969cc92016-04-22 15:02:23 -0400383 CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, ctx->iv, ctx->buf,
384 &ctx->num, dat->stream.ctr);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800385 } else {
David Benjamin4969cc92016-04-22 15:02:23 -0400386 CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &ctx->num,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800387 dat->block);
388 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800389 return 1;
390}
391
Adam Langleye9ada862015-05-11 17:20:37 -0700392static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
393 size_t len) {
394 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
395
396 CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, ctx->iv, &ctx->num, dat->block);
397 return 1;
398}
399
400static char aesni_capable(void);
401
402static ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
403 block128_f *out_block, const uint8_t *key,
David Benjamin4969cc92016-04-22 15:02:23 -0400404 size_t key_len) {
Adam Langleye9ada862015-05-11 17:20:37 -0700405 if (aesni_capable()) {
406 aesni_set_encrypt_key(key, key_len * 8, aes_key);
407 if (gcm_ctx != NULL) {
408 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aesni_encrypt);
409 }
410 if (out_block) {
411 *out_block = (block128_f) aesni_encrypt;
412 }
413 return (ctr128_f)aesni_ctr32_encrypt_blocks;
414 }
415
Adam Langleyd9e397b2015-01-22 14:27:53 -0800416 if (hwaes_capable()) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400417 aes_hw_set_encrypt_key(key, key_len * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700418 if (gcm_ctx != NULL) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400419 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aes_hw_encrypt);
Adam Langleye9ada862015-05-11 17:20:37 -0700420 }
421 if (out_block) {
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400422 *out_block = (block128_f) aes_hw_encrypt;
Adam Langleye9ada862015-05-11 17:20:37 -0700423 }
Steven Valdezbb1ceac2016-10-07 10:34:51 -0400424 return (ctr128_f)aes_hw_ctr32_encrypt_blocks;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800425 }
426
427 if (bsaes_capable()) {
428 AES_set_encrypt_key(key, key_len * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700429 if (gcm_ctx != NULL) {
430 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
431 }
432 if (out_block) {
433 *out_block = (block128_f) AES_encrypt;
434 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800435 return (ctr128_f)bsaes_ctr32_encrypt_blocks;
436 }
437
438 if (vpaes_capable()) {
439 vpaes_set_encrypt_key(key, key_len * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700440 if (out_block) {
441 *out_block = (block128_f) vpaes_encrypt;
442 }
443 if (gcm_ctx != NULL) {
444 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt);
445 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800446 return NULL;
447 }
448
449 AES_set_encrypt_key(key, key_len * 8, aes_key);
Adam Langleye9ada862015-05-11 17:20:37 -0700450 if (gcm_ctx != NULL) {
451 CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
452 }
453 if (out_block) {
454 *out_block = (block128_f) AES_encrypt;
455 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800456 return NULL;
457}
458
459static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
460 const uint8_t *iv, int enc) {
461 EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
462 if (!iv && !key) {
463 return 1;
464 }
465 if (key) {
Adam Langleye9ada862015-05-11 17:20:37 -0700466 gctx->ctr =
467 aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm, NULL, key, ctx->key_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800468 /* If we have an iv can set it directly, otherwise use saved IV. */
469 if (iv == NULL && gctx->iv_set) {
470 iv = gctx->iv;
471 }
472 if (iv) {
Kenny Roote99801b2015-11-06 15:31:15 -0800473 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800474 gctx->iv_set = 1;
475 }
476 gctx->key_set = 1;
477 } else {
478 /* If key set use IV, otherwise copy */
479 if (gctx->key_set) {
Kenny Roote99801b2015-11-06 15:31:15 -0800480 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800481 } else {
Robert Sloan69939df2017-01-09 10:53:07 -0800482 OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800483 }
484 gctx->iv_set = 1;
485 gctx->iv_gen = 0;
486 }
487 return 1;
488}
489
Adam Langleye9ada862015-05-11 17:20:37 -0700490static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800491 EVP_AES_GCM_CTX *gctx = c->cipher_data;
492 OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
493 if (gctx->iv != c->iv) {
494 OPENSSL_free(gctx->iv);
495 }
Adam Langleyd9e397b2015-01-22 14:27:53 -0800496}
497
498/* increment counter (64-bit int) by 1 */
499static void ctr64_inc(uint8_t *counter) {
500 int n = 8;
501 uint8_t c;
502
503 do {
504 --n;
505 c = counter[n];
506 ++c;
507 counter[n] = c;
508 if (c) {
509 return;
510 }
511 } while (n);
512}
513
514static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
515 EVP_AES_GCM_CTX *gctx = c->cipher_data;
516 switch (type) {
517 case EVP_CTRL_INIT:
518 gctx->key_set = 0;
519 gctx->iv_set = 0;
520 gctx->ivlen = c->cipher->iv_len;
521 gctx->iv = c->iv;
522 gctx->taglen = -1;
523 gctx->iv_gen = 0;
524 return 1;
525
526 case EVP_CTRL_GCM_SET_IVLEN:
527 if (arg <= 0) {
528 return 0;
529 }
530
531 /* Allocate memory for IV if needed */
532 if (arg > EVP_MAX_IV_LENGTH && arg > gctx->ivlen) {
533 if (gctx->iv != c->iv) {
534 OPENSSL_free(gctx->iv);
535 }
536 gctx->iv = OPENSSL_malloc(arg);
537 if (!gctx->iv) {
538 return 0;
539 }
540 }
541 gctx->ivlen = arg;
542 return 1;
543
544 case EVP_CTRL_GCM_SET_TAG:
545 if (arg <= 0 || arg > 16 || c->encrypt) {
546 return 0;
547 }
Robert Sloan69939df2017-01-09 10:53:07 -0800548 OPENSSL_memcpy(c->buf, ptr, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800549 gctx->taglen = arg;
550 return 1;
551
552 case EVP_CTRL_GCM_GET_TAG:
553 if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) {
554 return 0;
555 }
Robert Sloan69939df2017-01-09 10:53:07 -0800556 OPENSSL_memcpy(ptr, c->buf, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800557 return 1;
558
559 case EVP_CTRL_GCM_SET_IV_FIXED:
560 /* Special case: -1 length restores whole IV */
561 if (arg == -1) {
Robert Sloan69939df2017-01-09 10:53:07 -0800562 OPENSSL_memcpy(gctx->iv, ptr, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800563 gctx->iv_gen = 1;
564 return 1;
565 }
566 /* Fixed field must be at least 4 bytes and invocation field
567 * at least 8. */
568 if (arg < 4 || (gctx->ivlen - arg) < 8) {
569 return 0;
570 }
571 if (arg) {
Robert Sloan69939df2017-01-09 10:53:07 -0800572 OPENSSL_memcpy(gctx->iv, ptr, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800573 }
574 if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) {
575 return 0;
576 }
577 gctx->iv_gen = 1;
578 return 1;
579
580 case EVP_CTRL_GCM_IV_GEN:
581 if (gctx->iv_gen == 0 || gctx->key_set == 0) {
582 return 0;
583 }
Kenny Roote99801b2015-11-06 15:31:15 -0800584 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800585 if (arg <= 0 || arg > gctx->ivlen) {
586 arg = gctx->ivlen;
587 }
Robert Sloan69939df2017-01-09 10:53:07 -0800588 OPENSSL_memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800589 /* Invocation field will be at least 8 bytes in size and
590 * so no need to check wrap around or increment more than
591 * last 8 bytes. */
592 ctr64_inc(gctx->iv + gctx->ivlen - 8);
593 gctx->iv_set = 1;
594 return 1;
595
596 case EVP_CTRL_GCM_SET_IV_INV:
597 if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) {
598 return 0;
599 }
Robert Sloan69939df2017-01-09 10:53:07 -0800600 OPENSSL_memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg);
Kenny Roote99801b2015-11-06 15:31:15 -0800601 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800602 gctx->iv_set = 1;
603 return 1;
604
605 case EVP_CTRL_COPY: {
606 EVP_CIPHER_CTX *out = ptr;
607 EVP_AES_GCM_CTX *gctx_out = out->cipher_data;
Adam Langleyd9e397b2015-01-22 14:27:53 -0800608 if (gctx->iv == c->iv) {
609 gctx_out->iv = out->iv;
610 } else {
611 gctx_out->iv = OPENSSL_malloc(gctx->ivlen);
612 if (!gctx_out->iv) {
613 return 0;
614 }
Robert Sloan69939df2017-01-09 10:53:07 -0800615 OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800616 }
617 return 1;
618 }
619
620 default:
621 return -1;
622 }
623}
624
625static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
626 size_t len) {
627 EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
628
629 /* If not set up, return error */
630 if (!gctx->key_set) {
631 return -1;
632 }
633 if (!gctx->iv_set) {
634 return -1;
635 }
636
637 if (in) {
638 if (out == NULL) {
639 if (!CRYPTO_gcm128_aad(&gctx->gcm, in, len)) {
640 return -1;
641 }
642 } else if (ctx->encrypt) {
643 if (gctx->ctr) {
David Benjamin4969cc92016-04-22 15:02:23 -0400644 if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
645 gctx->ctr)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800646 return -1;
647 }
648 } else {
David Benjamin4969cc92016-04-22 15:02:23 -0400649 if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800650 return -1;
651 }
652 }
653 } else {
654 if (gctx->ctr) {
David Benjamin4969cc92016-04-22 15:02:23 -0400655 if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len,
656 gctx->ctr)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800657 return -1;
658 }
659 } else {
David Benjamin4969cc92016-04-22 15:02:23 -0400660 if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800661 return -1;
662 }
663 }
664 }
665 return len;
666 } else {
667 if (!ctx->encrypt) {
668 if (gctx->taglen < 0 ||
Kenny Rootb8494592015-09-25 02:29:14 +0000669 !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -0800670 return -1;
671 }
672 gctx->iv_set = 0;
673 return 0;
674 }
675 CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16);
676 gctx->taglen = 16;
677 /* Don't reuse the IV */
678 gctx->iv_set = 0;
679 return 0;
680 }
681}
682
683static const EVP_CIPHER aes_128_cbc = {
684 NID_aes_128_cbc, 16 /* block_size */, 16 /* key_size */,
685 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
686 NULL /* app_data */, aes_init_key, aes_cbc_cipher,
687 NULL /* cleanup */, NULL /* ctrl */};
688
689static const EVP_CIPHER aes_128_ctr = {
690 NID_aes_128_ctr, 1 /* block_size */, 16 /* key_size */,
691 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
692 NULL /* app_data */, aes_init_key, aes_ctr_cipher,
693 NULL /* cleanup */, NULL /* ctrl */};
694
695static const EVP_CIPHER aes_128_ecb = {
696 NID_aes_128_ecb, 16 /* block_size */, 16 /* key_size */,
697 0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
698 NULL /* app_data */, aes_init_key, aes_ecb_cipher,
699 NULL /* cleanup */, NULL /* ctrl */};
700
Adam Langleye9ada862015-05-11 17:20:37 -0700701static const EVP_CIPHER aes_128_ofb = {
702 NID_aes_128_ofb128, 1 /* block_size */, 16 /* key_size */,
703 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
704 NULL /* app_data */, aes_init_key, aes_ofb_cipher,
705 NULL /* cleanup */, NULL /* ctrl */};
706
Adam Langleyd9e397b2015-01-22 14:27:53 -0800707static const EVP_CIPHER aes_128_gcm = {
708 NID_aes_128_gcm, 1 /* block_size */, 16 /* key_size */, 12 /* iv_len */,
709 sizeof(EVP_AES_GCM_CTX),
710 EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
711 EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
712 EVP_CIPH_FLAG_AEAD_CIPHER,
713 NULL /* app_data */, aes_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
714 aes_gcm_ctrl};
715
716
Adam Langley13d393e2015-04-08 11:18:53 -0700717static const EVP_CIPHER aes_192_cbc = {
718 NID_aes_192_cbc, 16 /* block_size */, 24 /* key_size */,
719 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
720 NULL /* app_data */, aes_init_key, aes_cbc_cipher,
721 NULL /* cleanup */, NULL /* ctrl */};
722
723static const EVP_CIPHER aes_192_ctr = {
724 NID_aes_192_ctr, 1 /* block_size */, 24 /* key_size */,
725 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
726 NULL /* app_data */, aes_init_key, aes_ctr_cipher,
727 NULL /* cleanup */, NULL /* ctrl */};
728
729static const EVP_CIPHER aes_192_ecb = {
730 NID_aes_192_ecb, 16 /* block_size */, 24 /* key_size */,
731 0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
732 NULL /* app_data */, aes_init_key, aes_ecb_cipher,
733 NULL /* cleanup */, NULL /* ctrl */};
734
735static const EVP_CIPHER aes_192_gcm = {
736 NID_aes_192_gcm, 1 /* block_size */, 24 /* key_size */, 12 /* iv_len */,
737 sizeof(EVP_AES_GCM_CTX),
738 EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
739 EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
740 EVP_CIPH_FLAG_AEAD_CIPHER,
741 NULL /* app_data */, aes_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
742 aes_gcm_ctrl};
743
744
Adam Langleyd9e397b2015-01-22 14:27:53 -0800745static const EVP_CIPHER aes_256_cbc = {
Adam Langleye9ada862015-05-11 17:20:37 -0700746 NID_aes_256_cbc, 16 /* block_size */, 32 /* key_size */,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800747 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
748 NULL /* app_data */, aes_init_key, aes_cbc_cipher,
749 NULL /* cleanup */, NULL /* ctrl */};
750
751static const EVP_CIPHER aes_256_ctr = {
Adam Langleye9ada862015-05-11 17:20:37 -0700752 NID_aes_256_ctr, 1 /* block_size */, 32 /* key_size */,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800753 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
754 NULL /* app_data */, aes_init_key, aes_ctr_cipher,
755 NULL /* cleanup */, NULL /* ctrl */};
756
757static const EVP_CIPHER aes_256_ecb = {
Adam Langleye9ada862015-05-11 17:20:37 -0700758 NID_aes_256_ecb, 16 /* block_size */, 32 /* key_size */,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800759 0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
760 NULL /* app_data */, aes_init_key, aes_ecb_cipher,
761 NULL /* cleanup */, NULL /* ctrl */};
762
Adam Langleye9ada862015-05-11 17:20:37 -0700763static const EVP_CIPHER aes_256_ofb = {
764 NID_aes_256_ofb128, 1 /* block_size */, 32 /* key_size */,
765 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
766 NULL /* app_data */, aes_init_key, aes_ofb_cipher,
767 NULL /* cleanup */, NULL /* ctrl */};
768
Adam Langleyd9e397b2015-01-22 14:27:53 -0800769static const EVP_CIPHER aes_256_gcm = {
Adam Langleye9ada862015-05-11 17:20:37 -0700770 NID_aes_256_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800771 sizeof(EVP_AES_GCM_CTX),
772 EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
773 EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
774 EVP_CIPH_FLAG_AEAD_CIPHER,
775 NULL /* app_data */, aes_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
776 aes_gcm_ctrl};
777
778#if !defined(OPENSSL_NO_ASM) && \
779 (defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
780
781/* AES-NI section. */
782
783static char aesni_capable(void) {
784 return (OPENSSL_ia32cap_P[1] & (1 << (57 - 32))) != 0;
785}
786
787static int aesni_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
788 const uint8_t *iv, int enc) {
789 int ret, mode;
790 EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data;
791
792 mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK;
793 if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) {
794 ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
795 dat->block = (block128_f)aesni_decrypt;
796 dat->stream.cbc =
797 mode == EVP_CIPH_CBC_MODE ? (cbc128_f)aesni_cbc_encrypt : NULL;
798 } else {
799 ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data);
800 dat->block = (block128_f)aesni_encrypt;
801 if (mode == EVP_CIPH_CBC_MODE) {
802 dat->stream.cbc = (cbc128_f)aesni_cbc_encrypt;
803 } else if (mode == EVP_CIPH_CTR_MODE) {
804 dat->stream.ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
805 } else {
806 dat->stream.cbc = NULL;
807 }
808 }
809
810 if (ret < 0) {
Kenny Rootb8494592015-09-25 02:29:14 +0000811 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800812 return 0;
813 }
814
815 return 1;
816}
817
818static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
819 const uint8_t *in, size_t len) {
820 aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt);
821
822 return 1;
823}
824
825static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
826 const uint8_t *in, size_t len) {
827 size_t bl = ctx->cipher->block_size;
828
829 if (len < bl) {
830 return 1;
831 }
832
833 aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt);
834
835 return 1;
836}
837
838static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
839 const uint8_t *iv, int enc) {
840 EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
841 if (!iv && !key) {
842 return 1;
843 }
844 if (key) {
845 aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks.ks);
846 CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)aesni_encrypt);
847 gctx->ctr = (ctr128_f)aesni_ctr32_encrypt_blocks;
848 /* If we have an iv can set it directly, otherwise use
849 * saved IV. */
850 if (iv == NULL && gctx->iv_set) {
851 iv = gctx->iv;
852 }
853 if (iv) {
Kenny Roote99801b2015-11-06 15:31:15 -0800854 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800855 gctx->iv_set = 1;
856 }
857 gctx->key_set = 1;
858 } else {
859 /* If key set use IV, otherwise copy */
860 if (gctx->key_set) {
Kenny Roote99801b2015-11-06 15:31:15 -0800861 CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800862 } else {
Robert Sloan69939df2017-01-09 10:53:07 -0800863 OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen);
Adam Langleyd9e397b2015-01-22 14:27:53 -0800864 }
865 gctx->iv_set = 1;
866 gctx->iv_gen = 0;
867 }
868 return 1;
869}
870
871static const EVP_CIPHER aesni_128_cbc = {
872 NID_aes_128_cbc, 16 /* block_size */, 16 /* key_size */,
873 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
874 NULL /* app_data */, aesni_init_key, aesni_cbc_cipher,
875 NULL /* cleanup */, NULL /* ctrl */};
876
877static const EVP_CIPHER aesni_128_ctr = {
878 NID_aes_128_ctr, 1 /* block_size */, 16 /* key_size */,
879 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
880 NULL /* app_data */, aesni_init_key, aes_ctr_cipher,
881 NULL /* cleanup */, NULL /* ctrl */};
882
883static const EVP_CIPHER aesni_128_ecb = {
884 NID_aes_128_ecb, 16 /* block_size */, 16 /* key_size */,
885 0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
886 NULL /* app_data */, aesni_init_key, aesni_ecb_cipher,
887 NULL /* cleanup */, NULL /* ctrl */};
888
Adam Langleye9ada862015-05-11 17:20:37 -0700889static const EVP_CIPHER aesni_128_ofb = {
890 NID_aes_128_ofb128, 1 /* block_size */, 16 /* key_size */,
891 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
892 NULL /* app_data */, aesni_init_key, aes_ofb_cipher,
893 NULL /* cleanup */, NULL /* ctrl */};
894
Adam Langleyd9e397b2015-01-22 14:27:53 -0800895static const EVP_CIPHER aesni_128_gcm = {
896 NID_aes_128_gcm, 1 /* block_size */, 16 /* key_size */, 12 /* iv_len */,
897 sizeof(EVP_AES_GCM_CTX),
898 EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
899 EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
900 EVP_CIPH_FLAG_AEAD_CIPHER,
901 NULL /* app_data */, aesni_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
902 aes_gcm_ctrl};
903
904
Adam Langley13d393e2015-04-08 11:18:53 -0700905static const EVP_CIPHER aesni_192_cbc = {
906 NID_aes_192_cbc, 16 /* block_size */, 24 /* key_size */,
907 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
908 NULL /* app_data */, aesni_init_key, aesni_cbc_cipher,
909 NULL /* cleanup */, NULL /* ctrl */};
910
911static const EVP_CIPHER aesni_192_ctr = {
912 NID_aes_192_ctr, 1 /* block_size */, 24 /* key_size */,
913 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
914 NULL /* app_data */, aesni_init_key, aes_ctr_cipher,
915 NULL /* cleanup */, NULL /* ctrl */};
916
917static const EVP_CIPHER aesni_192_ecb = {
918 NID_aes_192_ecb, 16 /* block_size */, 24 /* key_size */,
919 0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
920 NULL /* app_data */, aesni_init_key, aesni_ecb_cipher,
921 NULL /* cleanup */, NULL /* ctrl */};
922
923static const EVP_CIPHER aesni_192_gcm = {
924 NID_aes_192_gcm, 1 /* block_size */, 24 /* key_size */, 12 /* iv_len */,
925 sizeof(EVP_AES_GCM_CTX),
926 EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
927 EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT |
928 EVP_CIPH_FLAG_AEAD_CIPHER,
929 NULL /* app_data */, aesni_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
930 aes_gcm_ctrl};
931
932
Adam Langleyd9e397b2015-01-22 14:27:53 -0800933static const EVP_CIPHER aesni_256_cbc = {
Adam Langleye9ada862015-05-11 17:20:37 -0700934 NID_aes_256_cbc, 16 /* block_size */, 32 /* key_size */,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800935 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CBC_MODE,
936 NULL /* app_data */, aesni_init_key, aesni_cbc_cipher,
937 NULL /* cleanup */, NULL /* ctrl */};
938
939static const EVP_CIPHER aesni_256_ctr = {
Adam Langleye9ada862015-05-11 17:20:37 -0700940 NID_aes_256_ctr, 1 /* block_size */, 32 /* key_size */,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800941 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_CTR_MODE,
942 NULL /* app_data */, aesni_init_key, aes_ctr_cipher,
943 NULL /* cleanup */, NULL /* ctrl */};
944
945static const EVP_CIPHER aesni_256_ecb = {
Adam Langleye9ada862015-05-11 17:20:37 -0700946 NID_aes_256_ecb, 16 /* block_size */, 32 /* key_size */,
Adam Langleyd9e397b2015-01-22 14:27:53 -0800947 0 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_ECB_MODE,
948 NULL /* app_data */, aesni_init_key, aesni_ecb_cipher,
949 NULL /* cleanup */, NULL /* ctrl */};
950
Adam Langleye9ada862015-05-11 17:20:37 -0700951static const EVP_CIPHER aesni_256_ofb = {
952 NID_aes_256_ofb128, 1 /* block_size */, 32 /* key_size */,
953 16 /* iv_len */, sizeof(EVP_AES_KEY), EVP_CIPH_OFB_MODE,
954 NULL /* app_data */, aesni_init_key, aes_ofb_cipher,
955 NULL /* cleanup */, NULL /* ctrl */};
956
Adam Langleyd9e397b2015-01-22 14:27:53 -0800957static const EVP_CIPHER aesni_256_gcm = {
958 NID_aes_256_gcm, 1 /* block_size */, 32 /* key_size */, 12 /* iv_len */,
959 sizeof(EVP_AES_GCM_CTX),
960 EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER |
961 EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY |
962 EVP_CIPH_FLAG_AEAD_CIPHER,
963 NULL /* app_data */, aesni_gcm_init_key, aes_gcm_cipher, aes_gcm_cleanup,
964 aes_gcm_ctrl};
965
966#define EVP_CIPHER_FUNCTION(keybits, mode) \
967 const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \
968 if (aesni_capable()) { \
969 return &aesni_##keybits##_##mode; \
970 } else { \
971 return &aes_##keybits##_##mode; \
972 } \
973 }
974
975#else /* ^^^ OPENSSL_X86_64 || OPENSSL_X86 */
976
977static char aesni_capable(void) {
978 return 0;
979}
980
981#define EVP_CIPHER_FUNCTION(keybits, mode) \
982 const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \
983 return &aes_##keybits##_##mode; \
984 }
985
986#endif
987
988EVP_CIPHER_FUNCTION(128, cbc)
989EVP_CIPHER_FUNCTION(128, ctr)
990EVP_CIPHER_FUNCTION(128, ecb)
Adam Langleye9ada862015-05-11 17:20:37 -0700991EVP_CIPHER_FUNCTION(128, ofb)
Adam Langleyd9e397b2015-01-22 14:27:53 -0800992EVP_CIPHER_FUNCTION(128, gcm)
993
Adam Langley13d393e2015-04-08 11:18:53 -0700994EVP_CIPHER_FUNCTION(192, cbc)
995EVP_CIPHER_FUNCTION(192, ctr)
996EVP_CIPHER_FUNCTION(192, ecb)
997EVP_CIPHER_FUNCTION(192, gcm)
998
Adam Langleyd9e397b2015-01-22 14:27:53 -0800999EVP_CIPHER_FUNCTION(256, cbc)
1000EVP_CIPHER_FUNCTION(256, ctr)
1001EVP_CIPHER_FUNCTION(256, ecb)
Adam Langleye9ada862015-05-11 17:20:37 -07001002EVP_CIPHER_FUNCTION(256, ofb)
Adam Langleyd9e397b2015-01-22 14:27:53 -08001003EVP_CIPHER_FUNCTION(256, gcm)
1004
1005
1006#define EVP_AEAD_AES_GCM_TAG_LEN 16
1007
1008struct aead_aes_gcm_ctx {
1009 union {
1010 double align;
1011 AES_KEY ks;
1012 } ks;
1013 GCM128_CONTEXT gcm;
1014 ctr128_f ctr;
1015 uint8_t tag_len;
1016};
1017
1018static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
1019 size_t key_len, size_t tag_len) {
1020 struct aead_aes_gcm_ctx *gcm_ctx;
1021 const size_t key_bits = key_len * 8;
1022
1023 if (key_bits != 128 && key_bits != 256) {
Kenny Rootb8494592015-09-25 02:29:14 +00001024 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001025 return 0; /* EVP_AEAD_CTX_init should catch this. */
1026 }
1027
1028 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
1029 tag_len = EVP_AEAD_AES_GCM_TAG_LEN;
1030 }
1031
1032 if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) {
Kenny Rootb8494592015-09-25 02:29:14 +00001033 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001034 return 0;
1035 }
1036
1037 gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_ctx));
1038 if (gcm_ctx == NULL) {
1039 return 0;
1040 }
1041
Adam Langleye9ada862015-05-11 17:20:37 -07001042 gcm_ctx->ctr =
1043 aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, NULL, key, key_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001044 gcm_ctx->tag_len = tag_len;
1045 ctx->aead_state = gcm_ctx;
1046
1047 return 1;
1048}
1049
1050static void aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx) {
1051 struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1052 OPENSSL_cleanse(gcm_ctx, sizeof(struct aead_aes_gcm_ctx));
1053 OPENSSL_free(gcm_ctx);
1054}
1055
1056static int aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
1057 size_t *out_len, size_t max_out_len,
1058 const uint8_t *nonce, size_t nonce_len,
1059 const uint8_t *in, size_t in_len,
1060 const uint8_t *ad, size_t ad_len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001061 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1062 GCM128_CONTEXT gcm;
1063
1064 if (in_len + gcm_ctx->tag_len < in_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001065 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001066 return 0;
1067 }
1068
1069 if (max_out_len < in_len + gcm_ctx->tag_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001070 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001071 return 0;
1072 }
1073
Kenny Roote99801b2015-11-06 15:31:15 -08001074 const AES_KEY *key = &gcm_ctx->ks.ks;
1075
Robert Sloan69939df2017-01-09 10:53:07 -08001076 OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
Kenny Roote99801b2015-11-06 15:31:15 -08001077 CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001078
1079 if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
1080 return 0;
1081 }
1082
1083 if (gcm_ctx->ctr) {
Kenny Roote99801b2015-11-06 15:31:15 -08001084 if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len,
Adam Langleyd9e397b2015-01-22 14:27:53 -08001085 gcm_ctx->ctr)) {
1086 return 0;
1087 }
1088 } else {
Kenny Roote99801b2015-11-06 15:31:15 -08001089 if (!CRYPTO_gcm128_encrypt(&gcm, key, in, out, in_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001090 return 0;
1091 }
1092 }
1093
1094 CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
1095 *out_len = in_len + gcm_ctx->tag_len;
1096 return 1;
1097}
1098
1099static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
1100 size_t *out_len, size_t max_out_len,
1101 const uint8_t *nonce, size_t nonce_len,
1102 const uint8_t *in, size_t in_len,
1103 const uint8_t *ad, size_t ad_len) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001104 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1105 uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN];
1106 size_t plaintext_len;
1107 GCM128_CONTEXT gcm;
1108
1109 if (in_len < gcm_ctx->tag_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001110 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001111 return 0;
1112 }
1113
1114 plaintext_len = in_len - gcm_ctx->tag_len;
1115
1116 if (max_out_len < plaintext_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001117 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001118 return 0;
1119 }
1120
Kenny Roote99801b2015-11-06 15:31:15 -08001121 const AES_KEY *key = &gcm_ctx->ks.ks;
1122
Robert Sloan69939df2017-01-09 10:53:07 -08001123 OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
Kenny Roote99801b2015-11-06 15:31:15 -08001124 CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001125
1126 if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) {
1127 return 0;
1128 }
1129
1130 if (gcm_ctx->ctr) {
Kenny Roote99801b2015-11-06 15:31:15 -08001131 if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out,
1132 in_len - gcm_ctx->tag_len, gcm_ctx->ctr)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001133 return 0;
1134 }
1135 } else {
Kenny Roote99801b2015-11-06 15:31:15 -08001136 if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len - gcm_ctx->tag_len)) {
Adam Langleyd9e397b2015-01-22 14:27:53 -08001137 return 0;
1138 }
1139 }
1140
1141 CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
1142 if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001143 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleyd9e397b2015-01-22 14:27:53 -08001144 return 0;
1145 }
1146
1147 *out_len = plaintext_len;
1148 return 1;
1149}
1150
1151static const EVP_AEAD aead_aes_128_gcm = {
1152 16, /* key len */
1153 12, /* nonce len */
1154 EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
1155 EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -07001156 aead_aes_gcm_init,
1157 NULL, /* init_with_direction */
1158 aead_aes_gcm_cleanup,
1159 aead_aes_gcm_seal,
1160 aead_aes_gcm_open,
Adam Langleyfad63272015-11-12 12:15:39 -08001161 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001162};
1163
1164static const EVP_AEAD aead_aes_256_gcm = {
1165 32, /* key len */
1166 12, /* nonce len */
1167 EVP_AEAD_AES_GCM_TAG_LEN, /* overhead */
1168 EVP_AEAD_AES_GCM_TAG_LEN, /* max tag length */
Adam Langleye9ada862015-05-11 17:20:37 -07001169 aead_aes_gcm_init,
1170 NULL, /* init_with_direction */
1171 aead_aes_gcm_cleanup,
1172 aead_aes_gcm_seal,
1173 aead_aes_gcm_open,
Adam Langleyfad63272015-11-12 12:15:39 -08001174 NULL, /* get_iv */
Adam Langleyd9e397b2015-01-22 14:27:53 -08001175};
1176
1177const EVP_AEAD *EVP_aead_aes_128_gcm(void) { return &aead_aes_128_gcm; }
1178
1179const EVP_AEAD *EVP_aead_aes_256_gcm(void) { return &aead_aes_256_gcm; }
1180
1181
Adam Langleye9ada862015-05-11 17:20:37 -07001182#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH
1183#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12
1184
1185struct aead_aes_ctr_hmac_sha256_ctx {
1186 union {
1187 double align;
1188 AES_KEY ks;
1189 } ks;
1190 ctr128_f ctr;
1191 block128_f block;
1192 SHA256_CTX inner_init_state;
1193 SHA256_CTX outer_init_state;
1194 uint8_t tag_len;
1195};
1196
1197static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer,
1198 const uint8_t hmac_key[32]) {
1199 static const size_t hmac_key_len = 32;
1200 uint8_t block[SHA256_CBLOCK];
Robert Sloan69939df2017-01-09 10:53:07 -08001201 OPENSSL_memcpy(block, hmac_key, hmac_key_len);
1202 OPENSSL_memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len);
Adam Langleye9ada862015-05-11 17:20:37 -07001203
1204 unsigned i;
1205 for (i = 0; i < hmac_key_len; i++) {
1206 block[i] ^= 0x36;
1207 }
1208
1209 SHA256_Init(out_inner);
1210 SHA256_Update(out_inner, block, sizeof(block));
1211
Robert Sloan69939df2017-01-09 10:53:07 -08001212 OPENSSL_memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len);
Adam Langleye9ada862015-05-11 17:20:37 -07001213 for (i = 0; i < hmac_key_len; i++) {
1214 block[i] ^= (0x36 ^ 0x5c);
1215 }
1216
1217 SHA256_Init(out_outer);
1218 SHA256_Update(out_outer, block, sizeof(block));
1219}
1220
1221static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
1222 size_t key_len, size_t tag_len) {
1223 struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx;
1224 static const size_t hmac_key_len = 32;
1225
1226 if (key_len < hmac_key_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001227 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
Adam Langleye9ada862015-05-11 17:20:37 -07001228 return 0; /* EVP_AEAD_CTX_init should catch this. */
1229 }
1230
1231 const size_t aes_key_len = key_len - hmac_key_len;
1232 if (aes_key_len != 16 && aes_key_len != 32) {
Kenny Rootb8494592015-09-25 02:29:14 +00001233 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
Adam Langleye9ada862015-05-11 17:20:37 -07001234 return 0; /* EVP_AEAD_CTX_init should catch this. */
1235 }
1236
1237 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
1238 tag_len = EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN;
1239 }
1240
1241 if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) {
Kenny Rootb8494592015-09-25 02:29:14 +00001242 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
Adam Langleye9ada862015-05-11 17:20:37 -07001243 return 0;
1244 }
1245
1246 aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
1247 if (aes_ctx == NULL) {
Kenny Rootb8494592015-09-25 02:29:14 +00001248 OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
Adam Langleye9ada862015-05-11 17:20:37 -07001249 return 0;
1250 }
1251
1252 aes_ctx->ctr =
1253 aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len);
1254 aes_ctx->tag_len = tag_len;
1255 hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state,
1256 key + aes_key_len);
1257
1258 ctx->aead_state = aes_ctx;
1259
1260 return 1;
1261}
1262
1263static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx) {
1264 struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
1265 OPENSSL_cleanse(aes_ctx, sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
1266 OPENSSL_free(aes_ctx);
1267}
1268
1269static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value) {
1270 unsigned i;
1271 uint8_t bytes[8];
1272
1273 for (i = 0; i < sizeof(bytes); i++) {
1274 bytes[i] = value & 0xff;
1275 value >>= 8;
1276 }
1277 SHA256_Update(sha256, bytes, sizeof(bytes));
1278}
1279
1280static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH],
1281 const SHA256_CTX *inner_init_state,
1282 const SHA256_CTX *outer_init_state,
1283 const uint8_t *ad, size_t ad_len,
1284 const uint8_t *nonce, const uint8_t *ciphertext,
1285 size_t ciphertext_len) {
1286 SHA256_CTX sha256;
Robert Sloan69939df2017-01-09 10:53:07 -08001287 OPENSSL_memcpy(&sha256, inner_init_state, sizeof(sha256));
Adam Langleye9ada862015-05-11 17:20:37 -07001288 hmac_update_uint64(&sha256, ad_len);
1289 hmac_update_uint64(&sha256, ciphertext_len);
1290 SHA256_Update(&sha256, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
1291 SHA256_Update(&sha256, ad, ad_len);
1292
1293 /* Pad with zeros to the end of the SHA-256 block. */
1294 const unsigned num_padding =
1295 (SHA256_CBLOCK - ((sizeof(uint64_t)*2 +
1296 EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN + ad_len) %
1297 SHA256_CBLOCK)) %
1298 SHA256_CBLOCK;
1299 uint8_t padding[SHA256_CBLOCK];
Robert Sloan69939df2017-01-09 10:53:07 -08001300 OPENSSL_memset(padding, 0, num_padding);
Adam Langleye9ada862015-05-11 17:20:37 -07001301 SHA256_Update(&sha256, padding, num_padding);
1302
1303 SHA256_Update(&sha256, ciphertext, ciphertext_len);
1304
1305 uint8_t inner_digest[SHA256_DIGEST_LENGTH];
1306 SHA256_Final(inner_digest, &sha256);
1307
Robert Sloan69939df2017-01-09 10:53:07 -08001308 OPENSSL_memcpy(&sha256, outer_init_state, sizeof(sha256));
Adam Langleye9ada862015-05-11 17:20:37 -07001309 SHA256_Update(&sha256, inner_digest, sizeof(inner_digest));
1310 SHA256_Final(out, &sha256);
1311}
1312
1313static void aead_aes_ctr_hmac_sha256_crypt(
1314 const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out,
1315 const uint8_t *in, size_t len, const uint8_t *nonce) {
1316 /* Since the AEAD operation is one-shot, keeping a buffer of unused keystream
1317 * bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it. */
1318 uint8_t partial_block_buffer[AES_BLOCK_SIZE];
1319 unsigned partial_block_offset = 0;
Robert Sloan69939df2017-01-09 10:53:07 -08001320 OPENSSL_memset(partial_block_buffer, 0, sizeof(partial_block_buffer));
Adam Langleye9ada862015-05-11 17:20:37 -07001321
1322 uint8_t counter[AES_BLOCK_SIZE];
Robert Sloan69939df2017-01-09 10:53:07 -08001323 OPENSSL_memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN);
1324 OPENSSL_memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4);
Adam Langleye9ada862015-05-11 17:20:37 -07001325
1326 if (aes_ctx->ctr) {
1327 CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter,
1328 partial_block_buffer, &partial_block_offset,
1329 aes_ctx->ctr);
1330 } else {
1331 CRYPTO_ctr128_encrypt(in, out, len, &aes_ctx->ks.ks, counter,
1332 partial_block_buffer, &partial_block_offset,
1333 aes_ctx->block);
1334 }
1335}
1336
1337static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
1338 size_t *out_len, size_t max_out_len,
1339 const uint8_t *nonce, size_t nonce_len,
1340 const uint8_t *in, size_t in_len,
1341 const uint8_t *ad, size_t ad_len) {
1342 const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
1343 const uint64_t in_len_64 = in_len;
1344
1345 if (in_len + aes_ctx->tag_len < in_len ||
1346 /* This input is so large it would overflow the 32-bit block counter. */
Adam Langley4139edb2016-01-13 15:00:54 -08001347 in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) {
Kenny Rootb8494592015-09-25 02:29:14 +00001348 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
Adam Langleye9ada862015-05-11 17:20:37 -07001349 return 0;
1350 }
1351
1352 if (max_out_len < in_len + aes_ctx->tag_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001353 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
Adam Langleye9ada862015-05-11 17:20:37 -07001354 return 0;
1355 }
1356
1357 if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
Kenny Rootb8494592015-09-25 02:29:14 +00001358 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
Adam Langleye9ada862015-05-11 17:20:37 -07001359 return 0;
1360 }
1361
1362 aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce);
1363
1364 uint8_t hmac_result[SHA256_DIGEST_LENGTH];
1365 hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
1366 &aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len);
Robert Sloan69939df2017-01-09 10:53:07 -08001367 OPENSSL_memcpy(out + in_len, hmac_result, aes_ctx->tag_len);
Adam Langleye9ada862015-05-11 17:20:37 -07001368 *out_len = in_len + aes_ctx->tag_len;
1369
1370 return 1;
1371}
1372
1373static int aead_aes_ctr_hmac_sha256_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
1374 size_t *out_len, size_t max_out_len,
1375 const uint8_t *nonce, size_t nonce_len,
1376 const uint8_t *in, size_t in_len,
1377 const uint8_t *ad, size_t ad_len) {
1378 const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state;
1379 size_t plaintext_len;
1380
1381 if (in_len < aes_ctx->tag_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001382 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleye9ada862015-05-11 17:20:37 -07001383 return 0;
1384 }
1385
1386 plaintext_len = in_len - aes_ctx->tag_len;
1387
1388 if (max_out_len < plaintext_len) {
Kenny Rootb8494592015-09-25 02:29:14 +00001389 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
Adam Langleye9ada862015-05-11 17:20:37 -07001390 return 0;
1391 }
1392
1393 if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
Kenny Rootb8494592015-09-25 02:29:14 +00001394 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
Adam Langleye9ada862015-05-11 17:20:37 -07001395 return 0;
1396 }
1397
1398 uint8_t hmac_result[SHA256_DIGEST_LENGTH];
1399 hmac_calculate(hmac_result, &aes_ctx->inner_init_state,
1400 &aes_ctx->outer_init_state, ad, ad_len, nonce, in,
1401 plaintext_len);
1402 if (CRYPTO_memcmp(hmac_result, in + plaintext_len, aes_ctx->tag_len) != 0) {
Kenny Rootb8494592015-09-25 02:29:14 +00001403 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
Adam Langleye9ada862015-05-11 17:20:37 -07001404 return 0;
1405 }
1406
1407 aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, plaintext_len, nonce);
1408
1409 *out_len = plaintext_len;
1410 return 1;
1411}
1412
1413static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = {
1414 16 /* AES key */ + 32 /* HMAC key */,
1415 12, /* nonce length */
1416 EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* overhead */
1417 EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* max tag length */
1418
1419 aead_aes_ctr_hmac_sha256_init,
1420 NULL /* init_with_direction */,
1421 aead_aes_ctr_hmac_sha256_cleanup,
1422 aead_aes_ctr_hmac_sha256_seal,
1423 aead_aes_ctr_hmac_sha256_open,
Adam Langleyfad63272015-11-12 12:15:39 -08001424 NULL /* get_iv */,
Adam Langleye9ada862015-05-11 17:20:37 -07001425};
1426
1427static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = {
1428 32 /* AES key */ + 32 /* HMAC key */,
1429 12, /* nonce length */
1430 EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* overhead */
1431 EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, /* max tag length */
1432
1433 aead_aes_ctr_hmac_sha256_init,
1434 NULL /* init_with_direction */,
1435 aead_aes_ctr_hmac_sha256_cleanup,
1436 aead_aes_ctr_hmac_sha256_seal,
1437 aead_aes_ctr_hmac_sha256_open,
Adam Langleyfad63272015-11-12 12:15:39 -08001438 NULL /* get_iv */,
Adam Langleye9ada862015-05-11 17:20:37 -07001439};
1440
1441const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) {
1442 return &aead_aes_128_ctr_hmac_sha256;
1443}
1444
1445const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void) {
1446 return &aead_aes_256_ctr_hmac_sha256;
1447}
1448
David Benjamin1b249672016-12-06 18:25:50 -05001449#if !defined(OPENSSL_SMALL)
1450
1451#define EVP_AEAD_AES_GCM_SIV_TAG_LEN 16
1452
1453struct aead_aes_gcm_siv_ctx {
1454 union {
1455 double align;
1456 AES_KEY ks;
1457 } ks;
1458 block128_f kgk_block;
1459 unsigned is_256:1;
1460};
1461
1462static int aead_aes_gcm_siv_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
1463 size_t key_len, size_t tag_len) {
1464 const size_t key_bits = key_len * 8;
1465
1466 if (key_bits != 128 && key_bits != 256) {
1467 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
1468 return 0; /* EVP_AEAD_CTX_init should catch this. */
1469 }
1470
1471 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) {
1472 tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN;
1473 }
1474
1475 if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
1476 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
1477 return 0;
1478 }
1479
1480 struct aead_aes_gcm_siv_ctx *gcm_siv_ctx =
1481 OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_ctx));
1482 if (gcm_siv_ctx == NULL) {
1483 return 0;
1484 }
Robert Sloan69939df2017-01-09 10:53:07 -08001485 OPENSSL_memset(gcm_siv_ctx, 0, sizeof(struct aead_aes_gcm_siv_ctx));
David Benjamin1b249672016-12-06 18:25:50 -05001486
1487 if (aesni_capable()) {
1488 aesni_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
1489 gcm_siv_ctx->kgk_block = (block128_f)aesni_encrypt;
1490 } else if (hwaes_capable()) {
1491 aes_hw_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
1492 gcm_siv_ctx->kgk_block = (block128_f)aes_hw_encrypt;
1493 } else if (vpaes_capable()) {
1494 vpaes_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
1495 gcm_siv_ctx->kgk_block = (block128_f)vpaes_encrypt;
1496 } else {
1497 AES_set_encrypt_key(key, key_len * 8, &gcm_siv_ctx->ks.ks);
1498 gcm_siv_ctx->kgk_block = (block128_f)AES_encrypt;
1499 }
1500
1501 gcm_siv_ctx->is_256 = (key_len == 32);
1502 ctx->aead_state = gcm_siv_ctx;
1503
1504 return 1;
1505}
1506
1507static void aead_aes_gcm_siv_cleanup(EVP_AEAD_CTX *ctx) {
1508 struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state;
1509 OPENSSL_cleanse(gcm_siv_ctx, sizeof(struct aead_aes_gcm_siv_ctx));
1510 OPENSSL_free(gcm_siv_ctx);
1511}
1512
1513/* gcm_siv_crypt encrypts (or decrypts—it's the same thing) |in_len| bytes from
1514 * |in| to |out|, using the block function |enc_block| with |key| in counter
1515 * mode, starting at |initial_counter|. This differs from the traditional
1516 * counter mode code in that the counter is handled little-endian, only the
1517 * first four bytes are used and the GCM-SIV tweak to the final byte is
1518 * applied. The |in| and |out| pointers may be equal but otherwise must not
1519 * alias. */
1520static void gcm_siv_crypt(uint8_t *out, const uint8_t *in, size_t in_len,
1521 const uint8_t initial_counter[AES_BLOCK_SIZE],
1522 block128_f enc_block, const AES_KEY *key) {
1523 union {
1524 uint32_t w[4];
1525 uint8_t c[16];
1526 } counter;
1527
Robert Sloan69939df2017-01-09 10:53:07 -08001528 OPENSSL_memcpy(counter.c, initial_counter, AES_BLOCK_SIZE);
David Benjamin1b249672016-12-06 18:25:50 -05001529 counter.c[15] |= 0x80;
1530
1531 for (size_t done = 0; done < in_len;) {
1532 uint8_t keystream[AES_BLOCK_SIZE];
1533 enc_block(counter.c, keystream, key);
1534 counter.w[0]++;
1535
1536 size_t todo = AES_BLOCK_SIZE;
1537 if (in_len - done < todo) {
1538 todo = in_len - done;
1539 }
1540
1541 for (size_t i = 0; i < todo; i++) {
1542 out[done + i] = keystream[i] ^ in[done + i];
1543 }
1544
1545 done += todo;
1546 }
1547}
1548
1549/* gcm_siv_polyval evaluates POLYVAL at |auth_key| on the given plaintext and
1550 * AD. The result is written to |out_tag|. */
1551static void gcm_siv_polyval(uint8_t out_tag[16], const uint8_t *in,
1552 size_t in_len, const uint8_t *ad, size_t ad_len,
1553 const uint8_t auth_key[16]) {
1554 struct polyval_ctx polyval_ctx;
1555 CRYPTO_POLYVAL_init(&polyval_ctx, auth_key);
1556
1557 CRYPTO_POLYVAL_update_blocks(&polyval_ctx, ad, ad_len & ~15);
1558
1559 uint8_t scratch[16];
1560 if (ad_len & 15) {
Robert Sloan69939df2017-01-09 10:53:07 -08001561 OPENSSL_memset(scratch, 0, sizeof(scratch));
1562 OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15);
David Benjamin1b249672016-12-06 18:25:50 -05001563 CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch));
1564 }
1565
1566 CRYPTO_POLYVAL_update_blocks(&polyval_ctx, in, in_len & ~15);
1567 if (in_len & 15) {
Robert Sloan69939df2017-01-09 10:53:07 -08001568 OPENSSL_memset(scratch, 0, sizeof(scratch));
1569 OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15);
David Benjamin1b249672016-12-06 18:25:50 -05001570 CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch));
1571 }
1572
1573 union {
1574 uint8_t c[16];
1575 struct {
1576 uint64_t ad;
1577 uint64_t in;
1578 } bitlens;
1579 } length_block;
1580
1581 length_block.bitlens.ad = ad_len * 8;
1582 length_block.bitlens.in = in_len * 8;
1583 CRYPTO_POLYVAL_update_blocks(&polyval_ctx, length_block.c,
1584 sizeof(length_block));
1585
1586 CRYPTO_POLYVAL_finish(&polyval_ctx, out_tag);
1587 out_tag[15] &= 0x7f;
1588}
1589
1590/* gcm_siv_record_keys contains the keys used for a specific GCM-SIV record. */
1591struct gcm_siv_record_keys {
1592 uint8_t auth_key[16];
1593 union {
1594 double align;
1595 AES_KEY ks;
1596 } enc_key;
1597 block128_f enc_block;
1598};
1599
1600/* gcm_siv_keys calculates the keys for a specific GCM-SIV record with the
1601 * given nonce and writes them to |*out_keys|. */
1602static void gcm_siv_keys(
1603 const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx,
1604 struct gcm_siv_record_keys *out_keys,
1605 const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_TAG_LEN]) {
1606 const AES_KEY *const key = &gcm_siv_ctx->ks.ks;
1607 gcm_siv_ctx->kgk_block(nonce, out_keys->auth_key, key);
1608
1609 if (gcm_siv_ctx->is_256) {
1610 uint8_t record_enc_key[32];
1611 gcm_siv_ctx->kgk_block(out_keys->auth_key, record_enc_key + 16, key);
1612 gcm_siv_ctx->kgk_block(record_enc_key + 16, record_enc_key, key);
1613 aes_ctr_set_key(&out_keys->enc_key.ks, NULL, &out_keys->enc_block,
1614 record_enc_key, sizeof(record_enc_key));
1615 } else {
1616 uint8_t record_enc_key[16];
1617 gcm_siv_ctx->kgk_block(out_keys->auth_key, record_enc_key, key);
1618 aes_ctr_set_key(&out_keys->enc_key.ks, NULL, &out_keys->enc_block,
1619 record_enc_key, sizeof(record_enc_key));
1620 }
1621}
1622
1623static int aead_aes_gcm_siv_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
1624 size_t *out_len, size_t max_out_len,
1625 const uint8_t *nonce, size_t nonce_len,
1626 const uint8_t *in, size_t in_len,
1627 const uint8_t *ad, size_t ad_len) {
1628 const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state;
1629 const uint64_t in_len_64 = in_len;
1630 const uint64_t ad_len_64 = ad_len;
1631
1632 if (in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN < in_len ||
1633 in_len_64 > (UINT64_C(1) << 36) ||
1634 ad_len_64 >= (UINT64_C(1) << 61)) {
1635 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
1636 return 0;
1637 }
1638
1639 if (max_out_len < in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN) {
1640 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
1641 return 0;
1642 }
1643
1644 if (nonce_len != AES_BLOCK_SIZE) {
1645 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
1646 return 0;
1647 }
1648
1649 struct gcm_siv_record_keys keys;
1650 gcm_siv_keys(gcm_siv_ctx, &keys, nonce);
1651
1652 uint8_t tag[16];
1653 gcm_siv_polyval(tag, in, in_len, ad, ad_len, keys.auth_key);
1654 keys.enc_block(tag, tag, &keys.enc_key.ks);
1655
1656 gcm_siv_crypt(out, in, in_len, tag, keys.enc_block, &keys.enc_key.ks);
1657
Robert Sloan69939df2017-01-09 10:53:07 -08001658 OPENSSL_memcpy(&out[in_len], tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN);
David Benjamin1b249672016-12-06 18:25:50 -05001659 *out_len = in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN;
1660
1661 return 1;
1662}
1663
1664static int aead_aes_gcm_siv_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
1665 size_t *out_len, size_t max_out_len,
1666 const uint8_t *nonce, size_t nonce_len,
1667 const uint8_t *in, size_t in_len,
1668 const uint8_t *ad, size_t ad_len) {
1669 const uint64_t ad_len_64 = ad_len;
1670 if (ad_len_64 >= (UINT64_C(1) << 61)) {
1671 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
1672 return 0;
1673 }
1674
1675 const uint64_t in_len_64 = in_len;
1676 if (in_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN ||
1677 in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) {
1678 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
1679 return 0;
1680 }
1681
1682 const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state;
1683 const size_t plaintext_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN;
1684
1685 if (max_out_len < plaintext_len) {
1686 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
1687 return 0;
1688 }
1689
1690 struct gcm_siv_record_keys keys;
1691 gcm_siv_keys(gcm_siv_ctx, &keys, nonce);
1692
1693 gcm_siv_crypt(out, in, plaintext_len, &in[plaintext_len], keys.enc_block,
1694 &keys.enc_key.ks);
1695
1696 uint8_t expected_tag[EVP_AEAD_AES_GCM_SIV_TAG_LEN];
1697 gcm_siv_polyval(expected_tag, out, plaintext_len, ad, ad_len, keys.auth_key);
1698 keys.enc_block(expected_tag, expected_tag, &keys.enc_key.ks);
1699
1700 if (CRYPTO_memcmp(expected_tag, &in[plaintext_len], sizeof(expected_tag)) !=
1701 0) {
1702 OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
1703 return 0;
1704 }
1705
1706 *out_len = plaintext_len;
1707 return 1;
1708}
1709
1710static const EVP_AEAD aead_aes_128_gcm_siv = {
1711 16, /* key length */
1712 AES_BLOCK_SIZE, /* nonce length */
1713 EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* overhead */
1714 EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* max tag length */
1715
1716 aead_aes_gcm_siv_init,
1717 NULL /* init_with_direction */,
1718 aead_aes_gcm_siv_cleanup,
1719 aead_aes_gcm_siv_seal,
1720 aead_aes_gcm_siv_open,
1721 NULL /* get_iv */,
1722};
1723
1724static const EVP_AEAD aead_aes_256_gcm_siv = {
1725 32, /* key length */
1726 AES_BLOCK_SIZE, /* nonce length */
1727 EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* overhead */
1728 EVP_AEAD_AES_GCM_SIV_TAG_LEN, /* max tag length */
1729
1730 aead_aes_gcm_siv_init,
1731 NULL /* init_with_direction */,
1732 aead_aes_gcm_siv_cleanup,
1733 aead_aes_gcm_siv_seal,
1734 aead_aes_gcm_siv_open,
1735 NULL /* get_iv */,
1736};
1737
1738const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) {
1739 return &aead_aes_128_gcm_siv;
1740}
1741
1742const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) {
1743 return &aead_aes_256_gcm_siv;
1744}
1745
1746#endif /* !OPENSSL_SMALL */
1747
Adam Langleyd9e397b2015-01-22 14:27:53 -08001748int EVP_has_aes_hardware(void) {
1749#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64)
1750 return aesni_capable() && crypto_gcm_clmul_enabled();
1751#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
Kenny Roote99801b2015-11-06 15:31:15 -08001752 return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable();
Adam Langleyd9e397b2015-01-22 14:27:53 -08001753#else
1754 return 0;
1755#endif
1756}