Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Side by Side Diff: openssl/patches/aead_support.patch

Issue 2072073002: Delete bundled copy of OpenSSL and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/openssl@master
Patch Set: Delete bundled copy of OpenSSL and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « openssl/patches/aead_ssl_support.patch ('k') | openssl/patches/chacha20poly1305.patch » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 From 98f0c6e114f55b4451bea824b05ab29db3351f12 Mon Sep 17 00:00:00 2001
2 From: Adam Langley <agl@chromium.org>
3 Date: Thu, 25 Jul 2013 16:52:35 -0400
4 Subject: [PATCH 40/50] aead_support
5
6 This change adds an AEAD interface to EVP and an AES-GCM implementation
7 suitable for use in TLS.
8 ---
9 crypto/evp/Makefile | 4 +-
10 crypto/evp/e_aes.c | 214 +++++++++++++++++++++++++++++++++++----
11 crypto/evp/evp.h | 111 ++++++++++++++++++++
12 crypto/evp/evp_aead.c | 192 +++++++++++++++++++++++++++++++++++
13 crypto/evp/evp_err.c | 8 ++
14 crypto/evp/evp_locl.h | 24 +++++
15 doc/crypto/EVP_AEAD_CTX_init.pod | 96 ++++++++++++++++++
16 7 files changed, 626 insertions(+), 23 deletions(-)
17 create mode 100644 crypto/evp/evp_aead.c
18 create mode 100644 doc/crypto/EVP_AEAD_CTX_init.pod
19
20 diff --git a/crypto/evp/Makefile b/crypto/evp/Makefile
21 index 1e46ceb..b73038d 100644
22 --- a/crypto/evp/Makefile
23 +++ b/crypto/evp/Makefile
24 @@ -29,7 +29,7 @@ LIBSRC= encode.c digest.c evp_enc.c evp_key.c evp_acnf.c evp_c nf.c \
25 c_all.c c_allc.c c_alld.c evp_lib.c bio_ok.c \
26 evp_pkey.c evp_pbe.c p5_crpt.c p5_crpt2.c \
27 e_old.c pmeth_lib.c pmeth_fn.c pmeth_gn.c m_sigver.c evp_fips.c \
28 - e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c
29 + e_aes_cbc_hmac_sha1.c e_rc4_hmac_md5.c evp_aead.c
30
31 LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \
32 e_des.o e_bf.o e_idea.o e_des3.o e_camellia.o\
33 @@ -42,7 +42,7 @@ LIBOBJ= encode.o digest.o evp_enc.o evp_key.o evp_acnf.o evp_cnf.o \
34 c_all.o c_allc.o c_alld.o evp_lib.o bio_ok.o \
35 evp_pkey.o evp_pbe.o p5_crpt.o p5_crpt2.o \
36 e_old.o pmeth_lib.o pmeth_fn.o pmeth_gn.o m_sigver.o evp_fips.o \
37 - e_aes_cbc_hmac_sha1.o e_rc4_hmac_md5.o
38 + e_aes_cbc_hmac_sha1.o e_rc4_hmac_md5.o evp_aead.o
39
40 SRC= $(LIBSRC)
41
42 diff --git a/crypto/evp/e_aes.c b/crypto/evp/e_aes.c
43 index ef44f63..e4485e4 100644
44 --- a/crypto/evp/e_aes.c
45 +++ b/crypto/evp/e_aes.c
46 @@ -814,44 +814,45 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int a rg, void *ptr)
47 }
48 }
49
50 -static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
51 - const unsigned char *iv, int enc)
52 +static ctr128_f aes_gcm_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx,
53 + const unsigned char *key, size_t key_len)
54 {
55 - EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
56 - if (!iv && !key)
57 - return 1;
58 - if (key)
59 - { do {
60 #ifdef BSAES_CAPABLE
61 if (BSAES_CAPABLE)
62 {
63 - AES_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
64 - CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
65 + AES_set_encrypt_key(key,key_len*8,aes_key);
66 + CRYPTO_gcm128_init(gcm_ctx,aes_key,
67 (block128_f)AES_encrypt);
68 - gctx->ctr = (ctr128_f)bsaes_ctr32_encrypt_blocks;
69 - break;
70 + return (ctr128_f)bsaes_ctr32_encrypt_blocks;
71 }
72 - else
73 #endif
74 #ifdef VPAES_CAPABLE
75 if (VPAES_CAPABLE)
76 {
77 - vpaes_set_encrypt_key(key,ctx->key_len*8,&gctx->ks);
78 - CRYPTO_gcm128_init(&gctx->gcm,&gctx->ks,
79 + vpaes_set_encrypt_key(key,key_len*8,aes_key);
80 + CRYPTO_gcm128_init(gcm_ctx,aes_key,
81 (block128_f)vpaes_encrypt);
82 - gctx->ctr = NULL;
83 - break;
84 + return NULL;
85 }
86 #endif
87 - AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks);
88 - CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f)AES_encryp t);
89 + AES_set_encrypt_key(key, key_len*8, aes_key);
90 + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt);
91 #ifdef AES_CTR_ASM
92 - gctx->ctr = (ctr128_f)AES_ctr32_encrypt;
93 + return (ctr128_f)AES_ctr32_encrypt;
94 #else
95 - gctx->ctr = NULL;
96 + return NULL;
97 #endif
98 - } while (0);
99 + }
100
101 +static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
102 + const unsigned char *iv, int enc)
103 + {
104 + EVP_AES_GCM_CTX *gctx = ctx->cipher_data;
105 + if (!iv && !key)
106 + return 1;
107 + if (key)
108 + {
109 + gctx->ctr = aes_gcm_set_key(&gctx->ks, &gctx->gcm, key, ctx->key _len);
110 /* If we have an iv can set it directly, otherwise use
111 * saved IV.
112 */
113 @@ -1310,5 +1311,176 @@ BLOCK_CIPHER_custom(NID_aes,128,1,12,ccm,CCM,EVP_CIPH_FL AG_FIPS|CUSTOM_FLAGS)
114 BLOCK_CIPHER_custom(NID_aes,192,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
115 BLOCK_CIPHER_custom(NID_aes,256,1,12,ccm,CCM,EVP_CIPH_FLAG_FIPS|CUSTOM_FLAGS)
116
117 +#define EVP_AEAD_AES_128_GCM_TAG_LEN 16
118 +
119 +struct aead_aes_128_gcm_ctx {
120 + union { double align; AES_KEY ks; } ks;
121 + GCM128_CONTEXT gcm;
122 + ctr128_f ctr;
123 + unsigned char tag_len;
124 +};
125 +
126 +static int aead_aes_128_gcm_init(EVP_AEAD_CTX *ctx,
127 + const unsigned char *key, size_t key_len, size_t tag_len)
128 + {
129 + struct aead_aes_128_gcm_ctx *gcm_ctx;
130 +
131 + if (key_len*8 != 128)
132 + {
133 + EVPerr(EVP_F_AEAD_AES_128_GCM_INIT, EVP_R_BAD_KEY_LENGTH);
134 + return 0; /* EVP_AEAD_CTX_init should catch this. */
135 + }
136 +
137 + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
138 + tag_len = EVP_AEAD_AES_128_GCM_TAG_LEN;
139 +
140 + if (tag_len > EVP_AEAD_AES_128_GCM_TAG_LEN)
141 + {
142 + EVPerr(EVP_F_AEAD_AES_128_GCM_INIT, EVP_R_TAG_TOO_LARGE);
143 + return 0;
144 + }
145 +
146 + gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_128_gcm_ctx));
147 + if (gcm_ctx == NULL)
148 + return 0;
149 +
150 +#ifdef AESNI_CAPABLE
151 + if (AESNI_CAPABLE)
152 + {
153 + aesni_set_encrypt_key(key, key_len * 8, &gcm_ctx->ks.ks);
154 + CRYPTO_gcm128_init(&gcm_ctx->gcm, &gcm_ctx->ks.ks,
155 + (block128_f)aesni_encrypt);
156 + gcm_ctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks;
157 + }
158 + else
159 +#endif
160 + {
161 + gcm_ctx->ctr = aes_gcm_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm,
162 + key, key_len);
163 + }
164 + gcm_ctx->tag_len = tag_len;
165 + ctx->aead_state = gcm_ctx;
166 +
167 + return 1;
168 + }
169 +
170 +static void aead_aes_128_gcm_cleanup(EVP_AEAD_CTX *ctx)
171 + {
172 + struct aead_aes_128_gcm_ctx *gcm_ctx = ctx->aead_state;
173 + OPENSSL_free(gcm_ctx);
174 + }
175 +
176 +static ssize_t aead_aes_128_gcm_seal(const EVP_AEAD_CTX *ctx,
177 + unsigned char *out, size_t max_out_len,
178 + const unsigned char *nonce, size_t nonce_len,
179 + const unsigned char *in, size_t in_len,
180 + const unsigned char *ad, size_t ad_len)
181 + {
182 + size_t bulk = 0;
183 + const struct aead_aes_128_gcm_ctx *gcm_ctx = ctx->aead_state;
184 + GCM128_CONTEXT gcm;
185 +
186 + if (max_out_len < in_len + gcm_ctx->tag_len)
187 + {
188 + EVPerr(EVP_F_AEAD_AES_128_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL);
189 + return -1;
190 + }
191 +
192 + memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
193 + CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
194 +
195 + if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len))
196 + return -1;
197 +
198 + if (gcm_ctx->ctr)
199 + {
200 + if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk,
201 + in_len - bulk, gcm_ctx->ctr))
202 + return -1;
203 + }
204 + else
205 + {
206 + if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk,
207 + in_len - bulk))
208 + return -1;
209 + }
210 +
211 + CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
212 + return in_len + gcm_ctx->tag_len;
213 + }
214 +
215 +static ssize_t aead_aes_128_gcm_open(const EVP_AEAD_CTX *ctx,
216 + unsigned char *out, size_t max_out_len,
217 + const unsigned char *nonce, size_t nonce_len,
218 + const unsigned char *in, size_t in_len,
219 + const unsigned char *ad, size_t ad_len)
220 + {
221 + size_t bulk = 0;
222 + const struct aead_aes_128_gcm_ctx *gcm_ctx = ctx->aead_state;
223 + unsigned char tag[EVP_AEAD_AES_128_GCM_TAG_LEN];
224 + size_t out_len;
225 + GCM128_CONTEXT gcm;
226 +
227 + if (in_len < gcm_ctx->tag_len)
228 + {
229 + EVPerr(EVP_F_AEAD_AES_128_GCM_OPEN, EVP_R_BAD_DECRYPT);
230 + return -1;
231 + }
232 +
233 + out_len = in_len - gcm_ctx->tag_len;
234 +
235 + if (max_out_len < out_len)
236 + {
237 + EVPerr(EVP_F_AEAD_AES_128_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL);
238 + return -1;
239 + }
240 +
241 + memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
242 + CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
243 +
244 + if (CRYPTO_gcm128_aad(&gcm, ad, ad_len))
245 + return -1;
246 +
247 + if (gcm_ctx->ctr)
248 + {
249 + if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
250 + in_len-bulk-gcm_ctx->tag_len,
251 + gcm_ctx->ctr))
252 + return -1;
253 + }
254 + else
255 + {
256 + if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
257 + in_len - bulk - gcm_ctx->tag_len))
258 + return -1;
259 + }
260 +
261 + CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
262 + if (CRYPTO_memcmp(tag, in + out_len, gcm_ctx->tag_len) != 0)
263 + {
264 + EVPerr(EVP_F_AEAD_AES_128_GCM_OPEN, EVP_R_BAD_DECRYPT);
265 + return -1;
266 + }
267 +
268 + return out_len;
269 + }
270 +
271 +static const EVP_AEAD aead_aes_128_gcm = {
272 + 16, /* key len */
273 + 12, /* nonce len */
274 + EVP_AEAD_AES_128_GCM_TAG_LEN, /* overhead */
275 + EVP_AEAD_AES_128_GCM_TAG_LEN, /* max tag length */
276 +
277 + aead_aes_128_gcm_init,
278 + aead_aes_128_gcm_cleanup,
279 + aead_aes_128_gcm_seal,
280 + aead_aes_128_gcm_open,
281 +};
282 +
283 +const EVP_AEAD *EVP_aead_aes_128_gcm()
284 + {
285 + return &aead_aes_128_gcm;
286 + }
287 +
288 #endif
289 #endif
290 diff --git a/crypto/evp/evp.h b/crypto/evp/evp.h
291 index 5f18d4b..bd10642 100644
292 --- a/crypto/evp/evp.h
293 +++ b/crypto/evp/evp.h
294 @@ -1243,6 +1243,109 @@ void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth,
295 int (*ctrl_str)(EVP_PKEY_CTX *ctx,
296 const char *type, const char *value));
297
298 +/* Authenticated Encryption with Additional Data.
299 + *
300 + * AEAD couples confidentiality and integrity in a single primtive. AEAD
301 + * algorithms take a key and then can seal and open individual messages. Each
302 + * message has a unique, per-message nonce and, optionally, additional data
303 + * which is authenticated but not included in the output. */
304 +
305 +struct evp_aead_st;
306 +typedef struct evp_aead_st EVP_AEAD;
307 +
308 +#ifndef OPENSSL_NO_AES
309 +/* EVP_aes_128_gcm is AES-128 in Galois Counter Mode. */
310 +const EVP_AEAD *EVP_aead_aes_128_gcm(void);
311 +#endif
312 +
313 +/* EVP_AEAD_key_length returns the length, in bytes, of the keys used by
314 + * |aead|. */
315 +size_t EVP_AEAD_key_length(const EVP_AEAD *aead);
316 +
317 +/* EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce
318 + * for |aead|. */
319 +size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead);
320 +
321 +/* EVP_AEAD_max_overhead returns the maximum number of additional bytes added
322 + * by the act of sealing data with |aead|. */
323 +size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead);
324 +
325 +/* EVP_AEAD_max_tag_len returns the maximum tag length when using |aead|. This
326 + * is the largest value that can be passed as |tag_len| to
327 + * |EVP_AEAD_CTX_init|. */
328 +size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead);
329 +
330 +/* An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key
331 + * and message-independent IV. */
332 +typedef struct evp_aead_ctx_st {
333 + const EVP_AEAD *aead;
334 + /* aead_state is an opaque pointer to whatever state the AEAD needs to
335 + * maintain. */
336 + void *aead_state;
337 +} EVP_AEAD_CTX;
338 +
339 +#define EVP_AEAD_DEFAULT_TAG_LENGTH 0
340 +
341 +/* EVP_AEAD_init initializes |ctx| for the given AEAD algorithm from |impl|.
342 + * The |impl| argument may be NULL to choose the default implementation.
343 + * Authentication tags may be truncated by passing a size as |tag_len|. A
344 + * |tag_len| of zero indicates the default tag length and this is defined as
345 + * EVP_AEAD_DEFAULT_TAG_LENGTH for readability.
346 + * Returns 1 on success. Otherwise returns 0 and pushes to the error stack. */
347 +int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
348 + const unsigned char *key, size_t key_len,
349 + size_t tag_len, ENGINE *impl);
350 +
351 +/* EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. */
352 +void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
353 +
354 +/* EVP_AEAD_CTX_seal encrypts and authenticates |in_len| bytes from |in| and
355 + * authenticates |ad_len| bytes from |ad| and writes the result to |out|,
356 + * returning the number of bytes written, or -1 on error.
357 + *
358 + * This function may be called (with the same EVP_AEAD_CTX) concurrently with
359 + * itself or EVP_AEAD_CTX_open.
360 + *
361 + * At most |max_out_len| bytes are written to |out| and, in order to ensure
362 + * success, |max_out_len| should be |in_len| plus the result of
363 + * EVP_AEAD_overhead.
364 + *
365 + * The length of |nonce|, |nonce_len|, must be equal to the result of
366 + * EVP_AEAD_nonce_length for this AEAD.
367 + *
368 + * EVP_AEAD_CTX_seal never results in a partial output. If |max_out_len| is
369 + * insufficient, -1 will be returned.
370 + *
371 + * If |in| and |out| alias then |out| must be <= |in|. */
372 +ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx,
373 + unsigned char *out, size_t max_out_len,
374 + const unsigned char *nonce, size_t nonce_len,
375 + const unsigned char *in, size_t in_len,
376 + const unsigned char *ad, size_t ad_len);
377 +
378 +/* EVP_AEAD_CTX_open authenticates |in_len| bytes from |in| and |ad_len| bytes
379 + * from |ad| and decrypts at most |in_len| bytes into |out|. It returns the
380 + * number of bytes written, or -1 on error.
381 + *
382 + * This function may be called (with the same EVP_AEAD_CTX) concurrently with
383 + * itself or EVP_AEAD_CTX_seal.
384 + *
385 + * At most |in_len| bytes are written to |out|. In order to ensure success,
386 + * |max_out_len| should be at least |in_len|.
387 + *
388 + * The length of |nonce|, |nonce_len|, must be equal to the result of
389 + * EVP_AEAD_nonce_length for this AEAD.
390 + *
391 + * EVP_AEAD_CTX_open never results in a partial output. If |max_out_len| is
392 + * insufficient, -1 will be returned.
393 + *
394 + * If |in| and |out| alias then |out| must be <= |in|. */
395 +ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx,
396 + unsigned char *out, size_t max_out_len,
397 + const unsigned char *nonce, size_t nonce_len,
398 + const unsigned char *in, size_t in_len,
399 + const unsigned char *ad, size_t ad_len);
400 +
401 void EVP_add_alg_module(void);
402
403 /* BEGIN ERROR CODES */
404 @@ -1254,6 +1357,11 @@ void ERR_load_EVP_strings(void);
405 /* Error codes for the EVP functions. */
406
407 /* Function codes. */
408 +#define EVP_F_AEAD_AES_128_GCM_INIT 183
409 +#define EVP_F_AEAD_AES_128_GCM_OPEN 181
410 +#define EVP_F_AEAD_AES_128_GCM_SEAL 182
411 +#define EVP_F_AEAD_CTX_OPEN 185
412 +#define EVP_F_AEAD_CTX_SEAL 186
413 #define EVP_F_AESNI_INIT_KEY 165
414 #define EVP_F_AESNI_XTS_CIPHER 176
415 #define EVP_F_AES_INIT_KEY 133
416 @@ -1268,6 +1376,7 @@ void ERR_load_EVP_strings(void);
417 #define EVP_F_DSA_PKEY2PKCS8 135
418 #define EVP_F_ECDSA_PKEY2PKCS8 129
419 #define EVP_F_ECKEY_PKEY2PKCS8 132
420 +#define EVP_F_EVP_AEAD_CTX_INIT 180
421 #define EVP_F_EVP_CIPHERINIT_EX 123
422 #define EVP_F_EVP_CIPHER_CTX_COPY 163
423 #define EVP_F_EVP_CIPHER_CTX_CTRL 124
424 @@ -1383,10 +1492,12 @@ void ERR_load_EVP_strings(void);
425 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
426 #define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150
427 #define EVP_R_OPERATON_NOT_INITIALIZED 151
428 +#define EVP_R_OUTPUT_ALIASES_INPUT 170
429 #define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117
430 #define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
431 #define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146
432 #define EVP_R_PUBLIC_KEY_NOT_RSA 106
433 +#define EVP_R_TAG_TOO_LARGE 171
434 #define EVP_R_TOO_LARGE 164
435 #define EVP_R_UNKNOWN_CIPHER 160
436 #define EVP_R_UNKNOWN_DIGEST 161
437 diff --git a/crypto/evp/evp_aead.c b/crypto/evp/evp_aead.c
438 new file mode 100644
439 index 0000000..91da561
440 --- /dev/null
441 +++ b/crypto/evp/evp_aead.c
442 @@ -0,0 +1,192 @@
443 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
444 + * All rights reserved.
445 + *
446 + * This package is an SSL implementation written
447 + * by Eric Young (eay@cryptsoft.com).
448 + * The implementation was written so as to conform with Netscapes SSL.
449 + *
450 + * This library is free for commercial and non-commercial use as long as
451 + * the following conditions are aheared to. The following conditions
452 + * apply to all code found in this distribution, be it the RC4, RSA,
453 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
454 + * included with this distribution is covered by the same copyright terms
455 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
456 + *
457 + * Copyright remains Eric Young's, and as such any Copyright notices in
458 + * the code are not to be removed.
459 + * If this package is used in a product, Eric Young should be given attribution
460 + * as the author of the parts of the library used.
461 + * This can be in the form of a textual message at program startup or
462 + * in documentation (online or textual) provided with the package.
463 + *
464 + * Redistribution and use in source and binary forms, with or without
465 + * modification, are permitted provided that the following conditions
466 + * are met:
467 + * 1. Redistributions of source code must retain the copyright
468 + * notice, this list of conditions and the following disclaimer.
469 + * 2. Redistributions in binary form must reproduce the above copyright
470 + * notice, this list of conditions and the following disclaimer in the
471 + * documentation and/or other materials provided with the distribution.
472 + * 3. All advertising materials mentioning features or use of this software
473 + * must display the following acknowledgement:
474 + * "This product includes cryptographic software written by
475 + * Eric Young (eay@cryptsoft.com)"
476 + * The word 'cryptographic' can be left out if the rouines from the library
477 + * being used are not cryptographic related :-).
478 + * 4. If you include any Windows specific code (or a derivative thereof) from
479 + * the apps directory (application code) you must include an acknowledgement :
480 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com) "
481 + *
482 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
483 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
484 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
485 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
486 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
487 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
488 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
489 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
490 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
491 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
492 + * SUCH DAMAGE.
493 + *
494 + * The licence and distribution terms for any publically available version or
495 + * derivative of this code cannot be changed. i.e. this code cannot simply be
496 + * copied and put under another distribution licence
497 + * [including the GNU Public Licence.]
498 + */
499 +
500 +#include <limits.h>
501 +#include <string.h>
502 +
503 +#include <openssl/evp.h>
504 +#include <openssl/err.h>
505 +
506 +#include "evp_locl.h"
507 +
508 +size_t EVP_AEAD_key_length(const EVP_AEAD *aead)
509 + {
510 + return aead->key_len;
511 + }
512 +
513 +size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead)
514 + {
515 + return aead->nonce_len;
516 + }
517 +
518 +size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead)
519 + {
520 + return aead->overhead;
521 + }
522 +
523 +size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead)
524 + {
525 + return aead->max_tag_len;
526 + }
527 +
528 +int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
529 + const unsigned char *key, size_t key_len,
530 + size_t tag_len, ENGINE *impl)
531 + {
532 + ctx->aead = aead;
533 + if (key_len != aead->key_len)
534 + {
535 + EVPerr(EVP_F_EVP_AEAD_CTX_INIT,EVP_R_UNSUPPORTED_KEY_SIZE);
536 + return 0;
537 + }
538 + return aead->init(ctx, key, key_len, tag_len);
539 + }
540 +
541 +void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx)
542 + {
543 + if (ctx->aead == NULL)
544 + return;
545 + ctx->aead->cleanup(ctx);
546 + ctx->aead = NULL;
547 + }
548 +
549 +/* check_alias returns 0 if |out| points within the buffer determined by |in|
550 + * and |in_len| and 1 otherwise.
551 + *
552 + * When processing, there's only an issue if |out| points within in[:in_len]
553 + * and isn't equal to |in|. If that's the case then writing the output will
554 + * stomp input that hasn't been read yet.
555 + *
556 + * This function checks for that case. */
557 +static int check_alias(const unsigned char *in, size_t in_len,
558 + const unsigned char *out)
559 + {
560 + if (out <= in)
561 + return 1;
562 + if (in + in_len <= out)
563 + return 1;
564 + return 0;
565 + }
566 +
567 +ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx,
568 + unsigned char *out, size_t max_out_len,
569 + const unsigned char *nonce, size_t nonce_len,
570 + const unsigned char *in, size_t in_len,
571 + const unsigned char *ad, size_t ad_len)
572 + {
573 + size_t possible_out_len = in_len + ctx->aead->overhead;
574 + ssize_t r;
575 +
576 + if (possible_out_len < in_len /* overflow */ ||
577 + possible_out_len > SSIZE_MAX /* return value cannot be
578 + represented */)
579 + {
580 + EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
581 + goto error;
582 + }
583 +
584 + if (!check_alias(in, in_len, out))
585 + {
586 + EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT);
587 + goto error;
588 + }
589 +
590 + r = ctx->aead->seal(ctx, out, max_out_len, nonce, nonce_len,
591 + in, in_len, ad, ad_len);
592 + if (r >= 0)
593 + return r;
594 +
595 +error:
596 + /* In the event of an error, clear the output buffer so that a caller
597 + * that doesn't check the return value doesn't send raw data. */
598 + memset(out, 0, max_out_len);
599 + return -1;
600 + }
601 +
602 +ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx,
603 + unsigned char *out, size_t max_out_len,
604 + const unsigned char *nonce, size_t nonce_len,
605 + const unsigned char *in, size_t in_len,
606 + const unsigned char *ad, size_t ad_len)
607 + {
608 + ssize_t r;
609 +
610 + if (in_len > SSIZE_MAX)
611 + {
612 + EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_TOO_LARGE);
613 + goto error; /* may not be able to represent return value. */
614 + }
615 +
616 + if (!check_alias(in, in_len, out))
617 + {
618 + EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT);
619 + goto error;
620 + }
621 +
622 + r = ctx->aead->open(ctx, out, max_out_len, nonce, nonce_len,
623 + in, in_len, ad, ad_len);
624 +
625 + if (r >= 0)
626 + return r;
627 +
628 +error:
629 + /* In the event of an error, clear the output buffer so that a caller
630 + * that doesn't check the return value doesn't try and process bad
631 + * data. */
632 + memset(out, 0, max_out_len);
633 + return -1;
634 + }
635 diff --git a/crypto/evp/evp_err.c b/crypto/evp/evp_err.c
636 index 08eab98..c47969c 100644
637 --- a/crypto/evp/evp_err.c
638 +++ b/crypto/evp/evp_err.c
639 @@ -70,6 +70,11 @@
640
641 static ERR_STRING_DATA EVP_str_functs[]=
642 {
643 +{ERR_FUNC(EVP_F_AEAD_AES_128_GCM_INIT), "AEAD_AES_128_GCM_INIT"},
644 +{ERR_FUNC(EVP_F_AEAD_AES_128_GCM_OPEN), "AEAD_AES_128_GCM_OPEN"},
645 +{ERR_FUNC(EVP_F_AEAD_AES_128_GCM_SEAL), "AEAD_AES_128_GCM_SEAL"},
646 +{ERR_FUNC(EVP_F_AEAD_CTX_OPEN), "AEAD_CTX_OPEN"},
647 +{ERR_FUNC(EVP_F_AEAD_CTX_SEAL), "AEAD_CTX_SEAL"},
648 {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"},
649 {ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"},
650 {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"},
651 @@ -84,6 +89,7 @@ static ERR_STRING_DATA EVP_str_functs[]=
652 {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"},
653 {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"},
654 {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"},
655 +{ERR_FUNC(EVP_F_EVP_AEAD_CTX_INIT), "EVP_AEAD_CTX_init"},
656 {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"},
657 {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"},
658 {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"},
659 @@ -202,10 +208,12 @@ static ERR_STRING_DATA EVP_str_reasons[]=
660 {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED),"no verify function configured "},
661 {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),"operation not supp orted for this keytype"},
662 {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED),"operaton not initialized"},
663 +{ERR_REASON(EVP_R_OUTPUT_ALIASES_INPUT) ,"output aliases input"},
664 {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),"pkcs8 unknown broken type"},
665 {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR),"private key decode error"},
666 {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR),"private key encode error"},
667 {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA) ,"public key not rsa"},
668 +{ERR_REASON(EVP_R_TAG_TOO_LARGE) ,"tag too large"},
669 {ERR_REASON(EVP_R_TOO_LARGE) ,"too large"},
670 {ERR_REASON(EVP_R_UNKNOWN_CIPHER) ,"unknown cipher"},
671 {ERR_REASON(EVP_R_UNKNOWN_DIGEST) ,"unknown digest"},
672 diff --git a/crypto/evp/evp_locl.h b/crypto/evp/evp_locl.h
673 index 08c0a66..c0f9fdf 100644
674 --- a/crypto/evp/evp_locl.h
675 +++ b/crypto/evp/evp_locl.h
676 @@ -348,6 +348,30 @@ int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const cha r *pass, int passlen,
677 ASN1_TYPE *param,
678 const EVP_CIPHER *c, const EVP_MD *md, int en_de);
679
680 +/* EVP_AEAD represents a specific AEAD algorithm. */
681 +struct evp_aead_st {
682 + unsigned char key_len;
683 + unsigned char nonce_len;
684 + unsigned char overhead;
685 + unsigned char max_tag_len;
686 +
687 + int (*init) (struct evp_aead_ctx_st*, const unsigned char *key,
688 + size_t key_len, size_t tag_len);
689 + void (*cleanup) (struct evp_aead_ctx_st*);
690 +
691 + ssize_t (*seal) (const struct evp_aead_ctx_st *ctx,
692 + unsigned char *out, size_t max_out_len,
693 + const unsigned char *nonce, size_t nonce_len,
694 + const unsigned char *in, size_t in_len,
695 + const unsigned char *ad, size_t ad_len);
696 +
697 + ssize_t (*open) (const struct evp_aead_ctx_st *ctx,
698 + unsigned char *out, size_t max_out_len,
699 + const unsigned char *nonce, size_t nonce_len,
700 + const unsigned char *in, size_t in_len,
701 + const unsigned char *ad, size_t ad_len);
702 +};
703 +
704 #ifdef OPENSSL_FIPS
705
706 #ifdef OPENSSL_DOING_MAKEDEPEND
707 diff --git a/doc/crypto/EVP_AEAD_CTX_init.pod b/doc/crypto/EVP_AEAD_CTX_init.pod
708 new file mode 100644
709 index 0000000..20e455d
710 --- /dev/null
711 +++ b/doc/crypto/EVP_AEAD_CTX_init.pod
712 @@ -0,0 +1,96 @@
713 +=pod
714 +
715 +=head1 NAME
716 +
717 +EVP_AEAD_CTX_init, EVP_AEAD_CTX_cleanup, EVP_AEAD_CTX_seal, EVP_AEAD_CTX_open - authenticated encryption functions.
718 +
719 +=head1 SYNOPSIS
720 +
721 + #include <openssl/evp.h>
722 +
723 + int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
724 + const unsigned char *key, size_t key_len,
725 + size_t tag_len, ENGINE *impl);
726 + void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
727 + ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx,
728 + unsigned char *out, size_t max_out_len,
729 + const unsigned char *nonce, size_t nonce_len,
730 + const unsigned char *in, size_t in_len,
731 + const unsigned char *ad, size_t ad_len);
732 + ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx,
733 + unsigned char *out, size_t max_out_len,
734 + const unsigned char *nonce, size_t nonce_len,
735 + const unsigned char *in, size_t in_len,
736 + const unsigned char *ad, size_t ad_len);
737 +
738 +=head1 DESCRIPTION
739 +
740 +The EVP_AEAD_CTX_init() function initialises an B<EVP_AEAD_CTX> structure and
741 +performs any precomputation needed to use B<aead> with B<key>. The length of
742 +the key, B<key_len>, is given in bytes.
743 +
744 +The B<tag_len> argument contains the length of the tags, in bytes, and allows
745 +for the processing of truncated authenticators. A zero value indicates that the
746 +default tag length should be used and this is defined as
747 +C<EVP_AEAD_DEFAULT_TAG_LENGTH> in order to make the code clear. Using truncated
748 +tags increases an attacker's chance of creating a valid forgery. Be aware that
749 +the attacker's chance may increase more than exponentially as would naively be
750 +expected.
751 +
752 +When no longer needed, the initialised B<EVP_AEAD_CTX> structure must be passed
753 +to EVP_AEAD_CTX_cleanup(), which will deallocate any memory used.
754 +
755 +With an B<EVP_AEAD_CTX> in hand, one can seal and open messages. These
756 +operations are intended to meet the standard notions of privacy and
757 +authenticity for authenticated encryption. For formal definitions see I<Bellare
758 +and Namprempre>, "Authenticated encryption: relations among notions and
759 +analysis of the generic composition paradigm," Lecture Notes in Computer
760 +Science B<1976> (2000), 531–545,
761 +L<http://www-cse.ucsd.edu/~mihir/papers/oem.html>.
762 +
763 +When sealing messages, a nonce must be given. The length of the nonce is fixed
764 +by the AEAD in use and is returned by EVP_AEAD_nonce_length(). I<The nonce must
765 +be unique for all messages with the same key>. This is critically important -
766 +nonce reuse may completely undermine the security of the AEAD. Nonces may be
767 +predictable and public, so long as they are unique. Uniqueness may be achieved
768 +with a simple counter or, if long enough, may be generated randomly. The nonce
769 +must be passed into the "open" operation by the receiver so must either be
770 +implicit (e.g. a counter), or must be transmitted along with the sealed message .
771 +
772 +The "seal" and "open" operations are atomic - an entire message must be
773 +encrypted or decrypted in a single call. Large messages may have to be split up
774 +in order to accomodate this. When doing so, be mindful of the need not to
775 +repeat nonces and the possibility that an attacker could duplicate, reorder or
776 +drop message chunks. For example, using a single key for a given (large)
777 +message and sealing chunks with nonces counting from zero would be secure as
778 +long as the number of chunks was securely transmitted. (Otherwise an attacker
779 +could truncate the message by dropping chunks from the end.)
780 +
781 +The number of chunks could be transmitted by prefixing it to the plaintext, for
782 +example. This also assumes that no other message would ever use the same key
783 +otherwise the rule that nonces must be unique for a given key would be
784 +violated.
785 +
786 +The "seal" and "open" operations also permit additional data to be
787 +authenticated via the B<ad> parameter. This data is not included in the
788 +ciphertext and must be identical for both the "seal" and "open" call. This
789 +permits implicit context to be authenticated but may be C<NULL> if not needed.
790 +
791 +The "seal" and "open" operations may work inplace if the B<out> and B<in>
792 +arguments are equal. They may also be used to shift the data left inside the
793 +same buffer if B<out> is less than B<in>. However, B<out> may not point inside
794 +the input data otherwise the input may be overwritten before it has been read.
795 +This case will cause an error.
796 +
797 +=head1 RETURN VALUES
798 +
799 +The "seal" and "open" operations return an C<ssize_t> with value -1 on error,
800 +otherwise they return the number of output bytes written. An error will be
801 +returned if the input length is large enough that the output size exceeds the
802 +range of a C<ssize_t>.
803 +
804 +=head1 HISTORY
805 +
806 +These functions were first added to OpenSSL 1.0.2.
807 +
808 +=cut
809 --
810 1.8.4.1
811
OLDNEW
« no previous file with comments | « openssl/patches/aead_ssl_support.patch ('k') | openssl/patches/chacha20poly1305.patch » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698