cc2538: aes: Make it possible to have several keys stored at once

Several keys can be kept at the same time in the key store, and several
keys can be loaded at once. Give access to these features.

The ccm-test example is also improved to better demonstrate the use of
the key store.

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
This commit is contained in:
Benoît Thébaudeau 2015-05-15 19:56:15 +02:00
parent b92a5afcc4
commit 801315e819
3 changed files with 54 additions and 47 deletions

View file

@ -48,16 +48,18 @@
#include <stdint.h>
/*---------------------------------------------------------------------------*/
uint8_t
aes_load_key(const void *key, uint8_t key_area)
aes_load_keys(const void *keys, uint8_t count, uint8_t start_area)
{
uint32_t aligned_key[4];
uint32_t aes_key_store_size;
uint32_t areas;
uint32_t aligned_keys[32];
if(REG(AES_CTRL_ALG_SEL) != 0x00000000) {
return CRYPTO_RESOURCE_IN_USE;
}
/* The key address needs to be 4-byte aligned */
rom_util_memcpy(aligned_key, key, sizeof(aligned_key));
/* The keys base address needs to be 4-byte aligned */
rom_util_memcpy(aligned_keys, keys, count << 4);
/* Workaround for AES registers not retained after PM2 */
REG(AES_CTRL_INT_CFG) = AES_CTRL_INT_CFG_LEVEL;
@ -71,25 +73,34 @@ aes_load_key(const void *key, uint8_t key_area)
REG(AES_CTRL_INT_CLR) = AES_CTRL_INT_CLR_DMA_IN_DONE |
AES_CTRL_INT_CLR_RESULT_AV;
/* Configure key store module (area, size): 128-bit key size */
REG(AES_KEY_STORE_SIZE) = (REG(AES_KEY_STORE_SIZE) &
~AES_KEY_STORE_SIZE_KEY_SIZE_M) |
AES_KEY_STORE_SIZE_KEY_SIZE_128;
/* Configure key store module (areas, size): 128-bit key size
* Note that writing AES_KEY_STORE_SIZE deletes all stored keys */
aes_key_store_size = REG(AES_KEY_STORE_SIZE);
if((aes_key_store_size & AES_KEY_STORE_SIZE_KEY_SIZE_M) !=
AES_KEY_STORE_SIZE_KEY_SIZE_128) {
REG(AES_KEY_STORE_SIZE) = (aes_key_store_size &
~AES_KEY_STORE_SIZE_KEY_SIZE_M) |
AES_KEY_STORE_SIZE_KEY_SIZE_128;
}
/* Enable keys to write (e.g. Key 0) */
REG(AES_KEY_STORE_WRITE_AREA) = 0x00000001 << key_area;
/* Free possibly already occupied key areas */
areas = ((0x00000001 << count) - 1) << start_area;
REG(AES_KEY_STORE_WRITTEN_AREA) = areas;
/* Enable key areas to write */
REG(AES_KEY_STORE_WRITE_AREA) = areas;
/* Configure DMAC
* Enable DMA channel 0 */
REG(AES_DMAC_CH0_CTRL) = AES_DMAC_CH_CTRL_EN;
/* Base address of the key in ext. memory */
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)aligned_key;
/* Base address of the keys in ext. memory */
REG(AES_DMAC_CH0_EXTADDR) = (uint32_t)aligned_keys;
/* Total key length in bytes (e.g. 16 for 1 x 128-bit key) */
/* Total keys length in bytes (e.g. 16 for 1 x 128-bit key) */
REG(AES_DMAC_CH0_DMALENGTH) = (REG(AES_DMAC_CH0_DMALENGTH) &
~AES_DMAC_CH_DMALENGTH_DMALEN_M) |
(0x10 << AES_DMAC_CH_DMALENGTH_DMALEN_S);
(count << (4 + AES_DMAC_CH_DMALENGTH_DMALEN_S));
/* Wait for operation to complete */
while(!(REG(AES_CTRL_INT_STAT) & AES_CTRL_INT_STAT_RESULT_AV));
@ -116,7 +127,7 @@ aes_load_key(const void *key, uint8_t key_area)
REG(AES_CTRL_ALG_SEL) = 0x00000000;
/* Check status, if error return error code */
if(!(REG(AES_KEY_STORE_WRITTEN_AREA) & (0x00000001 << key_area))) {
if((REG(AES_KEY_STORE_WRITTEN_AREA) & areas) != areas) {
return AES_KEYSTORE_WRITE_ERROR;
}

View file

@ -470,12 +470,13 @@
* @{
*/
/** \brief Writes the key into the Key RAM
* \param key Pointer to AES Key
* \param key_area Area in Key RAM where to store the key (0 to 7)
/** \brief Writes keys into the Key RAM
* \param keys Pointer to AES Keys
* \param count Number of keys (1 to 8 - \p start_area)
* \param start_area Start area in Key RAM where to store the key (0 to 7)
* \return \c CRYPTO_SUCCESS if successful, or CRYPTO/AES error code
*/
uint8_t aes_load_key(const void *key, uint8_t key_area);
uint8_t aes_load_keys(const void *keys, uint8_t count, uint8_t start_area);
/** @} */

View file

@ -73,10 +73,15 @@ PROCESS_THREAD(ccm_test_process, ev, data)
"keystore write error",
"authentication failed"
};
static const uint8_t keys[][16] = {
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
{ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf }
};
static struct {
bool encrypt;
uint8_t len_len;
uint8_t key[16];
uint8_t key_area;
uint8_t nonce[13];
uint8_t adata[26];
@ -90,8 +95,6 @@ PROCESS_THREAD(ccm_test_process, ev, data)
{
true, /* encrypt */
2, /* len_len */
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
0, /* key_area */
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
@ -109,9 +112,7 @@ PROCESS_THREAD(ccm_test_process, ev, data)
}, {
true, /* encrypt */
2, /* len_len */
{ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf }, /* key */
0, /* key_area */
1, /* key_area */
{ 0xac, 0xde, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x05, 0x02 }, /* nonce */
{ 0x08, 0xd0, 0x84, 0x21, 0x43, 0x01, 0x00, 0x00,
@ -127,8 +128,6 @@ PROCESS_THREAD(ccm_test_process, ev, data)
}, {
true, /* encrypt */
2, /* len_len */
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
0, /* key_area */
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
@ -147,8 +146,6 @@ PROCESS_THREAD(ccm_test_process, ev, data)
}, {
false, /* decrypt */
2, /* len_len */
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
0, /* key_area */
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
@ -166,9 +163,7 @@ PROCESS_THREAD(ccm_test_process, ev, data)
}, {
false, /* decrypt */
2, /* len_len */
{ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf }, /* key */
0, /* key_area */
1, /* key_area */
{ 0xac, 0xde, 0x48, 0x00, 0x00, 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x05, 0x02 }, /* nonce */
{ 0x08, 0xd0, 0x84, 0x21, 0x43, 0x01, 0x00, 0x00,
@ -184,8 +179,6 @@ PROCESS_THREAD(ccm_test_process, ev, data)
}, {
false, /* decrypt */
2, /* len_len */
{ 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* key */
0, /* key_area */
{ 0x00, 0x00, 0xf0, 0xe0, 0xd0, 0xc0, 0xb0, 0xa0,
0x00, 0x00, 0x00, 0x00, 0x05 }, /* nonce */
@ -213,6 +206,18 @@ PROCESS_THREAD(ccm_test_process, ev, data)
"Initializing cryptoprocessor...");
crypto_init();
puts("-----------------------------------------\n"
"Filling key store...");
time = RTIMER_NOW();
ret = aes_load_keys(keys, sizeof(keys) / sizeof(keys[0]), 0);
time = RTIMER_NOW() - time;
printf("aes_load_keys(): %s, %lu us\n", str_res[ret],
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
PROCESS_PAUSE();
if(ret != CRYPTO_SUCCESS) {
goto fatal;
}
for(i = 0; i < sizeof(vectors) / sizeof(vectors[0]); i++) {
printf("-----------------------------------------\n"
"Test vector #%d: %s\n"
@ -222,17 +227,6 @@ PROCESS_THREAD(ccm_test_process, ev, data)
vectors[i].len_len, vectors[i].key_area,
vectors[i].adata_len, vectors[i].mdata_len, vectors[i].mic_len);
time = RTIMER_NOW();
ret = aes_load_key(vectors[i].key, vectors[i].key_area);
time = RTIMER_NOW() - time;
total_time = time;
printf("aes_load_key(): %s, %lu us\n", str_res[ret],
(uint32_t)((uint64_t)time * 1000000 / RTIMER_SECOND));
PROCESS_PAUSE();
if(ret != CRYPTO_SUCCESS) {
continue;
}
time = RTIMER_NOW();
if(vectors[i].encrypt) {
ret = ccm_auth_encrypt_start(vectors[i].len_len, vectors[i].key_area,
@ -242,7 +236,7 @@ PROCESS_THREAD(ccm_test_process, ev, data)
&ccm_test_process);
time2 = RTIMER_NOW();
time = time2 - time;
total_time += time;
total_time = time;
if(ret == CRYPTO_SUCCESS) {
PROCESS_WAIT_EVENT_UNTIL(ccm_auth_encrypt_check_status());
time2 = RTIMER_NOW() - time2;
@ -290,7 +284,7 @@ PROCESS_THREAD(ccm_test_process, ev, data)
&ccm_test_process);
time2 = RTIMER_NOW();
time = time2 - time;
total_time += time;
total_time = time;
if(ret == CRYPTO_SUCCESS) {
PROCESS_WAIT_EVENT_UNTIL(ccm_auth_decrypt_check_status());
time2 = RTIMER_NOW() - time2;
@ -329,6 +323,7 @@ PROCESS_THREAD(ccm_test_process, ev, data)
(uint32_t)((uint64_t)total_time * 1000000 / RTIMER_SECOND));
}
fatal:
puts("-----------------------------------------\n"
"Disabling cryptoprocessor...");
crypto_disable();