1
0
Fork 0

Adds AES128-CTR mode and NRF51 RNG peripheral utility functions

This commit is contained in:
Shawn Nock 2016-06-06 11:26:08 -04:00
parent 93456bb4d0
commit a0c4034430
8 changed files with 123 additions and 20 deletions

View File

@ -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);

28
ctr.c Normal file
View File

@ -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));
}
}

7
ctr.h Normal file
View File

@ -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
View File

@ -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);
}

25
rng.c Normal file
View File

@ -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;
}

4
rng.h Normal file
View File

@ -0,0 +1,4 @@
#pragma once
uint8_t rng_byte(void);
void rng_bytes(uint8_t *out, uint32_t num_bytes);

View File

@ -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

30
tests/test_ctr.c Normal file
View File

@ -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");
}