diff --git a/cpu/cc2538/dev/aes.c b/cpu/cc2538/dev/aes.c index 7fe52e07e..8aa9cd58b 100644 --- a/cpu/cc2538/dev/aes.c +++ b/cpu/cc2538/dev/aes.c @@ -48,16 +48,18 @@ #include /*---------------------------------------------------------------------------*/ 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; } diff --git a/cpu/cc2538/dev/aes.h b/cpu/cc2538/dev/aes.h index 8a6762739..b98050896 100644 --- a/cpu/cc2538/dev/aes.h +++ b/cpu/cc2538/dev/aes.h @@ -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); /** @} */ diff --git a/examples/cc2538dk/crypto/ccm-test.c b/examples/cc2538dk/crypto/ccm-test.c index c34965e5d..739953d08 100644 --- a/examples/cc2538dk/crypto/ccm-test.c +++ b/examples/cc2538dk/crypto/ccm-test.c @@ -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();