summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/evp/e_aes.c
diff options
context:
space:
mode:
authorjsing <>2014-05-26 13:01:58 +0000
committerjsing <>2014-05-26 13:01:58 +0000
commit1e04f96479c885fa94175f42f348872cbdd3c9d4 (patch)
tree2d8c2f3b74e112db8f84b41231b2cde79d0be571 /src/lib/libcrypto/evp/e_aes.c
parent3ebf48c494177b3b775febf8302322375c80fe3b (diff)
downloadopenbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.tar.gz
openbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.tar.bz2
openbsd-1e04f96479c885fa94175f42f348872cbdd3c9d4.zip
Implement an improved version of the EVP AEAD API. The
EVP_AEAD_CTX_{open,seal} functions previously returned an ssize_t that was overloaded to indicate success/failure, along with the number of bytes written as output. This change adds an explicit *out_len argument which is used to return the number of output bytes and the return value is now an int that is purely used to identify success or failure. This change effectively rides the last libcrypto crank (although I do not expect there to be many users of the EVP AEAD API currently). Thanks to Adam Langley for providing the improved code that this diff is based on. ok miod@
Diffstat (limited to 'src/lib/libcrypto/evp/e_aes.c')
-rw-r--r--src/lib/libcrypto/evp/e_aes.c51
1 files changed, 28 insertions, 23 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 = {