Skip to content

Commit f0bddb2

Browse files
authored
Merge pull request contiki-os#2203 from herjulf/AES128HW
Atmel radio AES128 crypto engine support.
2 parents d53b6ad + e97f3bc commit f0bddb2

File tree

8 files changed

+413
-0
lines changed

8 files changed

+413
-0
lines changed

cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h

+18
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,24 @@
8888
#define RG_XAH_CTRL_1 (0x157)
8989
#define SR_AACK_PROM_MODE 0x157, 0x02, 1
9090

91+
92+
#define RG_AES_KEY (0x13F)
93+
#define SR_AES_KEY 0x13F, 0xff, 0
94+
#define RG_AES_STATE (0x13E)
95+
#define SR_AES_STATE 0x13E, 0xff, 0
96+
#define RG_AES_STATUS (0x13D)
97+
#define SR_AES_STATUS 0x13D, 0xff, 0
98+
#define SR_AES_STATUS_DONE 0x13D, 0x01, 0
99+
#define SR_AES_STATUS_ERR 0x13D, 0x80, 7
100+
#define RG_AES_CNTRL (0x13C)
101+
#define SR_AES_CNTRL 0x13C, 0xff, 0
102+
#define SR_AES_CNTRL_IM 0x13C, 0x04, 2
103+
#define SR_AES_CNTRL_DIR 0x13C, 0x08, 3
104+
#define SR_AES_CNTRL_MODE 0x13C, 0x20, 5
105+
#define SR_AES_CNTRL_REQUEST 0x13C, 0x80, 7
106+
107+
#define SR_IRQ_MASK 0x14e, 0xff, 0
108+
91109
/* RF230 register assignments, for reference */
92110
#if 0
93111
#define HAVE_REGISTER_MAP (1)

cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h

+15
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,21 @@ Counter Compare Source
229229
#define SR_CSMA_SEED_1 0x16e, 0x03, 0
230230
#define SR_AACK_DIS_ACK 0x16e, 0x10, 4
231231

232+
#define RG_AES_KEY (0x13F)
233+
#define SR_AES_KEY 0x13F, 0xff, 0
234+
#define RG_AES_STATE (0x13E)
235+
#define SR_AES_STATE 0x13E, 0xff, 0
236+
#define RG_AES_STATUS (0x13D)
237+
#define SR_AES_STATUS 0x13D, 0xff, 0
238+
#define SR_AES_STATUS_DONE 0x13D, 0x01, 0
239+
#define SR_AES_STATUS_ERR 0x13D, 0x80, 7
240+
#define RG_AES_CNTRL (0x13C)
241+
#define SR_AES_CNTRL 0x13C, 0xff, 0
242+
#define SR_AES_CNTRL_IM 0x13C, 0x04, 2
243+
#define SR_AES_CNTRL_DIR 0x13C, 0x08, 3
244+
#define SR_AES_CNTRL_MODE 0x13C, 0x20, 5
245+
#define SR_AES_CNTRL_REQUEST 0x13C, 0x80, 7
246+
232247
/* RF230 register assignments, for reference */
233248
#if 1
234249
//#define HAVE_REGISTER_MAP (1)

cpu/avr/radio/rf230bb/rf230bb.c

+180
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646

4747
#if defined(__AVR__)
4848
#include <avr/io.h>
49+
#include <dev/watchdog.h>
4950

