summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrey Pronin <apronin@google.com>2016-08-18 19:51:20 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-08-20 20:04:29 -0700
commit76d1d896009f87172cee13e8761d20eee42039e3 (patch)
tree065aacbd15f953ddcfa98d0c12df8e9fa14b5308
parent152dd753e085a5c91eb74f7e3602c36f6d6bdc1e (diff)
downloadchrome-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.c32
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;
}