Adds AES128-CTR mode and NRF51 RNG peripheral utility functions
This commit is contained in:
parent
93456bb4d0
commit
a0c4034430
2
block.h
2
block.h
|
@ -4,6 +4,8 @@
|
|||
#include <stdint.h>
|
||||
|
||||
bool block_eq(uint8_t const * const, uint8_t const * const);
|
||||
void block_decr(uint8_t *);
|
||||
void block_incr(uint8_t *);
|
||||
void block_print(char const * const, uint8_t const * const);
|
||||
void block_shiftl(uint8_t *, uint8_t * const, uint_fast8_t);
|
||||
void block_shiftr(uint8_t *, uint8_t * const, uint_fast8_t);
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "aes.h"
|
||||
#include "block.h"
|
||||
|
||||
static uint8_t g_counter[16];
|
||||
|
||||
void aes128_ctr_init(uint8_t *key, uint8_t *counter) {
|
||||
memcpy(g_counter, counter, 16);
|
||||
/* Decrementing the counter so that initial value will match without
|
||||
special logic during encryption */
|
||||
block_decr(g_counter);
|
||||
aes128_init(key);
|
||||
}
|
||||
|
||||
uint8_t *aes128_ctr_evolve_counter(void) {
|
||||
block_incr(g_counter);
|
||||
return g_counter;
|
||||
}
|
||||
|
||||
void aes128_ctr(uint8_t *dest, uint8_t *msg, uint32_t msg_len) {
|
||||
uint32_t num_blocks = msg_len / 16 + (msg_len % 16 ? 1 : 0);
|
||||
for (uint32_t i = 0; i < num_blocks; i++) {
|
||||
uint8_t keystream[16];
|
||||
aes128_ecb(keystream, aes128_ctr_evolve_counter());
|
||||
block_xor(dest+(i*16), keystream, msg+(i*16));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void aes128_ctr(uint8_t *, uint8_t *, uint32_t);
|
||||
void aes128_ctr_init(uint8_t *, uint8_t *);
|
||||
|
45
main.c
45
main.c
|
@ -20,41 +20,46 @@
|
|||
|
||||
void test_cmac(void) {
|
||||
/* NIST Examples */
|
||||
block_t k = { .ui8={0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c}};
|
||||
cmac_aes128_init(&k);
|
||||
uint8_t k[16] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
|
||||
cmac_aes128_init(k);
|
||||
uint8_t tag[16];
|
||||
|
||||
/* Test Null Message, NIST Example */
|
||||
uint8_t msg1[] = "";
|
||||
block_t case1 = {.ui8={0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
|
||||
0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46}};
|
||||
block_t tag = cmac_aes128(msg1, 0);
|
||||
if (!block_cmp(&tag, &case1)) {
|
||||
uint8_t *msg1 = NULL;
|
||||
uint8_t case1[] = {0xbb, 0x1d, 0x69, 0x29, 0xe9, 0x59, 0x37, 0x28,
|
||||
0x7f, 0xa3, 0x7d, 0x12, 0x9b, 0x75, 0x67, 0x46};
|
||||
cmac_aes128(tag, msg1, 0, 16);
|
||||
if (!block_eq(tag, case1)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* 16b example */
|
||||
uint8_t msg2[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a};
|
||||
block_t case2 = {.ui8={0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
|
||||
0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c}};
|
||||
tag = cmac_aes128(msg2, sizeof(msg2));
|
||||
if (!block_cmp(&tag, &case2)) {
|
||||
uint8_t case2[] = {0x07, 0x0a, 0x16, 0xb4, 0x6b, 0x4d, 0x41, 0x44,
|
||||
0xf7, 0x9b, 0xdd, 0x9d, 0xd0, 0x4a, 0x28, 0x7c};
|
||||
cmac_aes128(tag, msg2, sizeof(msg2), 16);
|
||||
if (!block_eq(tag, case2)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* 40b example */
|
||||
uint8_t msg3[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
|
||||
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
|
||||
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11};
|
||||
block_t case3 = {.ui8={0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
|
||||
0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27}};
|
||||
tag = cmac_aes128(msg3, sizeof(msg3));
|
||||
if (!block_cmp(&tag, &case3)) {
|
||||
uint8_t case3[] = {0xdf, 0xa6, 0x67, 0x47, 0xde, 0x9a, 0xe6, 0x30,
|
||||
0x30, 0xca, 0x32, 0x61, 0x14, 0x97, 0xc8, 0x27};
|
||||
cmac_aes128(tag, msg3, sizeof(msg3), 16);
|
||||
if (!block_eq(tag, case3)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
|
||||
/* 64b example */
|
||||
uint8_t msg4[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
|
||||
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
|
@ -64,10 +69,10 @@ void test_cmac(void) {
|
|||
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
|
||||
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
|
||||
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
||||
block_t case4 = {.ui8={0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
|
||||
0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe}};
|
||||
tag = cmac_aes128(msg4, sizeof(msg4));
|
||||
if (!block_cmp(&tag, &case4)) {
|
||||
uint8_t case4[] = {0x51, 0xf0, 0xbe, 0xbf, 0x7e, 0x3b, 0x9d, 0x92,
|
||||
0xfc, 0x49, 0x74, 0x17, 0x79, 0x36, 0x3c, 0xfe};
|
||||
cmac_aes128(tag, msg4, sizeof(msg4), 16);
|
||||
if (!block_eq(tag, case4)) {
|
||||
ERROR_LED_ON;
|
||||
while(1);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "nrf.h"
|
||||
|
||||
uint8_t rng_byte(void) {
|
||||
NRF_RNG->TASKS_START = 1;
|
||||
while(!NRF_RNG->EVENTS_VALRDY) {
|
||||
/* Waiting for hardware */
|
||||
}
|
||||
uint8_t val = (uint8_t)NRF_RNG->VALUE;
|
||||
NRF_RNG->TASKS_STOP = 1;
|
||||
NRF_RNG->EVENTS_VALRDY = 0;
|
||||
return val;
|
||||
}
|
||||
|
||||
void rng_bytes(uint8_t *out, uint32_t num_bytes) {
|
||||
NRF_RNG->TASKS_START = 1;
|
||||
for (uint32_t i = 0; i < num_bytes; i++) {
|
||||
while(!NRF_RNG->EVENTS_VALRDY);
|
||||
out[i] = (uint8_t)NRF_RNG->VALUE;
|
||||
NRF_RNG->EVENTS_VALRDY = 0;
|
||||
}
|
||||
NRF_RNG->TASKS_STOP = 1;
|
||||
return;
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
#pragma once
|
||||
|
||||
uint8_t rng_byte(void);
|
||||
void rng_bytes(uint8_t *out, uint32_t num_bytes);
|
|
@ -81,3 +81,5 @@ debug-gdbinit:
|
|||
test:
|
||||
gcc -g -std=gnu99 -Wall -Werror -I.. -DHOST_BUILD -lcrypto block.c aes.c cmac.c tests/test_cmac.c -o tests/test_cmac
|
||||
./tests/test_cmac
|
||||
gcc -g -std=gnu99 -Wall -Werror -I.. -DHOST_BUILD -lcrypto block.c aes.c ctr.c tests/test_ctr.c -o tests/test_ctr
|
||||
./tests/test_ctr
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "../block.h"
|
||||
#include "../ctr.h"
|
||||
|
||||
int main(void) {
|
||||
printf("Testing AES128-CTR: ");
|
||||
/* Test Vec from NIST SP 800-38A F5.1 */
|
||||
uint8_t key[] = {0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
|
||||
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c};
|
||||
uint8_t counter[] = {0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
|
||||
0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff};
|
||||
aes128_ctr_init(key, counter);
|
||||
uint8_t plaintext[] = {0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96, 0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a,
|
||||
0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c, 0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51,
|
||||
0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11, 0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef,
|
||||
0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10};
|
||||
|
||||
uint8_t cyphertext[] = {0x87, 0x4d, 0x61, 0x91, 0xb6, 0x20, 0xe3, 0x26, 0x1b, 0xef, 0x68, 0x64, 0x99, 0x0d, 0xb6, 0xce,
|
||||
0x98, 0x06, 0xf6, 0x6b, 0x79, 0x70, 0xfd, 0xff, 0x86, 0x17, 0x18, 0x7b, 0xb9, 0xff, 0xfd, 0xff,
|
||||
0x5a, 0xe4, 0xdf, 0x3e, 0xdb, 0xd5, 0xd3, 0x5e, 0x5b, 0x4f, 0x09, 0x02, 0x0d, 0xb0, 0x3e, 0xab,
|
||||
0x1e, 0x03, 0x1d, 0xda, 0x2f, 0xbe, 0x03, 0xd1, 0x79, 0x21, 0x70, 0xa0, 0xf3, 0x00, 0x9c, 0xee};
|
||||
|
||||
uint8_t ct_undertest[sizeof(cyphertext)];
|
||||
aes128_ctr(ct_undertest, plaintext, sizeof(plaintext));
|
||||
for (int i = 0; i < 4; i++) {
|
||||
printf("%s", block_eq(ct_undertest+(i*16), cyphertext+(i*16)) ? "." : "F");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
Loading…
Reference in New Issue