diff options
-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; } |