summaryrefslogtreecommitdiff
path: root/board/cr50/tpm2/aes.c
diff options
context:
space:
mode:
authornagendra modadugu <ngm@google.com>2017-01-04 21:08:17 -0800
committerchrome-bot <chrome-bot@chromium.org>2017-01-27 03:50:47 -0800
commitbb55470b0e0a2dd085a26cb1fbdb2428f3cfea4f (patch)
tree58504480ed664aa52e958802914ae449c186be1e /board/cr50/tpm2/aes.c
parentc05d723dcf1f59dc8fe4655f7d5dd16647a13216 (diff)
downloadchrome-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.c84
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(