5051
//_delay_us has the potential to use floating point which brings the 256 byte clz table into RAM
5152
//#include <util/delay.h>
@@ -2100,4 +2101,183 @@ void rf230_start_sneeze(void) {
21002101
// while (hal_register_read(0x0f)!=1) {continue;} //wait for pll lock-hangs
21012102
hal_register_write(0x02,0x02); //Set TRX_STATE to TX_START
21022103
}
2104+
21032105
#endif
2106+
2107+
#ifdef AES_128_HW_CONF
2108+
#define IEEE_VECT 0
2109+
2110+
extern unsigned char aes_key[16];
2111+
extern unsigned char aes_p[];
2112+
extern unsigned char aes_c[];
2113+
extern unsigned char aes_s[];
2114+
extern unsigned char tmp[16];
2115+
2116+
/*
2117+
After PWR_SAVE sleep key is lost. We'll lock en/decyption to avoid
2118+
not to forced in to sleep while doing crypto. Also the key is hold
2119+
be the user so AES block should be reentrant. Encode/Docode och 128bit
2120+
(16 bytes) is promised to be less than 24us.
2121+
Note! Radio must be on to use the HW crypto engine. --ro
2122+
*/
2123+
2124+
static void
2125+
rf230_aes_write_key(unsigned char *key)
2126+
{
2127+
uint8_t i;
2128+
for(i = 0; i < 16; i++) {
2129+
hal_subregister_write(SR_AES_KEY, key[i]);
2130+
}
2131+
}
2132+
static void
2133+
rf230_aes_read_key(unsigned char *key)
2134+
{
2135+
uint8_t i;
2136+
for(i = 0; i < 16; i++) {
2137+
key[i] = hal_subregister_read(SR_AES_KEY);
2138+
}
2139+
}
2140+
static void
2141+
rf230_aes_write_state(unsigned char *state)
2142+
{
2143+
uint8_t i;
2144+
for(i = 0; i < 16; i++) {
2145+
hal_subregister_write(SR_AES_STATE, state[i]);
2146+
}
2147+
}
2148+
static void
2149+
rf230_aes_read_state(unsigned char *state)
2150+
{
2151+
uint8_t i;
2152+
for(i = 0; i < 16; i++) {
2153+
state[i] = hal_subregister_read(SR_AES_STATE);
2154+
}
2155+
}
2156+
2157+
static int
2158+
crypt(void)
2159+
{
2160+
uint8_t status;
2161+
2162+
hal_subregister_write(SR_AES_CNTRL_REQUEST, 1); /* Kick */
2163+
2164+
do {
2165+
watchdog_periodic();
2166+
status = hal_subregister_read(SR_AES_STATUS);
2167+
} while(status == 0);
2168+
2169+
if (hal_subregister_read(SR_AES_STATUS_ERR)) {
2170+
PRINTF("AES ERR\n");
2171+
return 0;
2172+
}
2173+
if (hal_subregister_read(SR_AES_STATUS_DONE)) {
2174+
PRINTF("AES DONE\n");
2175+
return 1;
2176+
}
2177+
return 0; /* Unknown */
2178+
}
2179+
2180+
int
2181+
rf230_aes_encrypt_cbc(unsigned char *key, unsigned char *plain, int len, unsigned char *mic)
2182+
{
2183+
uint8_t i;
2184+
uint8_t sreg;
2185+
int res;
2186+
2187+
sreg = SREG;
2188+
cli();
2189+
rf230_aes_write_key(key);
2190+
hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/
2191+
hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */
2192+
2193+
/* write string to encrypt into buffer */
2194+
for(i = 0; i < 16; i++) {
2195+
AES_STATE = plain[i] ^ IEEE_VECT;
2196+
}
2197+
res = crypt();
2198+
if(!res)
2199+
goto out;
2200+
2201+
len -= 16;
2202+
/* Swiitch Mode */
2203+
hal_subregister_write(SR_AES_CNTRL_MODE, 1); /* AES_MODE=1 -> CBC */
2204+
hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */
2205+
2206+
while(len > 0) {
2207+
rf230_aes_write_state(plain);
2208+
res = crypt();
2209+
if(!res)
2210+
goto out;
2211+
2212+
len -= 16;
2213+
}
2214+
/* Read and retrun cipher */
2215+
rf230_aes_read_state(mic);
2216+
2217+
out:
2218+
SREG = sreg;
2219+
return res;
2220+
}
2221+
2222+
/* Electonic Code Block */
2223+
int
2224+
rf230_aes_encrypt_ebc(unsigned char *key, unsigned char *plain, unsigned char *cipher)
2225+
{
2226+
int res;
2227+
uint8_t sreg;
2228+
2229+
sreg = SREG;
2230+
cli();
2231+
rf230_aes_write_key(key);
2232+
hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/
2233+
hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */
2234+
rf230_aes_write_state(plain); /* write string to encrypt into buffer */
2235+
res = crypt();
2236+
if(!res)
2237+
goto out;
2238+
rf230_aes_read_state(cipher); /* Read and return cipher */
2239+
2240+
out:
2241+
SREG = sreg;
2242+
return res;
2243+
}
2244+
2245+
int
2246+
rf230_aes_decrypt_ebc(unsigned char *key, unsigned char *cipher, unsigned char *plain)
2247+
{
2248+
int res;
2249+
uint8_t sreg;
2250+
/*
2251+
Dummy encryption of 0 w. original key
2252+
to get last round key to be used decrytion
2253+
*/
2254+
2255+
sreg = SREG;
2256+
cli();
2257+
2258+
rf230_aes_write_key(key);
2259+
hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/
2260+
hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */
2261+
memset(tmp, 0, sizeof(tmp)); /* Setup for last round */
2262+
rf230_aes_write_state(tmp);
2263+
res = crypt();
2264+
if(!res)
2265+
goto out;
2266+
2267+
rf230_aes_read_key(tmp);/* Save the last round key */
2268+
/* And use as decrytion key */
2269+
rf230_aes_write_key(tmp);
2270+
hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/
2271+
hal_subregister_write(SR_AES_CNTRL_DIR, 1); /* AES_DIR=1 -> decryption */
2272+
/* Write string to decrypt into buffer */
2273+
rf230_aes_write_state(cipher);
2274+
res = crypt();
2275+
if(!res)
2276+
goto out;
2277+
rf230_aes_read_state(plain); /* Read plaintext into string */
2278+
2279+
out:
2280+
SREG = sreg;
2281+
return res;
2282+
}
2283+
#endif /* AES_128_HW_CONF */

