diff --git a/library/aes.c b/library/aes.c index f0ade21490..6306fecf84 100644 --- a/library/aes.c +++ b/library/aes.c @@ -661,6 +661,16 @@ int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key, } #endif +#if defined(MBEDTLS_AESCE_C) && defined(MBEDTLS_HAVE_ARM64) + if (mbedtls_aesce_has_support()) { + mbedtls_aesce_inverse_key( + (unsigned char *) RK, + (const unsigned char *) (cty.buf + cty.rk_offset), + ctx->nr); + goto exit; + } +#endif + SK = cty.buf + cty.rk_offset + cty.nr * 4; *RK++ = *SK++; diff --git a/library/aesce.c b/library/aesce.c index 4b0f9d7449..ba9adc95cb 100644 --- a/library/aesce.c +++ b/library/aesce.c @@ -66,6 +66,24 @@ int mbedtls_aesce_has_support(void) } +/* + * Compute decryption round keys from encryption round keys + */ +void mbedtls_aesce_inverse_key(unsigned char *invkey, + const unsigned char *fwdkey, + int nr) +{ + int i, j; + j = nr; + vst1q_u8(invkey, vld1q_u8(fwdkey + j * 16)); + for (i = 1, j--; j > 0; i++, j--) { + vst1q_u8(invkey + i * 16, + vaesimcq_u8(vld1q_u8(fwdkey + j * 16))); + } + vst1q_u8(invkey + i * 16, vld1q_u8(fwdkey + j * 16)); + +} + static uint8_t const rcon[] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; diff --git a/library/aesce.h b/library/aesce.h index 7fc0cfa0eb..d0e02a49d8 100644 --- a/library/aesce.h +++ b/library/aesce.h @@ -50,6 +50,18 @@ extern "C" { int mbedtls_aesce_has_support(void); +/** + * \brief Internal round key inversion. This function computes + * decryption round keys from the encryption round keys. + * + * \param invkey Round keys for the equivalent inverse cipher + * \param fwdkey Original round keys (for encryption) + * \param nr Number of rounds (that is, number of round keys minus one) + */ +void mbedtls_aesce_inverse_key(unsigned char *invkey, + const unsigned char *fwdkey, + int nr); + /** * \brief Internal key expansion for encryption *