summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVadim Sukhomlinov <sukhomlinov@google.com>2021-09-16 17:47:39 -0700
committerCommit Bot <commit-bot@chromium.org>2021-09-17 20:44:08 +0000
commit222f2fb900fc74a369aa80163219eba323f1ad75 (patch)
tree404b7af0afb9add54bed20d3cd3acd3013df366d
parentb89dd9906c4b990d45d48195368df1cfb583b9b0 (diff)
downloadchrome-ec-222f2fb900fc74a369aa80163219eba323f1ad75.tar.gz
cr50: implement AES using aligned memory access
Folks working on other Haven firmware shared issue that our code for unaligned access is sensitive to compiler version and with updated gcc results in broken code. Replacing access_helper with aligned access and memcpy into aligned buffer if unaligned data is provided results in smaller and faster code. Unaligned access unfortunately results in quite lengthy code. Specifically for AES I got back 312 bytes. BUG=none TEST=make BOARD=cr50 CRYPTO_TEST=1; test/tpm_test + TCG tests Signed-off-by: Vadim Sukhomlinov <sukhomlinov@google.com> Change-Id: Ie03b7ce3a24c4fea0506c204fce82bca719f1b79 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3167003 Reviewed-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Reviewed-by: Andrey Pronin <apronin@chromium.org> Tested-by: Vadim Sukhomlinov <sukhomlinov@chromium.org> Commit-Queue: Vadim Sukhomlinov <sukhomlinov@chromium.org>
-rw-r--r--board/cr50/dcrypto/aes.c65
1 files changed, 47 insertions, 18 deletions
diff --git a/board/cr50/dcrypto/aes.c b/board/cr50/dcrypto/aes.c
index f5cc0e6d8f..b1b8021728 100644
--- a/board/cr50/dcrypto/aes.c
+++ b/board/cr50/dcrypto/aes.c
@@ -75,23 +75,28 @@ int DCRYPTO_aes_init(const uint8_t *key, uint32_t key_len, const uint8_t *iv,
}
/* Initialize IV for modes that require it. */
- if (iv) {
- p = (struct access_helper *) iv;
- for (i = 0; i < 4; i++)
- GR_KEYMGR_AES_CTR(i) = p[i].udata;
- }
+ if (iv)
+ DCRYPTO_aes_write_iv(iv);
+
return 1;
}
int DCRYPTO_aes_block(const uint8_t *in, uint8_t *out)
{
int i;
- struct access_helper *outw;
- const struct access_helper *inw = (struct access_helper *) in;
+ uint32_t buf[4];
+ const uint32_t *inw;
+ uint32_t *outw;
+
+ if (is_not_aligned(in)) {
+ memcpy(buf, in, sizeof(buf));
+ inw = buf;
+ } else
+ inw = (const uint32_t *)in;
/* Write plaintext. */
for (i = 0; i < 4; i++)
- GREG32(KEYMGR, AES_WFIFO_DATA) = inw[i].udata;
+ GREG32(KEYMGR, AES_WFIFO_DATA) = inw[i];
/* Wait for the result. */
if (!wait_read_data(GREG32_ADDR(KEYMGR, AES_RFIFO_EMPTY))) {
@@ -100,28 +105,52 @@ int DCRYPTO_aes_block(const uint8_t *in, uint8_t *out)
}
/* Read ciphertext. */
- outw = (struct access_helper *) out;
+ if (is_not_aligned(out))
+ outw = buf;
+ else
+ outw = (uint32_t *)out;
+
for (i = 0; i < 4; i++)
- outw[i].udata = GREG32(KEYMGR, AES_RFIFO_DATA);
+ outw[i] = GREG32(KEYMGR, AES_RFIFO_DATA);
+
+ if (out != (uint8_t *)outw)
+ memcpy(out, outw, sizeof(buf));
+
return 1;
}
void DCRYPTO_aes_write_iv(const uint8_t *iv)
{
int i;
- const struct access_helper *p = (const struct access_helper *) iv;
+ uint32_t buf[4];
+ const uint32_t *ivw;
+
+ if (is_not_aligned(iv)) {
+ memcpy(buf, iv, sizeof(buf));
+ ivw = buf;
+ } else
+ ivw = (uint32_t *)iv;
for (i = 0; i < 4; i++)
- GR_KEYMGR_AES_CTR(i) = p[i].udata;
+ GR_KEYMGR_AES_CTR(i) = ivw[i];
}
void DCRYPTO_aes_read_iv(uint8_t *iv)
{
int i;
- struct access_helper *p = (struct access_helper *) iv;
+ uint32_t buf[4];
+ uint32_t *ivw;
+
+ if (is_not_aligned(iv))
+ ivw = buf;
+ else
+ ivw = (uint32_t *)iv;
for (i = 0; i < 4; i++)
- p[i].udata = GR_KEYMGR_AES_CTR(i);
+ ivw[i] = GR_KEYMGR_AES_CTR(i);
+
+ if (iv != (uint8_t *)ivw)
+ memcpy(iv, ivw, sizeof(buf));
}
int DCRYPTO_aes_ctr(uint8_t *out, const uint8_t *key, uint32_t key_bits,
@@ -133,16 +162,16 @@ int DCRYPTO_aes_ctr(uint8_t *out, const uint8_t *key, uint32_t key_bits,
return 0;
while (in_len > 0) {
- uint8_t tmpin[16];
- uint8_t tmpout[16];
+ uint32_t tmpin[4];
+ uint32_t tmpout[4];
const uint8_t *inp;
uint8_t *outp;
const size_t count = MIN(in_len, 16);
if (count < 16) {
memcpy(tmpin, in, count);
- inp = tmpin;
- outp = tmpout;
+ inp = (uint8_t *)tmpin;
+ outp = (uint8_t *)tmpout;
} else {
inp = in;
outp = out;