diff options
author | jsing <> | 2014-05-26 13:01:58 +0000 |
---|---|---|
committer | jsing <> | 2014-05-26 13:01:58 +0000 |
commit | 1e04f96479c885fa94175f42f348872cbdd3c9d4 (patch) | |
tree | 2d8c2f3b74e112db8f84b41231b2cde79d0be571 | |
parent | 3ebf48c494177b3b775febf8302322375c80fe3b (diff) | |
download | openbsd-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@
-rw-r--r-- | src/lib/libcrypto/evp/e_aes.c | 51 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/e_chacha20poly1305.c | 62 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/evp.h | 34 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/evp_aead.c | 50 | ||||
-rw-r--r-- | src/lib/libcrypto/evp/evp_locl.h | 18 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/evp/e_aes.c | 51 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/evp/e_chacha20poly1305.c | 62 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/evp/evp.h | 34 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/evp/evp_aead.c | 50 | ||||
-rw-r--r-- | src/lib/libssl/src/crypto/evp/evp_locl.h | 18 |
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 | ||
1327 | static ssize_t | 1328 | static int |
1328 | aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1329 | aead_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 | ||
1362 | static ssize_t | 1365 | static int |
1363 | aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1366 | aead_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 | ||
1411 | static const EVP_AEAD aead_aes_128_gcm = { | 1416 | static 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 | |||
100 | aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) | 101 | aead_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 | ||
124 | static ssize_t | 126 | static int |
125 | aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 127 | aead_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 | ||
178 | static ssize_t | 182 | static int |
179 | aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 183 | aead_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 | ||
240 | static const EVP_AEAD aead_chacha20_poly1305 = { | 244 | static 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, | |||
1258 | void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); | 1258 | void 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. */ |
1278 | ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1279 | int 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. */ |
1300 | ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1302 | int 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 | ||
1305 | void EVP_add_alg_module(void); | 1307 | void 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 | ||
129 | ssize_t | 129 | int |
130 | EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 130 | EVP_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 | ||
155 | error: | 153 | error: |
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 | ||
162 | ssize_t | 161 | int |
163 | EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 162 | EVP_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 | ||
186 | error: | 177 | error: |
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 | ||
1327 | static ssize_t | 1328 | static int |
1328 | aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1329 | aead_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 | ||
1362 | static ssize_t | 1365 | static int |
1363 | aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1366 | aead_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 | ||
1411 | static const EVP_AEAD aead_aes_128_gcm = { | 1416 | static 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 | |||
100 | aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) | 101 | aead_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 | ||
124 | static ssize_t | 126 | static int |
125 | aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 127 | aead_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 | ||
178 | static ssize_t | 182 | static int |
179 | aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 183 | aead_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 | ||
240 | static const EVP_AEAD aead_chacha20_poly1305 = { | 244 | static 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, | |||
1258 | void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); | 1258 | void 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. */ |
1278 | ssize_t EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1279 | int 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. */ |
1300 | ssize_t EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 1302 | int 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 | ||
1305 | void EVP_add_alg_module(void); | 1307 | void 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 | ||
129 | ssize_t | 129 | int |
130 | EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, unsigned char *out, | 130 | EVP_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 | ||
155 | error: | 153 | error: |
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 | ||
162 | ssize_t | 161 | int |
163 | EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, unsigned char *out, | 162 | EVP_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 | ||
186 | error: | 177 | error: |
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 | }; |