summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagendra modadugu <ngm@google.com>2016-02-19 14:43:53 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-02-23 12:19:28 -0800
commit9f5782ba05dcf21e85e7c26e49df5630df38967b (patch)
treeb40db1efeed5b8a80f0783d636f3075ec216110f
parent2af857276d8653a021a14a867f2402bc7c67632f (diff)
downloadchrome-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>
-rw-r--r--board/cr50/tpm2/aes.c53
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;
}