summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorjsing <>2014-05-26 13:01:58 +0000
committerjsing <>2014-05-26 13:01:58 +0000
commit1e04f96479c885fa94175f42f348872cbdd3c9d4 (patch)
tree2d8c2f3b74e112db8f84b41231b2cde79d0be571 /src
parent3ebf48c494177b3b775febf8302322375c80fe3b (diff)
downloadopenbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.tar.gz
openbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.tar.bz2
openbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.zip
Implement an improved version of the EVP AEAD API. The
EVP_AEAD_CTX_{open,seal} functions previously returned an ssize_t that was overloaded to indicate success/failure, along with the number of bytes written as output. This change adds an explicit *out_len argument which is used to return the number of output bytes and the return value is now an int that is purely used to identify success or failure. This change effectively rides the last libcrypto crank (although I do not expect there to be many users of the EVP AEAD API currently). Thanks to Adam Langley for providing the improved code that this diff is based on. ok miod@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/evp/e_aes.c51
-rw-r--r--src/lib/libcrypto/evp/e_chacha20poly1305.c62
-rw-r--r--src/lib/libcrypto/evp/evp.h34
-rw-r--r--src/lib/libcrypto/evp/evp_aead.c50
-rw-r--r--src/lib/libcrypto/evp/evp_locl.h18
-rw-r--r--src/lib/libssl/src/crypto/evp/e_aes.c51
-rw-r--r--src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c62
-rw-r--r--src/lib/libssl/src/crypto/evp/evp.h34
-rw-r--r--src/lib/libssl/src/crypto/evp/evp_aead.c50
-rw-r--r--src/lib/libssl/src/crypto/evp/evp_locl.h18
10 files changed, 218 insertions, 212 deletions
diff --git a/src/lib/libcrypto/evp/e_aes.c b/src/lib/libcrypto/evp/e_aes.c
index 2e81495e5f..0276cc2bd3 100644
--- a/src/lib/libcrypto/evp/e_aes.c
+++ b/src/lib/libcrypto/evp/e_aes.c
@@ -1281,9 +1281,10 @@ aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
1281 struct aead_aes_gcm_ctx *gcm_ctx; 1281 struct aead_aes_gcm_ctx *gcm_ctx;
1282 const size_t key_bits = key_len * 8; 1282 const size_t key_bits = key_len * 8;
1283 1283
1284 /* EVP_AEAD_CTX_init should catch this. */
1284 if (key_bits != 128 && key_bits != 256) { 1285 if (key_bits != 128 && key_bits != 256) {
1285 EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_BAD_KEY_LENGTH); 1286 EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_BAD_KEY_LENGTH);
1286 return 0; /* EVP_AEAD_CTX_init should catch this. */ 1287 return 0;
1287 } 1288 }
1288 1289
1289 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) 1290 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
@@ -1324,88 +1325,92 @@ aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx)
1324 free(gcm_ctx); 1325 free(gcm_ctx);
1325} 1326}
1326 1327
1327static ssize_t 1328static int
1328aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 1329aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
1329 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1330 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
1330 const unsigned char *in, size_t in_len, const unsigned char *ad, 1331 const unsigned char *in, size_t in_len, const unsigned char *ad,
1331 size_t ad_len) 1332 size_t ad_len)
1332{ 1333{
1333 size_t bulk = 0;
1334 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; 1334 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1335 GCM128_CONTEXT gcm; 1335 GCM128_CONTEXT gcm;
1336 size_t bulk = 0;
1336 1337
1337 if (max_out_len < in_len + gcm_ctx->tag_len) { 1338 if (max_out_len < in_len + gcm_ctx->tag_len) {
1338 EVPerr(EVP_F_AEAD_AES_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL); 1339 EVPerr(EVP_F_AEAD_AES_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL);
1339 return -1; 1340 return 0;
1340 } 1341 }
1341 1342
1342 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); 1343 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
1343 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); 1344 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
1344 1345
1345 if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len)) 1346 if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len))
1346 return -1; 1347 return 0;
1347 1348
1348 if (gcm_ctx->ctr) { 1349 if (gcm_ctx->ctr) {
1349 if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk, 1350 if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk,
1350 in_len - bulk, gcm_ctx->ctr)) 1351 in_len - bulk, gcm_ctx->ctr))
1351 return -1; 1352 return 0;
1352 } else { 1353 } else {
1353 if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk, 1354 if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk,
1354 in_len - bulk)) 1355 in_len - bulk))
1355 return -1; 1356 return 0;
1356 } 1357 }
1357 1358
1358 CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len); 1359 CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
1359 return in_len + gcm_ctx->tag_len; 1360 *out_len = in_len + gcm_ctx->tag_len;
1361
1362 return 1;
1360} 1363}
1361 1364
1362static ssize_t 1365static int
1363aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 1366aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
1364 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1367 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
1365 const unsigned char *in, size_t in_len, const unsigned char *ad, 1368 const unsigned char *in, size_t in_len, const unsigned char *ad,
1366 size_t ad_len) 1369 size_t ad_len)
1367{ 1370{
1368 size_t bulk = 0;
1369 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; 1371 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1370 unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN]; 1372 unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN];
1371 size_t out_len;
1372 GCM128_CONTEXT gcm; 1373 GCM128_CONTEXT gcm;
1374 size_t plaintext_len;
1375 size_t bulk = 0;
1373 1376
1374 if (in_len < gcm_ctx->tag_len) { 1377 if (in_len < gcm_ctx->tag_len) {
1375 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT); 1378 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
1376 return -1; 1379 return 0;
1377 } 1380 }
1378 1381
1379 out_len = in_len - gcm_ctx->tag_len; 1382 plaintext_len = in_len - gcm_ctx->tag_len;
1380 1383
1381 if (max_out_len < out_len) { 1384 if (max_out_len < plaintext_len) {
1382 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL); 1385 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL);
1383 return -1; 1386 return 0;
1384 } 1387 }
1385 1388
1386 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); 1389 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
1387 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); 1390 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
1388 1391
1389 if (CRYPTO_gcm128_aad(&gcm, ad, ad_len)) 1392 if (CRYPTO_gcm128_aad(&gcm, ad, ad_len))
1390 return -1; 1393 return 0;
1391 1394
1392 if (gcm_ctx->ctr) { 1395 if (gcm_ctx->ctr) {
1393 if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk, 1396 if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
1394 in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr)) 1397 in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr))
1395 return -1; 1398 return 0;
1396 } else { 1399 } else {
1397 if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk, 1400 if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
1398 in_len - bulk - gcm_ctx->tag_len)) 1401 in_len - bulk - gcm_ctx->tag_len))
1399 return -1; 1402 return 0;
1400 } 1403 }
1401 1404
1402 CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len); 1405 CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
1403 if (CRYPTO_memcmp(tag, in + out_len, gcm_ctx->tag_len) != 0) { 1406 if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
1404 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT); 1407 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
1405 return -1; 1408 return 0;
1406 } 1409 }
1407 1410
1408 return out_len; 1411 *out_len = plaintext_len;
1412
1413 return 1;
1409} 1414}
1410 1415
1411static const EVP_AEAD aead_aes_128_gcm = { 1416static const EVP_AEAD aead_aes_128_gcm = {
diff --git a/src/lib/libcrypto/evp/e_chacha20poly1305.c b/src/lib/libcrypto/evp/e_chacha20poly1305.c
index 7e32668b7f..7aeaf8775d 100644
--- a/src/lib/libcrypto/evp/e_chacha20poly1305.c
+++ b/src/lib/libcrypto/evp/e_chacha20poly1305.c
@@ -82,8 +82,9 @@ aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key,
82 return 0; 82 return 0;
83 } 83 }
84 84
85 /* Internal error - EVP_AEAD_CTX_init should catch this. */
85 if (key_len != sizeof(c20_ctx->key)) 86 if (key_len != sizeof(c20_ctx->key))
86 return 0; /* internal error - EVP_AEAD_CTX_init should catch this. */ 87 return 0;
87 88
88 c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx)); 89 c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx));
89 if (c20_ctx == NULL) 90 if (c20_ctx == NULL)
@@ -100,6 +101,7 @@ static void
100aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) 101aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx)
101{ 102{
102 struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 103 struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
104
103 OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key)); 105 OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key));
104 free(c20_ctx); 106 free(c20_ctx);
105} 107}
@@ -121,11 +123,11 @@ poly1305_update_with_length(poly1305_state *poly1305,
121 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); 123 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
122} 124}
123 125
124static ssize_t 126static int
125aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 127aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
126 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 128 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
127 const unsigned char *in, size_t in_len, const unsigned char *ad, 129 size_t nonce_len, const unsigned char *in, size_t in_len,
128 size_t ad_len) 130 const unsigned char *ad, size_t ad_len)
129{ 131{
130 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 132 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
131 unsigned char poly1305_key[32]; 133 unsigned char poly1305_key[32];
@@ -139,20 +141,20 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
139 * 32-bits and this produces a warning because it's always false. 141 * 32-bits and this produces a warning because it's always false.
140 * Casting to uint64_t inside the conditional is not sufficient to stop 142 * Casting to uint64_t inside the conditional is not sufficient to stop
141 * the warning. */ 143 * the warning. */
142 if (in_len_64 >= (1ull << 32)*64 - 64) { 144 if (in_len_64 >= (1ULL << 32) * 64 - 64) {
143 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE); 145 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE);
144 return -1; 146 return 0;
145 } 147 }
146 148
147 if (max_out_len < in_len + c20_ctx->tag_len) { 149 if (max_out_len < in_len + c20_ctx->tag_len) {
148 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, 150 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL,
149 EVP_R_BUFFER_TOO_SMALL); 151 EVP_R_BUFFER_TOO_SMALL);
150 return -1; 152 return 0;
151 } 153 }
152 154
153 if (nonce_len != CHACHA20_NONCE_LEN) { 155 if (nonce_len != CHACHA20_NONCE_LEN) {
154 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); 156 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE);
155 return -1; 157 return 0;
156 } 158 }
157 159
158 memset(poly1305_key, 0, sizeof(poly1305_key)); 160 memset(poly1305_key, 0, sizeof(poly1305_key));
@@ -168,29 +170,31 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
168 unsigned char tag[POLY1305_TAG_LEN]; 170 unsigned char tag[POLY1305_TAG_LEN];
169 CRYPTO_poly1305_finish(&poly1305, tag); 171 CRYPTO_poly1305_finish(&poly1305, tag);
170 memcpy(out + in_len, tag, c20_ctx->tag_len); 172 memcpy(out + in_len, tag, c20_ctx->tag_len);
171 return in_len + c20_ctx->tag_len; 173 *out_len = in_len + c20_ctx->tag_len;
174 return 1;
172 } 175 }
173 176
174 CRYPTO_poly1305_finish(&poly1305, out + in_len); 177 CRYPTO_poly1305_finish(&poly1305, out + in_len);
175 return in_len + POLY1305_TAG_LEN; 178 *out_len = in_len + POLY1305_TAG_LEN;
179 return 1;
176} 180}
177 181
178static ssize_t 182static int
179aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 183aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
180 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 184 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
181 const unsigned char *in, size_t in_len, const unsigned char *ad, 185 size_t nonce_len, const unsigned char *in, size_t in_len,
182 size_t ad_len) 186 const unsigned char *ad, size_t ad_len)
183{ 187{
184 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 188 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
185 unsigned char mac[POLY1305_TAG_LEN]; 189 unsigned char mac[POLY1305_TAG_LEN];
186 unsigned char poly1305_key[32]; 190 unsigned char poly1305_key[32];
187 size_t out_len;
188 poly1305_state poly1305; 191 poly1305_state poly1305;
189 const uint64_t in_len_64 = in_len; 192 const uint64_t in_len_64 = in_len;
193 size_t plaintext_len;
190 194
191 if (in_len < c20_ctx->tag_len) { 195 if (in_len < c20_ctx->tag_len) {
192 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); 196 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT);
193 return -1; 197 return 0;
194 } 198 }
195 199
196 /* The underlying ChaCha implementation may not overflow the block 200 /* The underlying ChaCha implementation may not overflow the block
@@ -200,22 +204,22 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
200 * 32-bits and this produces a warning because it's always false. 204 * 32-bits and this produces a warning because it's always false.
201 * Casting to uint64_t inside the conditional is not sufficient to stop 205 * Casting to uint64_t inside the conditional is not sufficient to stop
202 * the warning. */ 206 * the warning. */
203 if (in_len_64 >= (1ull << 32)*64 - 64) { 207 if (in_len_64 >= (1ULL << 32) * 64 - 64) {
204 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE); 208 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE);
205 return -1; 209 return 0;
206 } 210 }
207 211
208 if (nonce_len != CHACHA20_NONCE_LEN) { 212 if (nonce_len != CHACHA20_NONCE_LEN) {
209 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); 213 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE);
210 return -1; 214 return 0;
211 } 215 }
212 216
213 out_len = in_len - c20_ctx->tag_len; 217 plaintext_len = in_len - c20_ctx->tag_len;
214 218
215 if (max_out_len < out_len) { 219 if (max_out_len < plaintext_len) {
216 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, 220 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN,
217 EVP_R_BUFFER_TOO_SMALL); 221 EVP_R_BUFFER_TOO_SMALL);
218 return -1; 222 return 0;
219 } 223 }
220 224
221 memset(poly1305_key, 0, sizeof(poly1305_key)); 225 memset(poly1305_key, 0, sizeof(poly1305_key));
@@ -224,17 +228,17 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
224 228
225 CRYPTO_poly1305_init(&poly1305, poly1305_key); 229 CRYPTO_poly1305_init(&poly1305, poly1305_key);
226 poly1305_update_with_length(&poly1305, ad, ad_len); 230 poly1305_update_with_length(&poly1305, ad, ad_len);
227 poly1305_update_with_length(&poly1305, in, out_len); 231 poly1305_update_with_length(&poly1305, in, plaintext_len);
228 CRYPTO_poly1305_finish(&poly1305, mac); 232 CRYPTO_poly1305_finish(&poly1305, mac);
229 233
230 if (CRYPTO_memcmp(mac, in + out_len, c20_ctx->tag_len) != 0) { 234 if (CRYPTO_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
231 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); 235 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT);
232 return -1; 236 return 0;
233 } 237 }
234 238
235 CRYPTO_chacha_20(out, in, out_len, c20_ctx->key, nonce, 1); 239 CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
236 240 *out_len = plaintext_len;
237 return out_len; 241 return 1;
238} 242}
239 243
240static const EVP_AEAD aead_chacha20_poly1305 = { 244static const EVP_AEAD aead_chacha20_poly1305 = {
diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 5cd125894f..3bd36e9266 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1258,49 +1258,51 @@ int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
1258void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); 1258void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
1259 1259
1260/* EVP_AEAD_CTX_seal encrypts and authenticates the input and authenticates 1260/* EVP_AEAD_CTX_seal encrypts and authenticates the input and authenticates
1261 * any additional data (AD). The result is written as output, with the number 1261 * any additional data (AD), the result being written as output. One is
1262 * of bytes written being returned, or -1 on error. 1262 * returned on success, otherwise zero.
1263 * 1263 *
1264 * This function may be called (with the same EVP_AEAD_CTX) concurrently with 1264 * This function may be called (with the same EVP_AEAD_CTX) concurrently with
1265 * itself or EVP_AEAD_CTX_open. 1265 * itself or EVP_AEAD_CTX_open.
1266 * 1266 *
1267 * At most max_out_len bytes are written as output and, in order to ensure 1267 * At most max_out_len bytes are written as output and, in order to ensure
1268 * success, this value should be the length of the input plus the result of 1268 * success, this value should be the length of the input plus the result of
1269 * EVP_AEAD_overhead. 1269 * EVP_AEAD_overhead. On successful return, out_len is set to the actual
1270 * number of bytes written.
1270 * 1271 *
1271 * The length of the nonce is must be equal to the result of 1272 * The length of the nonce is must be equal to the result of
1272 * EVP_AEAD_nonce_length for this AEAD. 1273 * EVP_AEAD_nonce_length for this AEAD.
1273 * 1274 *
1274 * EVP_AEAD_CTX_seal never results in a partial output. If max_out_len is 1275 * EVP_AEAD_CTX_seal never results in a partial output. If max_out_len is
1275 * insufficient, -1 will be returned. 1276 * insufficient, zero will be returned and out_len will be set to zero.
1276 * 1277 *
1277 * If the input and output are aliased then out must be <= in. */ 1278 * If the input and output are aliased then out must be <= in. */
1278ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 1279int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
1279 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1280 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
1280 const unsigned char *in, size_t in_len, const unsigned char *ad, 1281 size_t nonce_len, const unsigned char *in, size_t in_len,
1281 size_t ad_len); 1282 const unsigned char *ad, size_t ad_len);
1282 1283
1283/* EVP_AEAD_CTX_open authenticates the input and additional data, decrypting 1284/* EVP_AEAD_CTX_open authenticates the input and additional data, decrypting
1284 * the input and writing it as output. The number of bytes decrypted and 1285 * the input and writing it as output. One is returned on success, otherwise
1285 * written as output is returned, or -1 on error. 1286 * zero.
1286 * 1287 *
1287 * This function may be called (with the same EVP_AEAD_CTX) concurrently with 1288 * This function may be called (with the same EVP_AEAD_CTX) concurrently with
1288 * itself or EVP_AEAD_CTX_seal. 1289 * itself or EVP_AEAD_CTX_seal.
1289 * 1290 *
1290 * At most the number of input bytes are written as output. In order to ensure 1291 * At most the number of input bytes are written as output. In order to ensure
1291 * success, max_out_len should be at least the same as the input length. 1292 * success, max_out_len should be at least the same as the input length. On
1293 * successful return out_len is set to the actual number of bytes written.
1292 * 1294 *
1293 * The length of nonce must be equal to the result of EVP_AEAD_nonce_length 1295 * The length of nonce must be equal to the result of EVP_AEAD_nonce_length
1294 * for this AEAD. 1296 * for this AEAD.
1295 * 1297 *
1296 * EVP_AEAD_CTX_open never results in a partial output. If max_out_len is 1298 * EVP_AEAD_CTX_open never results in a partial output. If max_out_len is
1297 * insufficient, -1 will be returned. 1299 * insufficient, zero will be returned and out_len will be set to zero.
1298 * 1300 *
1299 * If the input and output are aliased then out must be <= in. */ 1301 * If the input and output are aliased then out must be <= in. */
1300ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 1302int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
1301 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1303 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
1302 const unsigned char *in, size_t in_len, const unsigned char *ad, 1304 size_t nonce_len, const unsigned char *in, size_t in_len,
1303 size_t ad_len); 1305 const unsigned char *ad, size_t ad_len);
1304 1306
1305void EVP_add_alg_module(void); 1307void EVP_add_alg_module(void);
1306 1308
diff --git a/src/lib/libcrypto/evp/evp_aead.c b/src/lib/libcrypto/evp/evp_aead.c
index c8ba1df54a..427bf05467 100644
--- a/src/lib/libcrypto/evp/evp_aead.c
+++ b/src/lib/libcrypto/evp/evp_aead.c
@@ -126,67 +126,59 @@ check_alias(const unsigned char *in, size_t in_len, const unsigned char *out)
126 return 0; 126 return 0;
127} 127}
128 128
129ssize_t 129int
130EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 130EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
131 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 131 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
132 const unsigned char *in, size_t in_len, const unsigned char *ad, 132 const unsigned char *in, size_t in_len, const unsigned char *ad,
133 size_t ad_len) 133 size_t ad_len)
134{ 134{
135 size_t possible_out_len = in_len + ctx->aead->overhead; 135 size_t possible_out_len = in_len + ctx->aead->overhead;
136 ssize_t r;
137 136
138 if (possible_out_len < in_len /* overflow */ || 137 /* Overflow. */
139 possible_out_len > SSIZE_MAX /* return value cannot be 138 if (possible_out_len < in_len) {
140 represented */) { 139 EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
141 EVPerr(EVP_F_EVP_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
142 goto error; 140 goto error;
143 } 141 }
144 142
145 if (!check_alias(in, in_len, out)) { 143 if (!check_alias(in, in_len, out)) {
146 EVPerr(EVP_F_EVP_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT); 144 EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT);
147 goto error; 145 goto error;
148 } 146 }
149 147
150 r = ctx->aead->seal(ctx, out, max_out_len, nonce, nonce_len, 148 if (ctx->aead->seal(ctx, out, out_len, max_out_len, nonce, nonce_len,
151 in, in_len, ad, ad_len); 149 in, in_len, ad, ad_len)) {
152 if (r >= 0) 150 return 1;
153 return r; 151 }
154 152
155error: 153error:
156 /* In the event of an error, clear the output buffer so that a caller 154 /* In the event of an error, clear the output buffer so that a caller
157 * that doesn't check the return value doesn't send raw data. */ 155 * that doesn't check the return value doesn't send raw data. */
158 memset(out, 0, max_out_len); 156 memset(out, 0, max_out_len);
159 return -1; 157 *out_len = 0;
158 return 0;
160} 159}
161 160
162ssize_t 161int
163EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 162EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
164 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 163 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
165 const unsigned char *in, size_t in_len, const unsigned char *ad, 164 const unsigned char *in, size_t in_len, const unsigned char *ad,
166 size_t ad_len) 165 size_t ad_len)
167{ 166{
168 ssize_t r;
169
170 if (in_len > SSIZE_MAX) {
171 EVPerr(EVP_F_EVP_AEAD_CTX_OPEN, EVP_R_TOO_LARGE);
172 goto error; /* may not be able to represent return value. */
173 }
174
175 if (!check_alias(in, in_len, out)) { 167 if (!check_alias(in, in_len, out)) {
176 EVPerr(EVP_F_EVP_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT); 168 EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT);
177 goto error; 169 goto error;
178 } 170 }
179 171
180 r = ctx->aead->open(ctx, out, max_out_len, nonce, nonce_len, 172 if (ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len,
181 in, in_len, ad, ad_len); 173 in, in_len, ad, ad_len)) {
182 174 return 1;
183 if (r >= 0) 175 }
184 return r;
185 176
186error: 177error:
187 /* In the event of an error, clear the output buffer so that a caller 178 /* In the event of an error, clear the output buffer so that a caller
188 * that doesn't check the return value doesn't try and process bad 179 * that doesn't check the return value doesn't try and process bad
189 * data. */ 180 * data. */
190 memset(out, 0, max_out_len); 181 memset(out, 0, max_out_len);
191 return -1; 182 *out_len = 0;
183 return 0;
192} 184}
diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h
index 6f9218eafc..3083f30975 100644
--- a/src/lib/libcrypto/evp/evp_locl.h
+++ b/src/lib/libcrypto/evp/evp_locl.h
@@ -354,13 +354,13 @@ struct evp_aead_st {
354 size_t key_len, size_t tag_len); 354 size_t key_len, size_t tag_len);
355 void (*cleanup)(struct evp_aead_ctx_st*); 355 void (*cleanup)(struct evp_aead_ctx_st*);
356 356
357 ssize_t (*seal)(const struct evp_aead_ctx_st *ctx, unsigned char *out, 357 int (*seal)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
358 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 358 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
359 const unsigned char *in, size_t in_len, const unsigned char *ad, 359 size_t nonce_len, const unsigned char *in, size_t in_len,
360 size_t ad_len); 360 const unsigned char *ad, size_t ad_len);
361 361
362 ssize_t (*open)(const struct evp_aead_ctx_st *ctx, unsigned char *out, 362 int (*open)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
363 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 363 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
364 const unsigned char *in, size_t in_len, const unsigned char *ad, 364 size_t nonce_len, const unsigned char *in, size_t in_len,
365 size_t ad_len); 365 const unsigned char *ad, size_t ad_len);
366}; 366};
diff --git a/src/lib/libssl/src/crypto/evp/e_aes.c b/src/lib/libssl/src/crypto/evp/e_aes.c
index 2e81495e5f..0276cc2bd3 100644
--- a/src/lib/libssl/src/crypto/evp/e_aes.c
+++ b/src/lib/libssl/src/crypto/evp/e_aes.c
@@ -1281,9 +1281,10 @@ aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const unsigned char *key, size_t key_len,
1281 struct aead_aes_gcm_ctx *gcm_ctx; 1281 struct aead_aes_gcm_ctx *gcm_ctx;
1282 const size_t key_bits = key_len * 8; 1282 const size_t key_bits = key_len * 8;
1283 1283
1284 /* EVP_AEAD_CTX_init should catch this. */
1284 if (key_bits != 128 && key_bits != 256) { 1285 if (key_bits != 128 && key_bits != 256) {
1285 EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_BAD_KEY_LENGTH); 1286 EVPerr(EVP_F_AEAD_AES_GCM_INIT, EVP_R_BAD_KEY_LENGTH);
1286 return 0; /* EVP_AEAD_CTX_init should catch this. */ 1287 return 0;
1287 } 1288 }
1288 1289
1289 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) 1290 if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH)
@@ -1324,88 +1325,92 @@ aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx)
1324 free(gcm_ctx); 1325 free(gcm_ctx);
1325} 1326}
1326 1327
1327static ssize_t 1328static int
1328aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 1329aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
1329 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1330 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
1330 const unsigned char *in, size_t in_len, const unsigned char *ad, 1331 const unsigned char *in, size_t in_len, const unsigned char *ad,
1331 size_t ad_len) 1332 size_t ad_len)
1332{ 1333{
1333 size_t bulk = 0;
1334 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; 1334 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1335 GCM128_CONTEXT gcm; 1335 GCM128_CONTEXT gcm;
1336 size_t bulk = 0;
1336 1337
1337 if (max_out_len < in_len + gcm_ctx->tag_len) { 1338 if (max_out_len < in_len + gcm_ctx->tag_len) {
1338 EVPerr(EVP_F_AEAD_AES_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL); 1339 EVPerr(EVP_F_AEAD_AES_GCM_SEAL, EVP_R_BUFFER_TOO_SMALL);
1339 return -1; 1340 return 0;
1340 } 1341 }
1341 1342
1342 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); 1343 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
1343 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); 1344 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
1344 1345
1345 if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len)) 1346 if (ad_len > 0 && CRYPTO_gcm128_aad(&gcm, ad, ad_len))
1346 return -1; 1347 return 0;
1347 1348
1348 if (gcm_ctx->ctr) { 1349 if (gcm_ctx->ctr) {
1349 if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk, 1350 if (CRYPTO_gcm128_encrypt_ctr32(&gcm, in + bulk, out + bulk,
1350 in_len - bulk, gcm_ctx->ctr)) 1351 in_len - bulk, gcm_ctx->ctr))
1351 return -1; 1352 return 0;
1352 } else { 1353 } else {
1353 if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk, 1354 if (CRYPTO_gcm128_encrypt(&gcm, in + bulk, out + bulk,
1354 in_len - bulk)) 1355 in_len - bulk))
1355 return -1; 1356 return 0;
1356 } 1357 }
1357 1358
1358 CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len); 1359 CRYPTO_gcm128_tag(&gcm, out + in_len, gcm_ctx->tag_len);
1359 return in_len + gcm_ctx->tag_len; 1360 *out_len = in_len + gcm_ctx->tag_len;
1361
1362 return 1;
1360} 1363}
1361 1364
1362static ssize_t 1365static int
1363aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 1366aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
1364 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1367 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
1365 const unsigned char *in, size_t in_len, const unsigned char *ad, 1368 const unsigned char *in, size_t in_len, const unsigned char *ad,
1366 size_t ad_len) 1369 size_t ad_len)
1367{ 1370{
1368 size_t bulk = 0;
1369 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; 1371 const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state;
1370 unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN]; 1372 unsigned char tag[EVP_AEAD_AES_GCM_TAG_LEN];
1371 size_t out_len;
1372 GCM128_CONTEXT gcm; 1373 GCM128_CONTEXT gcm;
1374 size_t plaintext_len;
1375 size_t bulk = 0;
1373 1376
1374 if (in_len < gcm_ctx->tag_len) { 1377 if (in_len < gcm_ctx->tag_len) {
1375 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT); 1378 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
1376 return -1; 1379 return 0;
1377 } 1380 }
1378 1381
1379 out_len = in_len - gcm_ctx->tag_len; 1382 plaintext_len = in_len - gcm_ctx->tag_len;
1380 1383
1381 if (max_out_len < out_len) { 1384 if (max_out_len < plaintext_len) {
1382 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL); 1385 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BUFFER_TOO_SMALL);
1383 return -1; 1386 return 0;
1384 } 1387 }
1385 1388
1386 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); 1389 memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm));
1387 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len); 1390 CRYPTO_gcm128_setiv(&gcm, nonce, nonce_len);
1388 1391
1389 if (CRYPTO_gcm128_aad(&gcm, ad, ad_len)) 1392 if (CRYPTO_gcm128_aad(&gcm, ad, ad_len))
1390 return -1; 1393 return 0;
1391 1394
1392 if (gcm_ctx->ctr) { 1395 if (gcm_ctx->ctr) {
1393 if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk, 1396 if (CRYPTO_gcm128_decrypt_ctr32(&gcm, in + bulk, out + bulk,
1394 in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr)) 1397 in_len - bulk - gcm_ctx->tag_len, gcm_ctx->ctr))
1395 return -1; 1398 return 0;
1396 } else { 1399 } else {
1397 if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk, 1400 if (CRYPTO_gcm128_decrypt(&gcm, in + bulk, out + bulk,
1398 in_len - bulk - gcm_ctx->tag_len)) 1401 in_len - bulk - gcm_ctx->tag_len))
1399 return -1; 1402 return 0;
1400 } 1403 }
1401 1404
1402 CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len); 1405 CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
1403 if (CRYPTO_memcmp(tag, in + out_len, gcm_ctx->tag_len) != 0) { 1406 if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
1404 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT); 1407 EVPerr(EVP_F_AEAD_AES_GCM_OPEN, EVP_R_BAD_DECRYPT);
1405 return -1; 1408 return 0;
1406 } 1409 }
1407 1410
1408 return out_len; 1411 *out_len = plaintext_len;
1412
1413 return 1;
1409} 1414}
1410 1415
1411static const EVP_AEAD aead_aes_128_gcm = { 1416static const EVP_AEAD aead_aes_128_gcm = {
diff --git a/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c b/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c
index 7e32668b7f..7aeaf8775d 100644
--- a/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c
+++ b/src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c
@@ -82,8 +82,9 @@ aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const unsigned char *key,
82 return 0; 82 return 0;
83 } 83 }
84 84
85 /* Internal error - EVP_AEAD_CTX_init should catch this. */
85 if (key_len != sizeof(c20_ctx->key)) 86 if (key_len != sizeof(c20_ctx->key))
86 return 0; /* internal error - EVP_AEAD_CTX_init should catch this. */ 87 return 0;
87 88
88 c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx)); 89 c20_ctx = malloc(sizeof(struct aead_chacha20_poly1305_ctx));
89 if (c20_ctx == NULL) 90 if (c20_ctx == NULL)
@@ -100,6 +101,7 @@ static void
100aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) 101aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx)
101{ 102{
102 struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 103 struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
104
103 OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key)); 105 OPENSSL_cleanse(c20_ctx->key, sizeof(c20_ctx->key));
104 free(c20_ctx); 106 free(c20_ctx);
105} 107}
@@ -121,11 +123,11 @@ poly1305_update_with_length(poly1305_state *poly1305,
121 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); 123 CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes));
122} 124}
123 125
124static ssize_t 126static int
125aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 127aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
126 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 128 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
127 const unsigned char *in, size_t in_len, const unsigned char *ad, 129 size_t nonce_len, const unsigned char *in, size_t in_len,
128 size_t ad_len) 130 const unsigned char *ad, size_t ad_len)
129{ 131{
130 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 132 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
131 unsigned char poly1305_key[32]; 133 unsigned char poly1305_key[32];
@@ -139,20 +141,20 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
139 * 32-bits and this produces a warning because it's always false. 141 * 32-bits and this produces a warning because it's always false.
140 * Casting to uint64_t inside the conditional is not sufficient to stop 142 * Casting to uint64_t inside the conditional is not sufficient to stop
141 * the warning. */ 143 * the warning. */
142 if (in_len_64 >= (1ull << 32)*64 - 64) { 144 if (in_len_64 >= (1ULL << 32) * 64 - 64) {
143 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE); 145 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_TOO_LARGE);
144 return -1; 146 return 0;
145 } 147 }
146 148
147 if (max_out_len < in_len + c20_ctx->tag_len) { 149 if (max_out_len < in_len + c20_ctx->tag_len) {
148 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, 150 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL,
149 EVP_R_BUFFER_TOO_SMALL); 151 EVP_R_BUFFER_TOO_SMALL);
150 return -1; 152 return 0;
151 } 153 }
152 154
153 if (nonce_len != CHACHA20_NONCE_LEN) { 155 if (nonce_len != CHACHA20_NONCE_LEN) {
154 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE); 156 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_SEAL, EVP_R_IV_TOO_LARGE);
155 return -1; 157 return 0;
156 } 158 }
157 159
158 memset(poly1305_key, 0, sizeof(poly1305_key)); 160 memset(poly1305_key, 0, sizeof(poly1305_key));
@@ -168,29 +170,31 @@ aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
168 unsigned char tag[POLY1305_TAG_LEN]; 170 unsigned char tag[POLY1305_TAG_LEN];
169 CRYPTO_poly1305_finish(&poly1305, tag); 171 CRYPTO_poly1305_finish(&poly1305, tag);
170 memcpy(out + in_len, tag, c20_ctx->tag_len); 172 memcpy(out + in_len, tag, c20_ctx->tag_len);
171 return in_len + c20_ctx->tag_len; 173 *out_len = in_len + c20_ctx->tag_len;
174 return 1;
172 } 175 }
173 176
174 CRYPTO_poly1305_finish(&poly1305, out + in_len); 177 CRYPTO_poly1305_finish(&poly1305, out + in_len);
175 return in_len + POLY1305_TAG_LEN; 178 *out_len = in_len + POLY1305_TAG_LEN;
179 return 1;
176} 180}
177 181
178static ssize_t 182static int
179aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 183aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
180 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 184 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
181 const unsigned char *in, size_t in_len, const unsigned char *ad, 185 size_t nonce_len, const unsigned char *in, size_t in_len,
182 size_t ad_len) 186 const unsigned char *ad, size_t ad_len)
183{ 187{
184 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; 188 const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state;
185 unsigned char mac[POLY1305_TAG_LEN]; 189 unsigned char mac[POLY1305_TAG_LEN];
186 unsigned char poly1305_key[32]; 190 unsigned char poly1305_key[32];
187 size_t out_len;
188 poly1305_state poly1305; 191 poly1305_state poly1305;
189 const uint64_t in_len_64 = in_len; 192 const uint64_t in_len_64 = in_len;
193 size_t plaintext_len;
190 194
191 if (in_len < c20_ctx->tag_len) { 195 if (in_len < c20_ctx->tag_len) {
192 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); 196 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT);
193 return -1; 197 return 0;
194 } 198 }
195 199
196 /* The underlying ChaCha implementation may not overflow the block 200 /* The underlying ChaCha implementation may not overflow the block
@@ -200,22 +204,22 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
200 * 32-bits and this produces a warning because it's always false. 204 * 32-bits and this produces a warning because it's always false.
201 * Casting to uint64_t inside the conditional is not sufficient to stop 205 * Casting to uint64_t inside the conditional is not sufficient to stop
202 * the warning. */ 206 * the warning. */
203 if (in_len_64 >= (1ull << 32)*64 - 64) { 207 if (in_len_64 >= (1ULL << 32) * 64 - 64) {
204 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE); 208 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_TOO_LARGE);
205 return -1; 209 return 0;
206 } 210 }
207 211
208 if (nonce_len != CHACHA20_NONCE_LEN) { 212 if (nonce_len != CHACHA20_NONCE_LEN) {
209 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE); 213 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_IV_TOO_LARGE);
210 return -1; 214 return 0;
211 } 215 }
212 216
213 out_len = in_len - c20_ctx->tag_len; 217 plaintext_len = in_len - c20_ctx->tag_len;
214 218
215 if (max_out_len < out_len) { 219 if (max_out_len < plaintext_len) {
216 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, 220 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN,
217 EVP_R_BUFFER_TOO_SMALL); 221 EVP_R_BUFFER_TOO_SMALL);
218 return -1; 222 return 0;
219 } 223 }
220 224
221 memset(poly1305_key, 0, sizeof(poly1305_key)); 225 memset(poly1305_key, 0, sizeof(poly1305_key));
@@ -224,17 +228,17 @@ aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
224 228
225 CRYPTO_poly1305_init(&poly1305, poly1305_key); 229 CRYPTO_poly1305_init(&poly1305, poly1305_key);
226 poly1305_update_with_length(&poly1305, ad, ad_len); 230 poly1305_update_with_length(&poly1305, ad, ad_len);
227 poly1305_update_with_length(&poly1305, in, out_len); 231 poly1305_update_with_length(&poly1305, in, plaintext_len);
228 CRYPTO_poly1305_finish(&poly1305, mac); 232 CRYPTO_poly1305_finish(&poly1305, mac);
229 233
230 if (CRYPTO_memcmp(mac, in + out_len, c20_ctx->tag_len) != 0) { 234 if (CRYPTO_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
231 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT); 235 EVPerr(EVP_F_AEAD_CHACHA20_POLY1305_OPEN, EVP_R_BAD_DECRYPT);
232 return -1; 236 return 0;
233 } 237 }
234 238
235 CRYPTO_chacha_20(out, in, out_len, c20_ctx->key, nonce, 1); 239 CRYPTO_chacha_20(out, in, plaintext_len, c20_ctx->key, nonce, 1);
236 240 *out_len = plaintext_len;
237 return out_len; 241 return 1;
238} 242}
239 243
240static const EVP_AEAD aead_chacha20_poly1305 = { 244static const EVP_AEAD aead_chacha20_poly1305 = {
diff --git a/src/lib/libssl/src/crypto/evp/evp.h b/src/lib/libssl/src/crypto/evp/evp.h
index 5cd125894f..3bd36e9266 100644
--- a/src/lib/libssl/src/crypto/evp/evp.h
+++ b/src/lib/libssl/src/crypto/evp/evp.h
@@ -1258,49 +1258,51 @@ int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
1258void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); 1258void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx);
1259 1259
1260/* EVP_AEAD_CTX_seal encrypts and authenticates the input and authenticates 1260/* EVP_AEAD_CTX_seal encrypts and authenticates the input and authenticates
1261 * any additional data (AD). The result is written as output, with the number 1261 * any additional data (AD), the result being written as output. One is
1262 * of bytes written being returned, or -1 on error. 1262 * returned on success, otherwise zero.
1263 * 1263 *
1264 * This function may be called (with the same EVP_AEAD_CTX) concurrently with 1264 * This function may be called (with the same EVP_AEAD_CTX) concurrently with
1265 * itself or EVP_AEAD_CTX_open. 1265 * itself or EVP_AEAD_CTX_open.
1266 * 1266 *
1267 * At most max_out_len bytes are written as output and, in order to ensure 1267 * At most max_out_len bytes are written as output and, in order to ensure
1268 * success, this value should be the length of the input plus the result of 1268 * success, this value should be the length of the input plus the result of
1269 * EVP_AEAD_overhead. 1269 * EVP_AEAD_overhead. On successful return, out_len is set to the actual
1270 * number of bytes written.
1270 * 1271 *
1271 * The length of the nonce is must be equal to the result of 1272 * The length of the nonce is must be equal to the result of
1272 * EVP_AEAD_nonce_length for this AEAD. 1273 * EVP_AEAD_nonce_length for this AEAD.
1273 * 1274 *
1274 * EVP_AEAD_CTX_seal never results in a partial output. If max_out_len is 1275 * EVP_AEAD_CTX_seal never results in a partial output. If max_out_len is
1275 * insufficient, -1 will be returned. 1276 * insufficient, zero will be returned and out_len will be set to zero.
1276 * 1277 *
1277 * If the input and output are aliased then out must be <= in. */ 1278 * If the input and output are aliased then out must be <= in. */
1278ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 1279int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out,
1279 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1280 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
1280 const unsigned char *in, size_t in_len, const unsigned char *ad, 1281 size_t nonce_len, const unsigned char *in, size_t in_len,
1281 size_t ad_len); 1282 const unsigned char *ad, size_t ad_len);
1282 1283
1283/* EVP_AEAD_CTX_open authenticates the input and additional data, decrypting 1284/* EVP_AEAD_CTX_open authenticates the input and additional data, decrypting
1284 * the input and writing it as output. The number of bytes decrypted and 1285 * the input and writing it as output. One is returned on success, otherwise
1285 * written as output is returned, or -1 on error. 1286 * zero.
1286 * 1287 *
1287 * This function may be called (with the same EVP_AEAD_CTX) concurrently with 1288 * This function may be called (with the same EVP_AEAD_CTX) concurrently with
1288 * itself or EVP_AEAD_CTX_seal. 1289 * itself or EVP_AEAD_CTX_seal.
1289 * 1290 *
1290 * At most the number of input bytes are written as output. In order to ensure 1291 * At most the number of input bytes are written as output. In order to ensure
1291 * success, max_out_len should be at least the same as the input length. 1292 * success, max_out_len should be at least the same as the input length. On
1293 * successful return out_len is set to the actual number of bytes written.
1292 * 1294 *
1293 * The length of nonce must be equal to the result of EVP_AEAD_nonce_length 1295 * The length of nonce must be equal to the result of EVP_AEAD_nonce_length
1294 * for this AEAD. 1296 * for this AEAD.
1295 * 1297 *
1296 * EVP_AEAD_CTX_open never results in a partial output. If max_out_len is 1298 * EVP_AEAD_CTX_open never results in a partial output. If max_out_len is
1297 * insufficient, -1 will be returned. 1299 * insufficient, zero will be returned and out_len will be set to zero.
1298 * 1300 *
1299 * If the input and output are aliased then out must be <= in. */ 1301 * If the input and output are aliased then out must be <= in. */
1300ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 1302int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out,
1301 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 1303 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
1302 const unsigned char *in, size_t in_len, const unsigned char *ad, 1304 size_t nonce_len, const unsigned char *in, size_t in_len,
1303 size_t ad_len); 1305 const unsigned char *ad, size_t ad_len);
1304 1306
1305void EVP_add_alg_module(void); 1307void EVP_add_alg_module(void);
1306 1308
diff --git a/src/lib/libssl/src/crypto/evp/evp_aead.c b/src/lib/libssl/src/crypto/evp/evp_aead.c
index c8ba1df54a..427bf05467 100644
--- a/src/lib/libssl/src/crypto/evp/evp_aead.c
+++ b/src/lib/libssl/src/crypto/evp/evp_aead.c
@@ -126,67 +126,59 @@ check_alias(const unsigned char *in, size_t in_len, const unsigned char *out)
126 return 0; 126 return 0;
127} 127}
128 128
129ssize_t 129int
130EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, 130EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
131 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 131 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
132 const unsigned char *in, size_t in_len, const unsigned char *ad, 132 const unsigned char *in, size_t in_len, const unsigned char *ad,
133 size_t ad_len) 133 size_t ad_len)
134{ 134{
135 size_t possible_out_len = in_len + ctx->aead->overhead; 135 size_t possible_out_len = in_len + ctx->aead->overhead;
136 ssize_t r;
137 136
138 if (possible_out_len < in_len /* overflow */ || 137 /* Overflow. */
139 possible_out_len > SSIZE_MAX /* return value cannot be 138 if (possible_out_len < in_len) {
140 represented */) { 139 EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
141 EVPerr(EVP_F_EVP_AEAD_CTX_SEAL, EVP_R_TOO_LARGE);
142 goto error; 140 goto error;
143 } 141 }
144 142
145 if (!check_alias(in, in_len, out)) { 143 if (!check_alias(in, in_len, out)) {
146 EVPerr(EVP_F_EVP_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT); 144 EVPerr(EVP_F_AEAD_CTX_SEAL, EVP_R_OUTPUT_ALIASES_INPUT);
147 goto error; 145 goto error;
148 } 146 }
149 147
150 r = ctx->aead->seal(ctx, out, max_out_len, nonce, nonce_len, 148 if (ctx->aead->seal(ctx, out, out_len, max_out_len, nonce, nonce_len,
151 in, in_len, ad, ad_len); 149 in, in_len, ad, ad_len)) {
152 if (r >= 0) 150 return 1;
153 return r; 151 }
154 152
155error: 153error:
156 /* In the event of an error, clear the output buffer so that a caller 154 /* In the event of an error, clear the output buffer so that a caller
157 * that doesn't check the return value doesn't send raw data. */ 155 * that doesn't check the return value doesn't send raw data. */
158 memset(out, 0, max_out_len); 156 memset(out, 0, max_out_len);
159 return -1; 157 *out_len = 0;
158 return 0;
160} 159}
161 160
162ssize_t 161int
163EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, 162EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, size_t *out_len,
164 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 163 size_t max_out_len, const unsigned char *nonce, size_t nonce_len,
165 const unsigned char *in, size_t in_len, const unsigned char *ad, 164 const unsigned char *in, size_t in_len, const unsigned char *ad,
166 size_t ad_len) 165 size_t ad_len)
167{ 166{
168 ssize_t r;
169
170 if (in_len > SSIZE_MAX) {
171 EVPerr(EVP_F_EVP_AEAD_CTX_OPEN, EVP_R_TOO_LARGE);
172 goto error; /* may not be able to represent return value. */
173 }
174
175 if (!check_alias(in, in_len, out)) { 167 if (!check_alias(in, in_len, out)) {
176 EVPerr(EVP_F_EVP_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT); 168 EVPerr(EVP_F_AEAD_CTX_OPEN, EVP_R_OUTPUT_ALIASES_INPUT);
177 goto error; 169 goto error;
178 } 170 }
179 171
180 r = ctx->aead->open(ctx, out, max_out_len, nonce, nonce_len, 172 if (ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len,
181 in, in_len, ad, ad_len); 173 in, in_len, ad, ad_len)) {
182 174 return 1;
183 if (r >= 0) 175 }
184 return r;
185 176
186error: 177error:
187 /* In the event of an error, clear the output buffer so that a caller 178 /* In the event of an error, clear the output buffer so that a caller
188 * that doesn't check the return value doesn't try and process bad 179 * that doesn't check the return value doesn't try and process bad
189 * data. */ 180 * data. */
190 memset(out, 0, max_out_len); 181 memset(out, 0, max_out_len);
191 return -1; 182 *out_len = 0;
183 return 0;
192} 184}
diff --git a/src/lib/libssl/src/crypto/evp/evp_locl.h b/src/lib/libssl/src/crypto/evp/evp_locl.h
index 6f9218eafc..3083f30975 100644
--- a/src/lib/libssl/src/crypto/evp/evp_locl.h
+++ b/src/lib/libssl/src/crypto/evp/evp_locl.h
@@ -354,13 +354,13 @@ struct evp_aead_st {
354 size_t key_len, size_t tag_len); 354 size_t key_len, size_t tag_len);
355 void (*cleanup)(struct evp_aead_ctx_st*); 355 void (*cleanup)(struct evp_aead_ctx_st*);
356 356
357 ssize_t (*seal)(const struct evp_aead_ctx_st *ctx, unsigned char *out, 357 int (*seal)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
358 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 358 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
359 const unsigned char *in, size_t in_len, const unsigned char *ad, 359 size_t nonce_len, const unsigned char *in, size_t in_len,
360 size_t ad_len); 360 const unsigned char *ad, size_t ad_len);
361 361
362 ssize_t (*open)(const struct evp_aead_ctx_st *ctx, unsigned char *out, 362 int (*open)(const struct evp_aead_ctx_st *ctx, unsigned char *out,
363 size_t max_out_len, const unsigned char *nonce, size_t nonce_len, 363 size_t *out_len, size_t max_out_len, const unsigned char *nonce,
364 const unsigned char *in, size_t in_len, const unsigned char *ad, 364 size_t nonce_len, const unsigned char *in, size_t in_len,
365 size_t ad_len); 365 const unsigned char *ad, size_t ad_len);
366}; 366};