mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-22 01:27:11 +08:00
Merge branch 'feature/add_aes_xts_to_util' into 'master'
util: add AES XTS and its unit test See merge request sdk/ESP8266_RTOS_SDK!1114
This commit is contained in:
@ -27,6 +27,10 @@ typedef struct esp_aes {
|
||||
uint32_t buf[68]; /*!< The AES calculation cache */
|
||||
} esp_aes_t;
|
||||
|
||||
typedef struct esp_aes_xts {
|
||||
esp_aes_t crypt; /*!< The AES context to use for AES block encryption or decryption. */
|
||||
esp_aes_t tweak; /*!< The AES context used for tweak computation. */
|
||||
} esp_aes_xts_t;
|
||||
|
||||
/**
|
||||
* @brief Set AES encrypt key
|
||||
@ -225,6 +229,42 @@ static inline int esp_aes_decrypt_ctr(esp_aes_t *aes, size_t *nc_off, void *p_no
|
||||
return esp_aes_encrypt_ctr(aes, nc_off, p_nonce_counter, p_stream_block, p_src, slen, p_dst, dlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set AES XTS encrypt key
|
||||
*
|
||||
* @param aes AES XTS contex pointer
|
||||
* @param p_key AES XTS key data buffer
|
||||
* @param keybits number of AES XTS key bits
|
||||
*
|
||||
* @return 0 if success or fail
|
||||
*/
|
||||
int esp_aes_xts_set_encrypt_key(esp_aes_xts_t *aes, const void *p_key, size_t keybits);
|
||||
|
||||
/**
|
||||
* @brief Set AES XTS decrypt key
|
||||
*
|
||||
* @param aes AES XTS contex pointer
|
||||
* @param p_key AES XTS key data buffer
|
||||
* @param keybits number of AES XTS key bits
|
||||
*
|
||||
* @return 0 if success or fail
|
||||
*/
|
||||
int esp_aes_xts_set_decrypt_key(esp_aes_xts_t *aes, const void *p_key, size_t keybits);
|
||||
|
||||
/**
|
||||
* @brief AES XTS encrypt/decrypt calculation
|
||||
*
|
||||
* @param aes AES contex pointer
|
||||
* @param encrypt 1 : encrypt, 0 : decrypt
|
||||
* @param length data unit data length by bytes
|
||||
* @param p_data_unit data unit buffer
|
||||
* @param p_src input data buffer
|
||||
* @param p_dst output data buffer
|
||||
*
|
||||
* @return 0 if success or fail
|
||||
*/
|
||||
int esp_aes_crypt_xts(esp_aes_xts_t *aes, int encrypt, size_t length, const void *p_data_unit, const void *p_src, void *p_dst);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -528,7 +528,7 @@ static void __esp_aes_encrypt(esp_aes_t *aes, const void *p_src, void *p_dst)
|
||||
PUT_UINT32_LE(X3, output, 12);
|
||||
}
|
||||
|
||||
static int __esp_aes_decrypt(esp_aes_t *aes, const void *p_src, void *p_dst)
|
||||
static void __esp_aes_decrypt(esp_aes_t *aes, const void *p_src, void *p_dst)
|
||||
{
|
||||
int i;
|
||||
uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3;
|
||||
@ -573,8 +573,6 @@ static int __esp_aes_decrypt(esp_aes_t *aes, const void *p_src, void *p_dst)
|
||||
PUT_UINT32_LE(X1, output, 4);
|
||||
PUT_UINT32_LE(X2, output, 8);
|
||||
PUT_UINT32_LE(X3, output, 12);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int esp_aes_encrypt(esp_aes_t *aes,
|
||||
@ -864,3 +862,147 @@ int esp_aes_encrypt_ctr(esp_aes_t *aes,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void aes_xts_decode_keys(const uint8_t *key,
|
||||
size_t keybits,
|
||||
const uint8_t **key1,
|
||||
size_t *key1bits,
|
||||
const uint8_t **key2,
|
||||
size_t *key2bits)
|
||||
{
|
||||
const size_t half_keybits = keybits / 2;
|
||||
const size_t half_keybytes = half_keybits / 8;
|
||||
|
||||
*key1bits = half_keybits;
|
||||
*key2bits = half_keybits;
|
||||
*key1 = &key[0];
|
||||
*key2 = &key[half_keybytes];
|
||||
}
|
||||
|
||||
static void aes_gf128mul_x_ble(uint8_t *r, const uint8_t *i)
|
||||
{
|
||||
uint64_t x[2], y[2];
|
||||
|
||||
memcpy(x, i, 16);
|
||||
|
||||
y[0] = (x[0] << 1) ^ 0x0087 >> (8 - ((x[1] >> 63 ) << 3));
|
||||
y[1] = (x[0] >> 63) | (x[1] << 1);
|
||||
|
||||
memcpy(r, y, 16);
|
||||
}
|
||||
|
||||
int esp_aes_xts_set_encrypt_key(esp_aes_xts_t *ctx, const void *p_key, size_t keybits)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *key1, *key2;
|
||||
size_t key1bits, key2bits;
|
||||
const uint8_t *key = (const uint8_t *)p_key;
|
||||
|
||||
util_assert(ctx);
|
||||
util_assert(key);
|
||||
|
||||
if (keybits != 256 && keybits != 512)
|
||||
return -EINVAL;
|
||||
|
||||
aes_xts_decode_keys(key, keybits, &key1, &key1bits, &key2, &key2bits);
|
||||
|
||||
ret = esp_aes_set_encrypt_key(&ctx->tweak, key2, key2bits);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return esp_aes_set_encrypt_key(&ctx->crypt, key1, key1bits);
|
||||
}
|
||||
|
||||
int esp_aes_xts_set_decrypt_key(esp_aes_xts_t *ctx, const void *p_key, size_t keybits)
|
||||
{
|
||||
int ret;
|
||||
const uint8_t *key1, *key2;
|
||||
size_t key1bits, key2bits;
|
||||
const uint8_t *key = (const uint8_t *)p_key;
|
||||
|
||||
util_assert(ctx);
|
||||
util_assert(key);
|
||||
|
||||
if (keybits != 256 && keybits != 512)
|
||||
return -EINVAL;
|
||||
|
||||
aes_xts_decode_keys(key, keybits, &key1, &key1bits, &key2, &key2bits);
|
||||
|
||||
ret = esp_aes_set_encrypt_key(&ctx->tweak, key2, key2bits);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return esp_aes_set_decrypt_key(&ctx->crypt, key1, key1bits);
|
||||
}
|
||||
|
||||
int esp_aes_crypt_xts(esp_aes_xts_t *ctx,
|
||||
int encrypt,
|
||||
size_t length,
|
||||
const void *p_data_unit,
|
||||
const void *p_src,
|
||||
void *p_dst)
|
||||
{
|
||||
size_t blocks = length / 16;
|
||||
size_t leftover = length % 16;
|
||||
uint8_t tweak[16];
|
||||
uint8_t prev_tweak[16];
|
||||
uint8_t tmp[16];
|
||||
void (*crypt_func)(esp_aes_t *aes, const void *p_src, void *p_dst);
|
||||
|
||||
const uint8_t *data_unit = (const uint8_t *)p_data_unit;
|
||||
const uint8_t *input = (const uint8_t *)p_src;
|
||||
uint8_t *output = (uint8_t *)p_dst;
|
||||
|
||||
util_assert(ctx);
|
||||
util_assert(data_unit);
|
||||
util_assert(input);
|
||||
util_assert(output);
|
||||
|
||||
if (length < 16 || (length > (1 << 20) * 16))
|
||||
return -EINVAL;
|
||||
|
||||
crypt_func = encrypt ? __esp_aes_encrypt : __esp_aes_decrypt;
|
||||
|
||||
__esp_aes_encrypt(&ctx->tweak, data_unit, tweak);
|
||||
|
||||
while (blocks--) {
|
||||
if (blocks == 0 && leftover && !encrypt) {
|
||||
memcpy(prev_tweak, tweak, sizeof(tweak));
|
||||
aes_gf128mul_x_ble(tweak, tweak);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
tmp[i] = input[i] ^ tweak[i];
|
||||
|
||||
crypt_func(&ctx->crypt, tmp, tmp);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
output[i] = tmp[i] ^ tweak[i];
|
||||
|
||||
aes_gf128mul_x_ble(tweak, tweak);
|
||||
|
||||
output += 16;
|
||||
input += 16;
|
||||
}
|
||||
|
||||
if (leftover) {
|
||||
int i;
|
||||
uint8_t *t = encrypt ? tweak : prev_tweak;
|
||||
uint8_t *prev_output = output - 16;
|
||||
|
||||
for (i = 0; i < leftover; i++) {
|
||||
output[i] = prev_output[i];
|
||||
tmp[i] = input[i] ^ t[i];
|
||||
}
|
||||
|
||||
for (; i < 16; i++ )
|
||||
tmp[i] = prev_output[i] ^ t[i];
|
||||
|
||||
crypt_func(&ctx->crypt, tmp, tmp);
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
prev_output[i] = tmp[i] ^ t[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -112,6 +112,95 @@ static const uint32_t s_aes_ctr_result[3][8] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const uint8_t aes_test_xts_key[][32] = {
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
},
|
||||
|
||||
{
|
||||
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22
|
||||
},
|
||||
|
||||
{
|
||||
0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
|
||||
0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
|
||||
0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22
|
||||
},
|
||||
};
|
||||
|
||||
static const uint8_t aes_test_xts_pt32[][32] =
|
||||
{
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
},
|
||||
|
||||
{
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44
|
||||
},
|
||||
|
||||
{
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
||||
0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44
|
||||
},
|
||||
};
|
||||
|
||||
static const uint8_t aes_test_xts_ct32[][32] =
|
||||
{
|
||||
{
|
||||
0x91, 0x7c, 0xf6, 0x9e, 0xbd, 0x68, 0xb2, 0xec,
|
||||
0x9b, 0x9f, 0xe9, 0xa3, 0xea, 0xdd, 0xa6, 0x92,
|
||||
0xcd, 0x43, 0xd2, 0xf5, 0x95, 0x98, 0xed, 0x85,
|
||||
0x8c, 0x02, 0xc2, 0x65, 0x2f, 0xbf, 0x92, 0x2e
|
||||
},
|
||||
|
||||
{
|
||||
0xc4, 0x54, 0x18, 0x5e, 0x6a, 0x16, 0x93, 0x6e,
|
||||
0x39, 0x33, 0x40, 0x38, 0xac, 0xef, 0x83, 0x8b,
|
||||
0xfb, 0x18, 0x6f, 0xff, 0x74, 0x80, 0xad, 0xc4,
|
||||
0x28, 0x93, 0x82, 0xec, 0xd6, 0xd3, 0x94, 0xf0
|
||||
},
|
||||
|
||||
{
|
||||
0xaf, 0x85, 0x33, 0x6b, 0x59, 0x7a, 0xfc, 0x1a,
|
||||
0x90, 0x0b, 0x2e, 0xb2, 0x1e, 0xc9, 0x49, 0xd2,
|
||||
0x92, 0xdf, 0x4c, 0x04, 0x7e, 0x0b, 0x21, 0x53,
|
||||
0x21, 0x86, 0xa5, 0x97, 0x1a, 0x22, 0x7a, 0x89
|
||||
},
|
||||
};
|
||||
|
||||
static const uint8_t aes_test_xts_data_unit[][16] =
|
||||
{
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
},
|
||||
|
||||
{
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
},
|
||||
|
||||
{
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
},
|
||||
};
|
||||
|
||||
TEST_CASE("Test AES-ECB", "[AES]")
|
||||
{
|
||||
uint32_t buf[4];
|
||||
@ -451,3 +540,50 @@ TEST_CASE("Test AES-CTR", "[AES]")
|
||||
|
||||
// align: AES-CRT test cost time totally encode 344845 us and decode 344421 us, once cost is about encode 336 us and decode 336 us
|
||||
// no align: AES-CRT test cost time totally encode 639256 us and decode 635343 us, once cost is about encode 624 us and decode 620 us
|
||||
|
||||
|
||||
|
||||
TEST_CASE("Test AES-XTS", "[AES]")
|
||||
{
|
||||
uint32_t encode_time = 0, decode_time = 0;
|
||||
const int num_tests = sizeof(aes_test_xts_key) / sizeof(*aes_test_xts_key);
|
||||
extern uint32_t esp_get_time(void);
|
||||
|
||||
for (int cnt = 0; cnt < TEST_AES_COUNT; cnt++) {
|
||||
for (int i = 0; i < num_tests; i++) {
|
||||
const int len = sizeof(*aes_test_xts_ct32);
|
||||
uint32_t buf[8];
|
||||
uint8_t key[32];
|
||||
const uint8_t *data_unit = aes_test_xts_data_unit[i];
|
||||
esp_aes_xts_t ctx_xts;
|
||||
|
||||
memcpy(key, aes_test_xts_key[i], 32);
|
||||
|
||||
TEST_ASSERT_TRUE(esp_aes_xts_set_encrypt_key(&ctx_xts, key, 256) == 0);
|
||||
memcpy(buf, aes_test_xts_pt32[i], len);
|
||||
|
||||
uint32_t tmp = esp_get_time();
|
||||
TEST_ASSERT_TRUE(esp_aes_crypt_xts(&ctx_xts, 1, len, data_unit, buf, buf) == 0);
|
||||
encode_time += esp_get_time() - tmp;
|
||||
|
||||
TEST_ASSERT_TRUE(memcmp(buf, aes_test_xts_ct32[i], len) == 0);
|
||||
|
||||
TEST_ASSERT_TRUE(esp_aes_xts_set_decrypt_key(&ctx_xts, key, 256) == 0);
|
||||
memcpy(buf, aes_test_xts_ct32[i], len);
|
||||
|
||||
tmp = esp_get_time();
|
||||
TEST_ASSERT_TRUE(esp_aes_crypt_xts(&ctx_xts, 0, len, data_unit, buf, buf) == 0);
|
||||
decode_time += esp_get_time() - tmp;
|
||||
|
||||
TEST_ASSERT_TRUE(memcmp(buf, aes_test_xts_pt32[i], len) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
#if TEST_AES_DEBUG_TIME
|
||||
printf("AES-XTS test cost time totally encode %u us and decode %u us, once cost is about encode %u us and decode %u us\n",
|
||||
encode_time, decode_time, encode_time / TEST_AES_COUNT, decode_time / TEST_AES_COUNT);
|
||||
#endif
|
||||
}
|
||||
|
||||
// align: AES-XTS test cost time totally encode 723197 us and decode 533441 us, once cost is about encode 706 us and decode 520 us
|
||||
// no align: AES-XTS test cost time totally encode 675249 us and decode 645998 us, once cost is about encode 659 us and decode 630 us
|
||||
|
Reference in New Issue
Block a user