summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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};