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 /src/lib/libcrypto/evp/e_aes.c | |
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@
Diffstat (limited to 'src/lib/libcrypto/evp/e_aes.c')
-rw-r--r-- | src/lib/libcrypto/evp/e_aes.c | 51 |
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 | ||
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 = { |