diff options
author | nagendra modadugu <ngm@google.com> | 2016-02-19 14:43:53 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-02-23 12:19:28 -0800 |
commit | 9f5782ba05dcf21e85e7c26e49df5630df38967b (patch) | |
tree | b40db1efeed5b8a80f0783d636f3075ec216110f /board | |
parent | 2af857276d8653a021a14a867f2402bc7c67632f (diff) | |
download | chrome-ec-9f5782ba05dcf21e85e7c26e49df5630df38967b.tar.gz |
CR50: add in-place decrypt support for AES-CFB
The api _cpri__AESDecryptCFB is expected to
support in-place decryption, which the previous
implementation did not support (i.e. part of
the input was was written to prior to being read).
Switch to CTR mode to ECB mode in order to support
in-place decrypt.
BRANCH=none
BUG=chrome-os-partner:43025,chrome-os-partner:47524
TEST=corresponding TPM2 test suite command passes
Change-Id: I8a096bdab7a1ca130a07d992c9fce3fc19016e17
Signed-off-by: nagendra modadugu <ngm@google.com>
Reviewed-on: https://chromium-review.googlesource.com/328761
Commit-Ready: Nagendra Modadugu <ngm@google.com>
Tested-by: Nagendra Modadugu <ngm@google.com>
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Diffstat (limited to 'board')
-rw-r--r-- | board/cr50/tpm2/aes.c | 53 |
1 files changed, 17 insertions, 36 deletions
diff --git a/board/cr50/tpm2/aes.c b/board/cr50/tpm2/aes.c index a751e9134e..214e18788a 100644 --- a/board/cr50/tpm2/aes.c +++ b/board/cr50/tpm2/aes.c @@ -37,51 +37,32 @@ CRYPT_RESULT _cpri__AESDecryptCFB(uint8_t *out, uint32_t num_bits, uint8_t *key, uint8_t *iv, uint32_t len, uint8_t *in) { - uint8_t *ivp = NULL; - int i; - int32_t slen; - if (len == 0) return CRYPT_SUCCESS; - assert(key != NULL && iv != NULL && out != NULL && in != NULL); - assert(len <= INT32_MAX); - slen = (int32_t) len; + /* Initialize AES hardware. */ - if (!DCRYPTO_aes_init(key, num_bits, iv, CIPHER_MODE_CTR, ENCRYPT_MODE)) + if (!DCRYPTO_aes_init(key, num_bits, NULL, + CIPHER_MODE_ECB, ENCRYPT_MODE)) return CRYPT_PARAMETER; - for (; slen > 0; slen -= 16) { - uint8_t tmpin[16]; - uint8_t tmpout[16]; - const uint8_t *inp; - uint8_t *outp; + while (len > 0) { + int i; + size_t chunk_len; + uint8_t mask[16]; - if (slen < 16) { - memcpy(tmpin, in, slen); - inp = tmpin; - outp = tmpout; - } else { - inp = in; - outp = out; - } - DCRYPTO_aes_block(inp, outp); - if (outp != out) - memcpy(out, outp, slen); + chunk_len = MIN(len, 16); - ivp = iv; - for (i = (slen < 16) ? slen : 16; i > 0; i--) { - *ivp++ = *in++; - out++; - } - DCRYPTO_aes_write_iv(iv); + DCRYPTO_aes_block(iv, mask); + + memcpy(iv, in, chunk_len); + if (chunk_len != 16) + memset(iv + chunk_len, 0, 16 - chunk_len); + + for (i = 0; i < chunk_len; i++) + *out++ = *in++ ^ mask[i]; + len -= chunk_len; } - /* If the inner loop (i loop) was smaller than 16, then slen - * would have been smaller than 16 and it is now negative - * If it is negative, then it indicates how may fill bytes - * are needed to pad out the IV for the next round. */ - for (; slen < 0; slen++) - *ivp++ = 0; return CRYPT_SUCCESS; } |