cpu/avr/radio/rf230bb/rf230bb.h

+4
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,10 @@ static bool rf230_is_sleeping(void);
227227
extern uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi;
228228

229229
uint8_t rf230_get_raw_rssi(void);
230+
int rf230_aes_encrypt_ebc(unsigned char *key, unsigned char *plain, unsigned char *cipher);
231+
int rf230_aes_decrypt_ebc(unsigned char *key, unsigned char *cipher, unsigned char *plain);
232+
int rf230_aes_decrypt_ebc(unsigned char *key, unsigned char *cipher, unsigned char *plain);
233+
230234

231235
#define rf230_rssi rf230_get_raw_rssi
232236

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2017, Robert Olsson
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
* 1. Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* 2. Redistributions in binary form must reproduce the above copyright
11+
* notice, this list of conditions and the following disclaimer in the
12+
* documentation and/or other materials provided with the distribution.
13+
* 3. Neither the name of the Institute nor the names of its contributors
14+
* may be used to endorse or promote products derived from this software
15+
* without specific prior written permission.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20+
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23+
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24+
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26+
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27+
* SUCH DAMAGE.
28+
*
29+
* This file is part of the Contiki operating system.
30+
*
31+
* Author : Robert Olsson
32+
* roolss@kth.se & robert@radio-sensors.com
33+
* Created : 2017-04-22
34+
*/
35+
36+
/**
37+
* \file
38+
* A simple AES128 crypto emmgine test for Atmel radios
39+
*/
40+
41+
#include "contiki.h"
42+
#include "dev/radio.h"
43+
#include "net/netstack.h"
44+
#include "sys/etimer.h"
45+
#include <stdio.h>
46+
#include <string.h>
47+
#include <stdlib.h>
48+
#include "rf230bb.h"
49+
50+
PROCESS(aes_crypto_process, "AES HW crypto process");
51+
AUTOSTART_PROCESSES(&aes_crypto_process);
52+
53+
unsigned char aes_key[16] = "abcdefghijklmnop";
54+
unsigned char aes_p[128];
55+
unsigned char aes_c[128];
56+
unsigned char aes_s[128];
57+
unsigned char tmp[16];
58+
uint8_t i;
59+
int res;
60+
61+
PROCESS_THREAD(aes_crypto_process, ev, data)
62+
{
63+
PROCESS_BEGIN();
64+
65+
/* AES engine on */
66+
NETSTACK_RADIO.on();
67+
68+
strcpy((char *)aes_s, "Teststring______");
69+
70+
for(i = 0; i < 16; i++) {
71+
printf("%02X", aes_s[i]);
72+
}
73+
printf(" Uncrypted \n");
74+
75+
res = rf230_aes_encrypt_ebc(aes_key, aes_s, aes_c);
76+
if(!res) {
77+
printf("ERR encryption\n");
78+
exit(0);
79+
}
80+
for(i = 0; i < 16; i++) {
81+
printf("%02X", aes_c[i]);
82+
}
83+
printf(" AES-128 EBC Crypted\n");
84+
85+
res = rf230_aes_decrypt_ebc(aes_key, aes_c, aes_p);
86+
if(!res) {
87+
printf("ERR decryption\n");
88+
exit(0);
89+
}
90+
for(i = 0; i < 16; i++) {
91+
printf("%02X", aes_p[i]);
92+
}
93+
printf(" Decrypted \n");
94+
95+
res = rf230_aes_encrypt_cbc(aes_key, aes_s, sizeof(aes_s), aes_c);
96+
if(!res) {
97+
printf("ERR encryption\n");
98+
exit(0);
99+
}
100+
for(i = 0; i < 16; i++) {
101+
printf("%02X", aes_c[i]);
102+
}
103+
printf(" AES-128 MIC\n");
104+
105+
PROCESS_END();
106+
}
107+
+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\"
2+
CONTIKI_PROJECT = AES128HW_test
3+
all: $(CONTIKI_PROJECT)
4+
5+
# We use floating vars. Add library.
6+
PRINTF_LIB_FLT = -Wl,-u,vfprintf -lprintf_flt -lm
7+
PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min
8+
PRINTF_LIB = $(PRINTF_LIB_FLT)
9+
CLIBS = $(PRINTF_LIB)
10+
11+
CUSTOM_RULE_LINK = 1
12+
%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a
13+
$(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ $(CLIBS)
14+
15+
CONTIKI_WITH_RIME = 1
16+
17+
CONTIKI = ../../..
18+
include $(CONTIKI)/Makefile.include

0 commit comments

Comments
 (0)