diff options
author | Andrey Pronin <apronin@google.com> | 2016-08-18 19:51:20 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-20 20:04:29 -0700 |
commit | 76d1d896009f87172cee13e8761d20eee42039e3 (patch) | |
tree | 065aacbd15f953ddcfa98d0c12df8e9fa14b5308 | |
parent | 152dd753e085a5c91eb74f7e3602c36f6d6bdc1e (diff) | |
download | chrome-ec-76d1d896009f87172cee13e8761d20eee42039e3.tar.gz |
Fix AES CFB encryption for non-divisible-by-16 lengths
BRANCH=none
BUG=chrome-os-partner:56284
TEST=login as new user, check in log that TPM2_Create is
unmarshaled without TPM_RC_INSUFFICIENT errors.
Change-Id: Ie0c0aeb2486b21eaffccf6565f68f4d96f2121bf
Signed-off-by: Andrey Pronin <apronin@google.com>
Reviewed-on: https://chromium-review.googlesource.com/373100
Commit-Ready: Andrey Pronin <apronin@chromium.org>
Tested-by: Andrey Pronin <apronin@chromium.org>
Reviewed-by: Marius Schilder <mschilder@chromium.org>
Reviewed-by: Nagendra Modadugu <ngm@google.com>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r-- | board/cr50/tpm2/aes.c | 32 |
1 files changed, 14 insertions, 18 deletions
diff --git a/board/cr50/tpm2/aes.c b/board/cr50/tpm2/aes.c index f0a63c1a7b..0882e776f0 100644 --- a/board/cr50/tpm2/aes.c +++ b/board/cr50/tpm2/aes.c @@ -119,34 +119,30 @@ CRYPT_RESULT _cpri__AESEncryptCFB( uint8_t *out, uint32_t num_bits, uint8_t *key, uint8_t *iv, uint32_t len, uint8_t *in) { - uint8_t *ivp = NULL; - int32_t slen; - int i; - if (len == 0) return CRYPT_SUCCESS; assert(out != NULL && key != NULL && iv != NULL && in != NULL); assert(len <= INT32_MAX); - slen = (int32_t) len; if (!DCRYPTO_aes_init(key, num_bits, iv, CIPHER_MODE_CTR, ENCRYPT_MODE)) return CRYPT_PARAMETER; - for (; slen > 0; slen -= 16) { + for (; len >= 16; len -= 16, in += 16, out += 16) { DCRYPTO_aes_block(in, out); - ivp = iv; - for (i = slen < 16 ? slen : 16; i > 0; i--) { - *ivp++ = *out++; - in++; - } - DCRYPTO_aes_write_iv(iv); + DCRYPTO_aes_write_iv(out); + } + if (len > 0) { + uint8_t buf[16]; + + memcpy(buf, in, len); + memset(buf+len, 0, 16-len); + DCRYPTO_aes_block(buf, buf); + memcpy(out, buf, len); + memcpy(iv, buf, len); + memset(iv+len, 0, 16-len); + } else { + memcpy(iv, out-16, 16); } - /* 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 many bytes are needed - * to pad out the IV for the next round. */ - for (; slen < 0; slen++) - *ivp++ = 0; return CRYPT_SUCCESS; } |