blob: 3b8d1b2509be84af188d0950e6a26ef50217f131 [file] [log] [blame]
David Benjamin31a07792015-03-03 14:20:26 -05001/* 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
David Benjamin9e4e01e2015-09-15 01:48:04 -040015#include <openssl/ssl.h>
16
David Benjamin31a07792015-03-03 14:20:26 -050017#include <assert.h>
18#include <string.h>
19
20#include <openssl/aead.h>
21#include <openssl/err.h>
22#include <openssl/rand.h>
David Benjamin31a07792015-03-03 14:20:26 -050023
David Benjamin17cf2cb2016-12-13 01:07:13 -050024#include "../crypto/internal.h"
David Benjamin31a07792015-03-03 14:20:26 -050025#include "internal.h"
26
27
David Benjamincfc11c22017-07-18 22:45:18 -040028#if defined(BORINGSSL_UNSAFE_FUZZER_MODE)
29#define FUZZER_MODE true
30#else
31#define FUZZER_MODE false
32#endif
33
David Benjamin86e95b82017-07-18 16:34:25 -040034namespace bssl {
35
David Benjamincfc11c22017-07-18 22:45:18 -040036SSLAEADContext::SSLAEADContext(uint16_t version_arg,
37 const SSL_CIPHER *cipher_arg)
38 : cipher_(cipher_arg),
39 version_(version_arg),
40 variable_nonce_included_in_record_(false),
41 random_variable_nonce_(false),
42 omit_length_in_ad_(false),
43 omit_version_in_ad_(false),
44 omit_ad_(false),
45 xor_fixed_nonce_(false) {
46 OPENSSL_memset(fixed_nonce_, 0, sizeof(fixed_nonce_));
47}
48
49SSLAEADContext::~SSLAEADContext() {}
50
51UniquePtr<SSLAEADContext> SSLAEADContext::CreateNullCipher() {
52 return MakeUnique<SSLAEADContext>(0 /* version */, nullptr /* cipher */);
53}
54
55UniquePtr<SSLAEADContext> SSLAEADContext::Create(
56 enum evp_aead_direction_t direction, uint16_t version, int is_dtls,
57 const SSL_CIPHER *cipher, const uint8_t *enc_key, size_t enc_key_len,
58 const uint8_t *mac_key, size_t mac_key_len, const uint8_t *fixed_iv,
59 size_t fixed_iv_len) {
David Benjamin31a07792015-03-03 14:20:26 -050060 const EVP_AEAD *aead;
David Benjamin4b0d0e42016-10-28 17:17:14 -040061 size_t expected_mac_key_len, expected_fixed_iv_len;
62 if (!ssl_cipher_get_evp_aead(&aead, &expected_mac_key_len,
Steven Valdez2f3404b2017-05-24 16:54:35 -040063 &expected_fixed_iv_len, cipher, version,
64 is_dtls) ||
David Benjamin4b0d0e42016-10-28 17:17:14 -040065 /* Ensure the caller returned correct key sizes. */
66 expected_fixed_iv_len != fixed_iv_len ||
67 expected_mac_key_len != mac_key_len) {
David Benjamin3570d732015-06-29 00:28:17 -040068 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamincfc11c22017-07-18 22:45:18 -040069 return nullptr;
David Benjamin31a07792015-03-03 14:20:26 -050070 }
71
72 uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH];
73 if (mac_key_len > 0) {
74 /* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
75 * suites). */
76 if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
David Benjamin3570d732015-06-29 00:28:17 -040077 OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
David Benjamincfc11c22017-07-18 22:45:18 -040078 return nullptr;
David Benjamin31a07792015-03-03 14:20:26 -050079 }
David Benjamin17cf2cb2016-12-13 01:07:13 -050080 OPENSSL_memcpy(merged_key, mac_key, mac_key_len);
81 OPENSSL_memcpy(merged_key + mac_key_len, enc_key, enc_key_len);
82 OPENSSL_memcpy(merged_key + mac_key_len + enc_key_len, fixed_iv,
83 fixed_iv_len);
David Benjamin31a07792015-03-03 14:20:26 -050084 enc_key = merged_key;
85 enc_key_len += mac_key_len;
86 enc_key_len += fixed_iv_len;
87 }
88
David Benjamincfc11c22017-07-18 22:45:18 -040089 UniquePtr<SSLAEADContext> aead_ctx =
90 MakeUnique<SSLAEADContext>(version, cipher);
91 if (!aead_ctx) {
David Benjamin3570d732015-06-29 00:28:17 -040092 OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
David Benjamincfc11c22017-07-18 22:45:18 -040093 return nullptr;
David Benjamin31a07792015-03-03 14:20:26 -050094 }
David Benjamin31a07792015-03-03 14:20:26 -050095
96 if (!EVP_AEAD_CTX_init_with_direction(
David Benjamincfc11c22017-07-18 22:45:18 -040097 aead_ctx->ctx_.get(), aead, enc_key, enc_key_len,
David Benjamin31a07792015-03-03 14:20:26 -050098 EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) {
David Benjamincfc11c22017-07-18 22:45:18 -040099 return nullptr;
David Benjamin31a07792015-03-03 14:20:26 -0500100 }
101
102 assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH);
David Benjamina3d76d02017-07-14 19:36:07 -0400103 static_assert(EVP_AEAD_MAX_NONCE_LENGTH < 256,
104 "variable_nonce_len doesn't fit in uint8_t");
David Benjamincfc11c22017-07-18 22:45:18 -0400105 aead_ctx->variable_nonce_len_ = (uint8_t)EVP_AEAD_nonce_length(aead);
David Benjamin51a01a52015-10-29 13:19:56 -0400106 if (mac_key_len == 0) {
David Benjamincfc11c22017-07-18 22:45:18 -0400107 assert(fixed_iv_len <= sizeof(aead_ctx->fixed_nonce_));
108 OPENSSL_memcpy(aead_ctx->fixed_nonce_, fixed_iv, fixed_iv_len);
109 aead_ctx->fixed_nonce_len_ = fixed_iv_len;
David Benjamin13414b32015-12-09 23:02:39 -0500110
111 if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) {
112 /* The fixed nonce into the actual nonce (the sequence number). */
David Benjamincfc11c22017-07-18 22:45:18 -0400113 aead_ctx->xor_fixed_nonce_ = true;
114 aead_ctx->variable_nonce_len_ = 8;
David Benjamin13414b32015-12-09 23:02:39 -0500115 } else {
116 /* The fixed IV is prepended to the nonce. */
David Benjamincfc11c22017-07-18 22:45:18 -0400117 assert(fixed_iv_len <= aead_ctx->variable_nonce_len_);
118 aead_ctx->variable_nonce_len_ -= fixed_iv_len;
David Benjamin13414b32015-12-09 23:02:39 -0500119 }
120
David Benjaminb2a985b2015-06-21 15:13:57 -0400121 /* AES-GCM uses an explicit nonce. */
122 if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) {
David Benjamincfc11c22017-07-18 22:45:18 -0400123 aead_ctx->variable_nonce_included_in_record_ = true;
David Benjaminb2a985b2015-06-21 15:13:57 -0400124 }
Steven Valdez494650c2016-05-24 12:43:04 -0400125
126 /* The TLS 1.3 construction XORs the fixed nonce into the sequence number
127 * and omits the additional data. */
128 if (version >= TLS1_3_VERSION) {
David Benjamincfc11c22017-07-18 22:45:18 -0400129 aead_ctx->xor_fixed_nonce_ = true;
130 aead_ctx->variable_nonce_len_ = 8;
131 aead_ctx->variable_nonce_included_in_record_ = false;
132 aead_ctx->omit_ad_ = true;
133 assert(fixed_iv_len >= aead_ctx->variable_nonce_len_);
Steven Valdez494650c2016-05-24 12:43:04 -0400134 }
David Benjamin31a07792015-03-03 14:20:26 -0500135 } else {
Steven Valdez79750562016-06-16 06:38:04 -0400136 assert(version < TLS1_3_VERSION);
David Benjamincfc11c22017-07-18 22:45:18 -0400137 aead_ctx->variable_nonce_included_in_record_ = true;
138 aead_ctx->random_variable_nonce_ = true;
139 aead_ctx->omit_length_in_ad_ = true;
140 aead_ctx->omit_version_in_ad_ = (version == SSL3_VERSION);
David Benjamin31a07792015-03-03 14:20:26 -0500141 }
142
143 return aead_ctx;
144}
145
David Benjamincfc11c22017-07-18 22:45:18 -0400146size_t SSLAEADContext::ExplicitNonceLen() const {
147 if (!FUZZER_MODE && variable_nonce_included_in_record_) {
148 return variable_nonce_len_;
David Benjamin31a07792015-03-03 14:20:26 -0500149 }
150 return 0;
151}
152
David Benjamincfc11c22017-07-18 22:45:18 -0400153size_t SSLAEADContext::MaxSuffixLen(size_t extra_in_len) const {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700154 return extra_in_len +
David Benjamincfc11c22017-07-18 22:45:18 -0400155 (is_null_cipher() || FUZZER_MODE
156 ? 0
157 : EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get())));
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700158}
159
David Benjamincfc11c22017-07-18 22:45:18 -0400160size_t SSLAEADContext::MaxOverhead() const {
161 return ExplicitNonceLen() + MaxSuffixLen(0);
David Benjamin31a07792015-03-03 14:20:26 -0500162}
163
David Benjamincfc11c22017-07-18 22:45:18 -0400164size_t SSLAEADContext::GetAdditionalData(uint8_t out[13], uint8_t type,
165 uint16_t wire_version,
166 const uint8_t seqnum[8],
167 size_t plaintext_len) {
168 if (omit_ad_) {
Steven Valdez494650c2016-05-24 12:43:04 -0400169 return 0;
170 }
171
David Benjamin17cf2cb2016-12-13 01:07:13 -0500172 OPENSSL_memcpy(out, seqnum, 8);
David Benjamin31a07792015-03-03 14:20:26 -0500173 size_t len = 8;
174 out[len++] = type;
David Benjamincfc11c22017-07-18 22:45:18 -0400175 if (!omit_version_in_ad_) {
176 out[len++] = static_cast<uint8_t>((wire_version >> 8));
177 out[len++] = static_cast<uint8_t>(wire_version);
David Benjamin31a07792015-03-03 14:20:26 -0500178 }
David Benjamincfc11c22017-07-18 22:45:18 -0400179 if (!omit_length_in_ad_) {
180 out[len++] = static_cast<uint8_t>((plaintext_len >> 8));
181 out[len++] = static_cast<uint8_t>(plaintext_len);
David Benjamin31a07792015-03-03 14:20:26 -0500182 }
183 return len;
184}
185
David Benjamincfc11c22017-07-18 22:45:18 -0400186bool SSLAEADContext::Open(CBS *out, uint8_t type, uint16_t wire_version,
187 const uint8_t seqnum[8], uint8_t *in, size_t in_len) {
188 if (is_null_cipher() || FUZZER_MODE) {
David Benjamin31a07792015-03-03 14:20:26 -0500189 /* Handle the initial NULL cipher. */
David Benjamina7810c12016-06-06 18:54:51 -0400190 CBS_init(out, in, in_len);
David Benjamincfc11c22017-07-18 22:45:18 -0400191 return true;
David Benjamin31a07792015-03-03 14:20:26 -0500192 }
193
194 /* TLS 1.2 AEADs include the length in the AD and are assumed to have fixed
195 * overhead. Otherwise the parameter is unused. */
196 size_t plaintext_len = 0;
David Benjamincfc11c22017-07-18 22:45:18 -0400197 if (!omit_length_in_ad_) {
198 size_t overhead = MaxOverhead();
David Benjamin31a07792015-03-03 14:20:26 -0500199 if (in_len < overhead) {
200 /* Publicly invalid. */
David Benjamin3570d732015-06-29 00:28:17 -0400201 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
David Benjamincfc11c22017-07-18 22:45:18 -0400202 return false;
David Benjamin31a07792015-03-03 14:20:26 -0500203 }
204 plaintext_len = in_len - overhead;
205 }
206 uint8_t ad[13];
David Benjamincfc11c22017-07-18 22:45:18 -0400207 size_t ad_len =
208 GetAdditionalData(ad, type, wire_version, seqnum, plaintext_len);
David Benjamin31a07792015-03-03 14:20:26 -0500209
210 /* Assemble the nonce. */
211 uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
212 size_t nonce_len = 0;
David Benjamin13414b32015-12-09 23:02:39 -0500213
214 /* Prepend the fixed nonce, or left-pad with zeros if XORing. */
David Benjamincfc11c22017-07-18 22:45:18 -0400215 if (xor_fixed_nonce_) {
216 nonce_len = fixed_nonce_len_ - variable_nonce_len_;
David Benjamin17cf2cb2016-12-13 01:07:13 -0500217 OPENSSL_memset(nonce, 0, nonce_len);
David Benjamin13414b32015-12-09 23:02:39 -0500218 } else {
David Benjamincfc11c22017-07-18 22:45:18 -0400219 OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_);
220 nonce_len += fixed_nonce_len_;
David Benjamin13414b32015-12-09 23:02:39 -0500221 }
222
223 /* Add the variable nonce. */
David Benjamincfc11c22017-07-18 22:45:18 -0400224 if (variable_nonce_included_in_record_) {
225 if (in_len < variable_nonce_len_) {
David Benjamin31a07792015-03-03 14:20:26 -0500226 /* Publicly invalid. */
David Benjamin3570d732015-06-29 00:28:17 -0400227 OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
David Benjamincfc11c22017-07-18 22:45:18 -0400228 return false;
David Benjamin31a07792015-03-03 14:20:26 -0500229 }
David Benjamincfc11c22017-07-18 22:45:18 -0400230 OPENSSL_memcpy(nonce + nonce_len, in, variable_nonce_len_);
231 in += variable_nonce_len_;
232 in_len -= variable_nonce_len_;
David Benjamin31a07792015-03-03 14:20:26 -0500233 } else {
David Benjamincfc11c22017-07-18 22:45:18 -0400234 assert(variable_nonce_len_ == 8);
235 OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_);
David Benjamin31a07792015-03-03 14:20:26 -0500236 }
David Benjamincfc11c22017-07-18 22:45:18 -0400237 nonce_len += variable_nonce_len_;
David Benjamin31a07792015-03-03 14:20:26 -0500238
David Benjamin13414b32015-12-09 23:02:39 -0500239 /* XOR the fixed nonce, if necessary. */
David Benjamincfc11c22017-07-18 22:45:18 -0400240 if (xor_fixed_nonce_) {
241 assert(nonce_len == fixed_nonce_len_);
242 for (size_t i = 0; i < fixed_nonce_len_; i++) {
243 nonce[i] ^= fixed_nonce_[i];
David Benjamin13414b32015-12-09 23:02:39 -0500244 }
245 }
246
David Benjamina7810c12016-06-06 18:54:51 -0400247 /* Decrypt in-place. */
248 size_t len;
David Benjamincfc11c22017-07-18 22:45:18 -0400249 if (!EVP_AEAD_CTX_open(ctx_.get(), in, &len, in_len, nonce, nonce_len, in,
250 in_len, ad, ad_len)) {
251 return false;
David Benjamina7810c12016-06-06 18:54:51 -0400252 }
253 CBS_init(out, in, len);
David Benjamincfc11c22017-07-18 22:45:18 -0400254 return true;
David Benjamin31a07792015-03-03 14:20:26 -0500255}
256
David Benjamincfc11c22017-07-18 22:45:18 -0400257bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out,
258 uint8_t *out_suffix, size_t *out_suffix_len,
259 size_t max_out_suffix_len, uint8_t type,
260 uint16_t wire_version, const uint8_t seqnum[8],
261 const uint8_t *in, size_t in_len,
262 const uint8_t *extra_in, size_t extra_in_len) {
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700263 if ((in != out && buffers_alias(in, in_len, out, in_len)) ||
264 buffers_alias(in, in_len, out_suffix, max_out_suffix_len)) {
265 OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
David Benjamincfc11c22017-07-18 22:45:18 -0400266 return false;
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700267 }
268 if (extra_in_len > max_out_suffix_len) {
269 OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
David Benjamincfc11c22017-07-18 22:45:18 -0400270 return false;
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700271 }
272
David Benjamincfc11c22017-07-18 22:45:18 -0400273 if (is_null_cipher() || FUZZER_MODE) {
David Benjamin31a07792015-03-03 14:20:26 -0500274 /* Handle the initial NULL cipher. */
David Benjamin17cf2cb2016-12-13 01:07:13 -0500275 OPENSSL_memmove(out, in, in_len);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700276 OPENSSL_memmove(out_suffix, extra_in, extra_in_len);
277 *out_suffix_len = extra_in_len;
David Benjamincfc11c22017-07-18 22:45:18 -0400278 return true;
David Benjamin31a07792015-03-03 14:20:26 -0500279 }
280
281 uint8_t ad[13];
David Benjamincfc11c22017-07-18 22:45:18 -0400282 size_t ad_len = GetAdditionalData(ad, type, wire_version, seqnum, in_len);
David Benjamin31a07792015-03-03 14:20:26 -0500283
284 /* Assemble the nonce. */
285 uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH];
286 size_t nonce_len = 0;
David Benjamin13414b32015-12-09 23:02:39 -0500287
288 /* Prepend the fixed nonce, or left-pad with zeros if XORing. */
David Benjamincfc11c22017-07-18 22:45:18 -0400289 if (xor_fixed_nonce_) {
290 nonce_len = fixed_nonce_len_ - variable_nonce_len_;
David Benjamin17cf2cb2016-12-13 01:07:13 -0500291 OPENSSL_memset(nonce, 0, nonce_len);
David Benjamin13414b32015-12-09 23:02:39 -0500292 } else {
David Benjamincfc11c22017-07-18 22:45:18 -0400293 OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_);
294 nonce_len += fixed_nonce_len_;
David Benjamin13414b32015-12-09 23:02:39 -0500295 }
296
297 /* Select the variable nonce. */
David Benjamincfc11c22017-07-18 22:45:18 -0400298 if (random_variable_nonce_) {
299 assert(variable_nonce_included_in_record_);
300 if (!RAND_bytes(nonce + nonce_len, variable_nonce_len_)) {
301 return false;
David Benjamin31a07792015-03-03 14:20:26 -0500302 }
303 } else {
304 /* When sending we use the sequence number as the variable part of the
305 * nonce. */
David Benjamincfc11c22017-07-18 22:45:18 -0400306 assert(variable_nonce_len_ == 8);
307 OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_);
David Benjamin31a07792015-03-03 14:20:26 -0500308 }
David Benjamincfc11c22017-07-18 22:45:18 -0400309 nonce_len += variable_nonce_len_;
David Benjamin31a07792015-03-03 14:20:26 -0500310
311 /* Emit the variable nonce if included in the record. */
David Benjamincfc11c22017-07-18 22:45:18 -0400312 if (variable_nonce_included_in_record_) {
313 assert(!xor_fixed_nonce_);
314 if (buffers_alias(in, in_len, out_prefix, variable_nonce_len_)) {
David Benjamin3570d732015-06-29 00:28:17 -0400315 OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
David Benjamincfc11c22017-07-18 22:45:18 -0400316 return false;
David Benjamin31a07792015-03-03 14:20:26 -0500317 }
David Benjamincfc11c22017-07-18 22:45:18 -0400318 OPENSSL_memcpy(out_prefix, nonce + fixed_nonce_len_,
319 variable_nonce_len_);
David Benjamin31a07792015-03-03 14:20:26 -0500320 }
321
David Benjamin13414b32015-12-09 23:02:39 -0500322 /* XOR the fixed nonce, if necessary. */
David Benjamincfc11c22017-07-18 22:45:18 -0400323 if (xor_fixed_nonce_) {
324 assert(nonce_len == fixed_nonce_len_);
325 for (size_t i = 0; i < fixed_nonce_len_; i++) {
326 nonce[i] ^= fixed_nonce_[i];
David Benjamin13414b32015-12-09 23:02:39 -0500327 }
328 }
329
David Benjamincfc11c22017-07-18 22:45:18 -0400330 return !!EVP_AEAD_CTX_seal_scatter(
331 ctx_.get(), out, out_suffix, out_suffix_len, max_out_suffix_len, nonce,
332 nonce_len, in, in_len, extra_in, extra_in_len, ad, ad_len);
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700333}
334
David Benjamincfc11c22017-07-18 22:45:18 -0400335bool SSLAEADContext::Seal(uint8_t *out, size_t *out_len, size_t max_out_len,
336 uint8_t type, uint16_t wire_version,
337 const uint8_t seqnum[8], const uint8_t *in,
338 size_t in_len) {
339 size_t prefix_len = ExplicitNonceLen();
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700340 if (in_len + prefix_len < in_len) {
341 OPENSSL_PUT_ERROR(CIPHER, SSL_R_RECORD_TOO_LARGE);
David Benjamincfc11c22017-07-18 22:45:18 -0400342 return false;
David Benjamin31a07792015-03-03 14:20:26 -0500343 }
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700344 if (in_len + prefix_len > max_out_len) {
345 OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
David Benjamincfc11c22017-07-18 22:45:18 -0400346 return false;
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700347 }
348
349 size_t suffix_len;
David Benjamincfc11c22017-07-18 22:45:18 -0400350 if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len,
351 &suffix_len, max_out_len - prefix_len - in_len, type,
352 wire_version, seqnum, in, in_len, 0, 0)) {
353 return false;
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700354 }
David Benjamincfc11c22017-07-18 22:45:18 -0400355 assert(suffix_len <= MaxSuffixLen(0));
Martin Kreichgauer9f2bffb2017-06-30 05:29:50 -0700356 *out_len = prefix_len + in_len + suffix_len;
David Benjamincfc11c22017-07-18 22:45:18 -0400357 return true;
358}
359
360bool SSLAEADContext::GetIV(const uint8_t **out_iv, size_t *out_iv_len) const {
361 return !is_null_cipher() &&
362 EVP_AEAD_CTX_get_iv(ctx_.get(), out_iv, out_iv_len);
David Benjamin31a07792015-03-03 14:20:26 -0500363}
David Benjamin86e95b82017-07-18 16:34:25 -0400364
365} // namespace bssl