1 /* Copyright (c) 2015, Google Inc.
2  *
3  * Permission to use, copy, modify, and/or distribute this software for any
4  * purpose with or without fee is hereby granted, provided that the above
5  * copyright notice and this permission notice appear in all copies.
6  *
7  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14 
15 #include <assert.h>
16 #include <string.h>
17 
18 #include <openssl/aead.h>
19 #include <openssl/err.h>
20 #include <openssl/rand.h>
21 #include <openssl/type_check.h>
22 
23 #include "internal.h"
24 
25 
26 OPENSSL_COMPILE_ASSERT(EVP_AEAD_MAX_NONCE_LENGTH < 256,
27                        variable_nonce_len_doesnt_fit_in_uint8_t);
28 
SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,uint16_t version,const SSL_CIPHER * cipher,const uint8_t * enc_key,size_t enc_key_len,const uint8_t * mac_key,size_t mac_key_len,const uint8_t * fixed_iv,size_t fixed_iv_len)29 SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
30                                uint16_t version, const SSL_CIPHER *cipher,
31                                const uint8_t *enc_key, size_t enc_key_len,
32                                const uint8_t *mac_key, size_t mac_key_len,
33                                const uint8_t *fixed_iv, size_t fixed_iv_len) {
34   const EVP_AEAD *aead;
35   size_t discard;
36   if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, cipher, version)) {
37     OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
38     return 0;
39   }
40 
41   uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
42   if (mac_key_len > 0) {
43     /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
44      * suites). */
45     if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
46       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
47       return 0;
48     }
49     memcpy(merged_key, mac_key, mac_key_len);
50     memcpy(merged_key + mac_key_len, enc_key, enc_key_len);
51     memcpy(merged_key + mac_key_len + enc_key_len, fixed_iv, fixed_iv_len);
52     enc_key = merged_key;
53     enc_key_len += mac_key_len;
54     enc_key_len += fixed_iv_len;
55   }
56 
57   SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
58   if (aead_ctx == NULL) {
59     OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_MALLOC_FAILURE);
60     return NULL;
61   }
62   memset(aead_ctx, 0, sizeof(SSL_AEAD_CTX));
63   aead_ctx->cipher = cipher;
64 
65   if (!EVP_AEAD_CTX_init_with_direction(
66           &aead_ctx->ctx, aead, enc_key, enc_key_len,
67           EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) {
68     OPENSSL_free(aead_ctx);
69     return NULL;
70   }
71 
72   assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH);
73   aead_ctx->variable_nonce_len = (uint8_t)EVP_AEAD_nonce_length(aead);
74   if (mac_key_len == 0) {
75     /* For a real AEAD, the IV is the fixed part of the nonce. */
76     if (fixed_iv_len > sizeof(aead_ctx->fixed_nonce) ||
77         fixed_iv_len > aead_ctx->variable_nonce_len) {
78       SSL_AEAD_CTX_free(aead_ctx);
79       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
80       return 0;
81     }
82     aead_ctx->variable_nonce_len -= fixed_iv_len;
83 
84     memcpy(aead_ctx->fixed_nonce, fixed_iv, fixed_iv_len);
85     aead_ctx->fixed_nonce_len = fixed_iv_len;
86     aead_ctx->variable_nonce_included_in_record =
87         (cipher->algorithm2 &
88          SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
89   } else {
90     aead_ctx->variable_nonce_included_in_record = 1;
91     aead_ctx->random_variable_nonce = 1;
92     aead_ctx->omit_length_in_ad = 1;
93     aead_ctx->omit_version_in_ad = (version == SSL3_VERSION);
94   }
95 
96   return aead_ctx;
97 }
98 
SSL_AEAD_CTX_free(SSL_AEAD_CTX * aead)99 void SSL_AEAD_CTX_free(SSL_AEAD_CTX *aead) {
100   if (aead == NULL) {
101     return;
102   }
103   EVP_AEAD_CTX_cleanup(&aead->ctx);
104   OPENSSL_free(aead);
105 }
106 
SSL_AEAD_CTX_explicit_nonce_len(SSL_AEAD_CTX * aead)107 size_t SSL_AEAD_CTX_explicit_nonce_len(SSL_AEAD_CTX *aead) {
108   if (aead != NULL && aead->variable_nonce_included_in_record) {
109     return aead->variable_nonce_len;
110   }
111   return 0;
112 }
113 
SSL_AEAD_CTX_max_overhead(SSL_AEAD_CTX * aead)114 size_t SSL_AEAD_CTX_max_overhead(SSL_AEAD_CTX *aead) {
115   if (aead == NULL) {
116     return 0;
117   }
118   return EVP_AEAD_max_overhead(aead->ctx.aead) +
119       SSL_AEAD_CTX_explicit_nonce_len(aead);
120 }
121 
122 /* ssl_aead_ctx_get_ad writes the additional data for |aead| into |out| and
123  * returns the number of bytes written. */
ssl_aead_ctx_get_ad(SSL_AEAD_CTX * aead,uint8_t out[13],uint8_t type,uint16_t wire_version,const uint8_t seqnum[8],size_t plaintext_len)124 static size_t ssl_aead_ctx_get_ad(SSL_AEAD_CTX *aead, uint8_t out[13],
125                                   uint8_t type, uint16_t wire_version,
126                                   const uint8_t seqnum[8],
127                                   size_t plaintext_len) {
128   memcpy(out, seqnum, 8);
129   size_t len = 8;
130   out[len++] = type;
131   if (!aead->omit_version_in_ad) {
132     out[len++] = (uint8_t)(wire_version >> 8);
133     out[len++] = (uint8_t)wire_version;
134   }
135   if (!aead->omit_length_in_ad) {
136     out[len++] = (uint8_t)(plaintext_len >> 8);
137     out[len++] = (uint8_t)plaintext_len;
138   }
139   return len;
140 }
141 
SSL_AEAD_CTX_open(SSL_AEAD_CTX * aead,uint8_t * out,size_t * out_len,size_t max_out,uint8_t type,uint16_t wire_version,const uint8_t seqnum[8],const uint8_t * in,size_t in_len)142 int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
143                       size_t max_out, uint8_t type, uint16_t wire_version,
144                       const uint8_t seqnum[8], const uint8_t *in,
145                       size_t in_len) {
146   if (aead == NULL) {
147     /* Handle the initial NULL cipher. */
148     if (in_len > max_out) {
149       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BUFFER_TOO_SMALL);
150       return 0;
151     }
152     memmove(out, in, in_len);
153     *out_len = in_len;
154     return 1;
155   }
156 
157   /* TLS 1.2 AEADs include the length in the AD and are assumed to have fixed
158    * overhead. Otherwise the parameter is unused. */
159   size_t plaintext_len = 0;
160   if (!aead->omit_length_in_ad) {
161     size_t overhead = SSL_AEAD_CTX_max_overhead(aead);
162     if (in_len < overhead) {
163       /* Publicly invalid. */
164       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
165       return 0;
166     }
167     plaintext_len = in_len - overhead;
168   }
169   uint8_t ad[13];
170   size_t ad_len = ssl_aead_ctx_get_ad(aead, ad, type, wire_version, seqnum,
171                                       plaintext_len);
172 
173   /* Assemble the nonce. */
174   uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
175   size_t nonce_len = 0;
176   memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
177   nonce_len += aead->fixed_nonce_len;
178   if (aead->variable_nonce_included_in_record) {
179     if (in_len < aead->variable_nonce_len) {
180       /* Publicly invalid. */
181       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
182       return 0;
183     }
184     memcpy(nonce + nonce_len, in, aead->variable_nonce_len);
185     in += aead->variable_nonce_len;
186     in_len -= aead->variable_nonce_len;
187   } else {
188     assert(aead->variable_nonce_len == 8);
189     memcpy(nonce + nonce_len, seqnum, aead->variable_nonce_len);
190   }
191   nonce_len += aead->variable_nonce_len;
192 
193   return EVP_AEAD_CTX_open(&aead->ctx, out, out_len, max_out, nonce, nonce_len,
194                            in, in_len, ad, ad_len);
195 }
196 
SSL_AEAD_CTX_seal(SSL_AEAD_CTX * aead,uint8_t * out,size_t * out_len,size_t max_out,uint8_t type,uint16_t wire_version,const uint8_t seqnum[8],const uint8_t * in,size_t in_len)197 int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
198                       size_t max_out, uint8_t type, uint16_t wire_version,
199                       const uint8_t seqnum[8], const uint8_t *in,
200                       size_t in_len) {
201   if (aead == NULL) {
202     /* Handle the initial NULL cipher. */
203     if (in_len > max_out) {
204       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
205       return 0;
206     }
207     memmove(out, in, in_len);
208     *out_len = in_len;
209     return 1;
210   }
211 
212   uint8_t ad[13];
213   size_t ad_len = ssl_aead_ctx_get_ad(aead, ad, type, wire_version, seqnum,
214                                       in_len);
215 
216   /* Assemble the nonce. */
217   uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
218   size_t nonce_len = 0;
219   memcpy(nonce, aead->fixed_nonce, aead->fixed_nonce_len);
220   nonce_len += aead->fixed_nonce_len;
221   if (aead->random_variable_nonce) {
222     assert(aead->variable_nonce_included_in_record);
223     if (!RAND_bytes(nonce + nonce_len, aead->variable_nonce_len)) {
224       return 0;
225     }
226   } else {
227     /* When sending we use the sequence number as the variable part of the
228      * nonce. */
229     assert(aead->variable_nonce_len == 8);
230     memcpy(nonce + nonce_len, ad, aead->variable_nonce_len);
231   }
232   nonce_len += aead->variable_nonce_len;
233 
234   /* Emit the variable nonce if included in the record. */
235   size_t extra_len = 0;
236   if (aead->variable_nonce_included_in_record) {
237     if (max_out < aead->variable_nonce_len) {
238       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
239       return 0;
240     }
241     if (out < in + in_len && in < out + aead->variable_nonce_len) {
242       OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_OUTPUT_ALIASES_INPUT);
243       return 0;
244     }
245     memcpy(out, nonce + aead->fixed_nonce_len, aead->variable_nonce_len);
246     extra_len = aead->variable_nonce_len;
247     out += aead->variable_nonce_len;
248     max_out -= aead->variable_nonce_len;
249   }
250 
251   if (!EVP_AEAD_CTX_seal(&aead->ctx, out, out_len, max_out, nonce, nonce_len,
252                          in, in_len, ad, ad_len)) {
253     return 0;
254   }
255   *out_len += extra_len;
256   return 1;
257 }
258