diff options
author | nagendra modadugu <ngm@google.com> | 2017-01-04 21:08:17 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-01-27 03:50:47 -0800 |
commit | bb55470b0e0a2dd085a26cb1fbdb2428f3cfea4f (patch) | |
tree | 58504480ed664aa52e958802914ae449c186be1e /board/cr50/tpm2/aes.c | |
parent | c05d723dcf1f59dc8fe4655f7d5dd16647a13216 (diff) | |
download | chrome-ec-bb55470b0e0a2dd085a26cb1fbdb2428f3cfea4f.tar.gz |
CR50: add a hardware backed GCM implementation
This change adds hardware support for AES128-GCM
along with a subset of NIST test vectors.
BRANCH=none
BUG=chrome-os-partner:60833
CQ-DEPEND=CL:411535
TEST=tpmtest.py passes
Change-Id: I93445684f6a910c35a9117eac6cb19d28067a021
Signed-off-by: nagendra modadugu <ngm@google.com>
Reviewed-on: https://chromium-review.googlesource.com/425002
Commit-Ready: Nagendra Modadugu <ngm@google.com>
Tested-by: Marius Schilder <mschilder@chromium.org>
Tested-by: Nagendra Modadugu <ngm@google.com>
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
Diffstat (limited to 'board/cr50/tpm2/aes.c')
-rw-r--r-- | board/cr50/tpm2/aes.c | 84 |
1 files changed, 83 insertions, 1 deletions
diff --git a/board/cr50/tpm2/aes.c b/board/cr50/tpm2/aes.c index 164f08aeb5..72148fb0ec 100644 --- a/board/cr50/tpm2/aes.c +++ b/board/cr50/tpm2/aes.c @@ -228,6 +228,8 @@ static void aes_command_handler(void *cmd_body, uint16_t key_len; uint8_t iv_len; uint8_t *iv; + uint8_t aad_len; + const uint8_t *aad; enum aes_test_cipher_mode c_mode; enum encrypt_mode e_mode; uint8_t *cmd = (uint8_t *)cmd_body; @@ -262,6 +264,8 @@ static void aes_command_handler(void *cmd_body, * key | key len | key to use * iv_len | 1 | either 0 or 16 * iv | 0 or 16 | as defined by iv_len + * aad_len | <= 127 | additional authentication data length + * aad | aad_len | additional authentication data * text_len | 2 | size of the text to process, big endian * text | text_len | text to encrypt/decrypt */ @@ -277,12 +281,16 @@ static void aes_command_handler(void *cmd_body, cmd += key_len; key_len *= 8; iv_len = *cmd++; - if (iv_len && (iv_len != 16)) { + if ((c_mode == TEST_MODE_GCM && iv_len == 0) || + (c_mode != TEST_MODE_GCM && iv_len && iv_len != 16)) { CPRINTF("Invalid vector len %d\n", iv_len); return; } iv = cmd; cmd += iv_len; + aad_len = *cmd++; + aad = cmd; + cmd += aad_len; data_len = *cmd++; data_len = data_len * 256 + *cmd++; @@ -388,6 +396,80 @@ static void aes_command_handler(void *cmd_body, } break; } + case TEST_MODE_GCM: + { + if (e_mode == 0) { + size_t total; + size_t count; + struct GCM_CTX ctx; + + DCRYPTO_gcm_init(&ctx, key_local.b, iv_local.b, iv_len); + DCRYPTO_gcm_aad(&ctx, aad, aad_len); + count = DCRYPTO_gcm_decrypt( + &ctx, out_local.b, sizeof(out_local.b), + data_local.b, data_len); + if (count < 0) { + CPRINTF( + "%s: gcm decrypt failed\n", __func__); + break; + } + total = count; + count = DCRYPTO_gcm_decrypt_final( + &ctx, out_local.b + total, + sizeof(out_local.b) - total); + if (count < 0) { + CPRINTF( + "%s: gcm decrypt_final failed\n", + __func__); + break; + } + total += count; + count = DCRYPTO_gcm_tag(&ctx, out_local.b + total, + sizeof(out_local.b) - total); + if (count == 0) { + CPRINTF("%s: gcm tag failed\n", __func__); + break; + } + total += count; + *response_size = total; + } else if (e_mode == 1) { + size_t total; + size_t count; + struct GCM_CTX ctx; + + DCRYPTO_gcm_init(&ctx, key_local.b, iv_local.b, iv_len); + DCRYPTO_gcm_aad(&ctx, aad, aad_len); + count = DCRYPTO_gcm_encrypt( + &ctx, out_local.b, sizeof(out_local.b), + data_local.b, data_len); + if (count < 0) { + CPRINTF( + "%s: gcm encrypt failed\n"); + break; + } + total = count; + count = DCRYPTO_gcm_encrypt_final( + &ctx, out_local.b + total, + sizeof(out_local.b) - total); + if (count < 0) { + CPRINTF( + "%s: gcm encrypt_final failed\n", + __func__); + break; + } + total += count; + count = DCRYPTO_gcm_tag( + &ctx, out_local.b + total, + sizeof(out_local.b) - total); + if (count == 0) { + CPRINTF("%s: gcm tag failed\n", __func__); + break; + } + total += count; + *response_size = total; + } + break; + } case TEST_MODE_OFB: if (e_mode == 0) { if (_cpri__AESDecryptOFB( |