From 58517dfcbde0467034f341bb77f3b9b5067ecfe5 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Mon, 24 Apr 2017 14:34:01 +0200 Subject: [PATCH 1/3] AES128 HW crypto engine support for Atmel radios modified: cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h modified: cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h modified: cpu/avr/radio/rf230bb/rf230bb.c modified: cpu/avr/radio/rf230bb/rf230bb.h --- .../radio/rf230bb/atmega128rfa1_registermap.h | 18 ++ .../radio/rf230bb/atmega256rfr2_registermap.h | 15 ++ cpu/avr/radio/rf230bb/rf230bb.c | 180 ++++++++++++++++++ cpu/avr/radio/rf230bb/rf230bb.h | 4 + 4 files changed, 217 insertions(+) diff --git a/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h b/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h index 64b068579..9a8e82308 100644 --- a/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h +++ b/cpu/avr/radio/rf230bb/atmega128rfa1_registermap.h @@ -88,6 +88,24 @@ #define RG_XAH_CTRL_1 (0x157) #define SR_AACK_PROM_MODE 0x157, 0x02, 1 + +#define RG_AES_KEY (0x13F) +#define SR_AES_KEY 0x13F, 0xff, 0 +#define RG_AES_STATE (0x13E) +#define SR_AES_STATE 0x13E, 0xff, 0 +#define RG_AES_STATUS (0x13D) +#define SR_AES_STATUS 0x13D, 0xff, 0 +#define SR_AES_STATUS_DONE 0x13D, 0x01, 0 +#define SR_AES_STATUS_ERR 0x13D, 0x80, 7 +#define RG_AES_CNTRL (0x13C) +#define SR_AES_CNTRL 0x13C, 0xff, 0 +#define SR_AES_CNTRL_IM 0x13C, 0x04, 2 +#define SR_AES_CNTRL_DIR 0x13C, 0x08, 3 +#define SR_AES_CNTRL_MODE 0x13C, 0x20, 5 +#define SR_AES_CNTRL_REQUEST 0x13C, 0x80, 7 + +#define SR_IRQ_MASK 0x14e, 0xff, 0 + /* RF230 register assignments, for reference */ #if 0 #define HAVE_REGISTER_MAP (1) diff --git a/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h index 151513a25..1e8ed54e3 100644 --- a/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h +++ b/cpu/avr/radio/rf230bb/atmega256rfr2_registermap.h @@ -229,6 +229,21 @@ Counter Compare Source #define SR_CSMA_SEED_1 0x16e, 0x03, 0 #define SR_AACK_DIS_ACK 0x16e, 0x10, 4 +#define RG_AES_KEY (0x13F) +#define SR_AES_KEY 0x13F, 0xff, 0 +#define RG_AES_STATE (0x13E) +#define SR_AES_STATE 0x13E, 0xff, 0 +#define RG_AES_STATUS (0x13D) +#define SR_AES_STATUS 0x13D, 0xff, 0 +#define SR_AES_STATUS_DONE 0x13D, 0x01, 0 +#define SR_AES_STATUS_ERR 0x13D, 0x80, 7 +#define RG_AES_CNTRL (0x13C) +#define SR_AES_CNTRL 0x13C, 0xff, 0 +#define SR_AES_CNTRL_IM 0x13C, 0x04, 2 +#define SR_AES_CNTRL_DIR 0x13C, 0x08, 3 +#define SR_AES_CNTRL_MODE 0x13C, 0x20, 5 +#define SR_AES_CNTRL_REQUEST 0x13C, 0x80, 7 + /* RF230 register assignments, for reference */ #if 1 //#define HAVE_REGISTER_MAP (1) diff --git a/cpu/avr/radio/rf230bb/rf230bb.c b/cpu/avr/radio/rf230bb/rf230bb.c index 4fa9a44b4..ce29b70af 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.c +++ b/cpu/avr/radio/rf230bb/rf230bb.c @@ -46,6 +46,7 @@ #if defined(__AVR__) #include +#include //_delay_us has the potential to use floating point which brings the 256 byte clz table into RAM //#include @@ -2075,4 +2076,183 @@ void rf230_start_sneeze(void) { // while (hal_register_read(0x0f)!=1) {continue;} //wait for pll lock-hangs hal_register_write(0x02,0x02); //Set TRX_STATE to TX_START } + #endif + +#ifdef AES_128_HW_CONF +#define IEEE_VECT 0 + +extern unsigned char aes_key[16]; +extern unsigned char aes_p[]; +extern unsigned char aes_c[]; +extern unsigned char aes_s[]; +extern unsigned char tmp[16]; + +/* + After PWR_SAVE sleep key is lost. We'll lock en/decyption to avoid + not to forced in to sleep while doing crypto. Also the key is hold + be the user so AES block should be reentrant. Encode/Docode och 128bit + (16 bytes) is promised to be less than 24us. + Note! Radio must be on to use the HW crypto engine. --ro +*/ + +static void +rf230_aes_write_key(unsigned char *key) +{ + uint8_t i; + for(i = 0; i < 16; i++) { + hal_subregister_write(SR_AES_KEY, key[i]); + } +} +static void +rf230_aes_read_key(unsigned char *key) +{ + uint8_t i; + for(i = 0; i < 16; i++) { + key[i] = hal_subregister_read(SR_AES_KEY); + } +} +static void +rf230_aes_write_state(unsigned char *state) +{ + uint8_t i; + for(i = 0; i < 16; i++) { + hal_subregister_write(SR_AES_STATE, state[i]); + } +} +static void +rf230_aes_read_state(unsigned char *state) +{ + uint8_t i; + for(i = 0; i < 16; i++) { + state[i] = hal_subregister_read(SR_AES_STATE); + } +} + +static int +crypt(void) +{ + uint8_t status; + + hal_subregister_write(SR_AES_CNTRL_REQUEST, 1); /* Kick */ + + do { + watchdog_periodic(); + status = hal_subregister_read(SR_AES_STATUS); + } while(status == 0); + + if (hal_subregister_read(SR_AES_STATUS_ERR)) { + PRINTF("AES ERR\n"); + return 0; + } + if (hal_subregister_read(SR_AES_STATUS_DONE)) { + PRINTF("AES DONE\n"); + return 1; + } + return 0; /* Unknown */ +} + +int +rf230_aes_encrypt_cbc(unsigned char *key, unsigned char *plain, int len, unsigned char *mic) +{ + uint8_t i; + uint8_t sreg; + int res; + + sreg = SREG; + cli(); + rf230_aes_write_key(key); + hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/ + hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */ + + /* write string to encrypt into buffer */ + for(i = 0; i < 16; i++) { + AES_STATE = plain[i] ^ IEEE_VECT; + } + res = crypt(); + if(!res) + goto out; + + len -= 16; + /* Swiitch Mode */ + hal_subregister_write(SR_AES_CNTRL_MODE, 1); /* AES_MODE=1 -> CBC */ + hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */ + + while(len > 0) { + rf230_aes_write_state(plain); + res = crypt(); + if(!res) + goto out; + + len -= 16; + } + /* Read and retrun cipher */ + rf230_aes_read_state(mic); + +out: + SREG = sreg; + return res; +} + +/* Electonic Code Block */ +int +rf230_aes_encrypt_ebc(unsigned char *key, unsigned char *plain, unsigned char *cipher) +{ + int res; + uint8_t sreg; + + sreg = SREG; + cli(); + rf230_aes_write_key(key); + hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/ + hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */ + rf230_aes_write_state(plain); /* write string to encrypt into buffer */ + res = crypt(); + if(!res) + goto out; + rf230_aes_read_state(cipher); /* Read and return cipher */ + +out: + SREG = sreg; + return res; +} + +int +rf230_aes_decrypt_ebc(unsigned char *key, unsigned char *cipher, unsigned char *plain) +{ + int res; + uint8_t sreg; + /* + Dummy encryption of 0 w. original key + to get last round key to be used decrytion + */ + + sreg = SREG; + cli(); + + rf230_aes_write_key(key); + hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/ + hal_subregister_write(SR_AES_CNTRL_DIR, 0); /* AES_DIR=0 -> encryption */ + memset(tmp, 0, sizeof(tmp)); /* Setup for last round */ + rf230_aes_write_state(tmp); + res = crypt(); + if(!res) + goto out; + + rf230_aes_read_key(tmp);/* Save the last round key */ + /* And use as decrytion key */ + rf230_aes_write_key(tmp); + hal_subregister_write(SR_AES_CNTRL_MODE, 0); /* AES_MODE=0 -> ECB for 1:st block*/ + hal_subregister_write(SR_AES_CNTRL_DIR, 1); /* AES_DIR=1 -> decryption */ + /* Write string to decrypt into buffer */ + rf230_aes_write_state(cipher); + res = crypt(); + if(!res) + goto out; + rf230_aes_read_state(plain); /* Read plaintext into string */ + +out: + SREG = sreg; + return res; +} +#endif /* AES_128_HW_CONF */ diff --git a/cpu/avr/radio/rf230bb/rf230bb.h b/cpu/avr/radio/rf230bb/rf230bb.h index 15f5b6438..a6414d4fc 100644 --- a/cpu/avr/radio/rf230bb/rf230bb.h +++ b/cpu/avr/radio/rf230bb/rf230bb.h @@ -227,6 +227,10 @@ bool rf230_is_ready_to_send(); extern uint8_t rf230_last_correlation,rf230_last_rssi,rf230_smallest_rssi; uint8_t rf230_get_raw_rssi(void); +int rf230_aes_encrypt_ebc(unsigned char *key, unsigned char *plain, unsigned char *cipher); +int rf230_aes_decrypt_ebc(unsigned char *key, unsigned char *cipher, unsigned char *plain); +int rf230_aes_decrypt_ebc(unsigned char *key, unsigned char *cipher, unsigned char *plain); + #define rf230_rssi rf230_get_raw_rssi From e9aed001bce4efaafd21f1908ddfe9e5cfa1cbc4 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Mon, 24 Apr 2017 14:40:33 +0200 Subject: [PATCH 2/3] Example project for Atmel radio AES128 cryto engine --- .../avr-rss2/AES128HW_test/AES128HW_test.c | 107 ++++++++++++++++++ examples/avr-rss2/AES128HW_test/Makefile | 18 +++ examples/avr-rss2/AES128HW_test/README.md | 24 ++++ .../avr-rss2/AES128HW_test/project-conf.h | 47 ++++++++ 4 files changed, 196 insertions(+) create mode 100644 examples/avr-rss2/AES128HW_test/AES128HW_test.c create mode 100644 examples/avr-rss2/AES128HW_test/Makefile create mode 100644 examples/avr-rss2/AES128HW_test/README.md create mode 100644 examples/avr-rss2/AES128HW_test/project-conf.h diff --git a/examples/avr-rss2/AES128HW_test/AES128HW_test.c b/examples/avr-rss2/AES128HW_test/AES128HW_test.c new file mode 100644 index 000000000..da7935838 --- /dev/null +++ b/examples/avr-rss2/AES128HW_test/AES128HW_test.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * Author : Robert Olsson + * roolss@kth.se & robert@radio-sensors.com + * Created : 2017-04-22 + */ + +/** + * \file + * A simple AES128 crypto emmgine test for Atmel radios + */ + +#include "contiki.h" +#include "dev/radio.h" +#include "net/netstack.h" +#include "sys/etimer.h" +#include +#include +#include +#include "rf230bb.h" + +PROCESS(aes_crypto_process, "AES HW crypto process"); +AUTOSTART_PROCESSES(&aes_crypto_process); + +unsigned char aes_key[16] = "abcdefghijklmnop"; +unsigned char aes_p[128]; +unsigned char aes_c[128]; +unsigned char aes_s[128]; +unsigned char tmp[16]; +uint8_t i; +int res; + +PROCESS_THREAD(aes_crypto_process, ev, data) +{ + PROCESS_BEGIN(); + + /* AES engine on */ + NETSTACK_RADIO.on(); + + strcpy((char *)aes_s, "Teststring______"); + + for(i = 0; i < 16; i++) { + printf("%02X", aes_s[i]); + } + printf(" Uncrypted \n"); + + res = rf230_aes_encrypt_ebc(aes_key, aes_s, aes_c); + if(!res) { + printf("ERR encryption\n"); + exit(0); + } + for(i = 0; i < 16; i++) { + printf("%02X", aes_c[i]); + } + printf(" AES-128 EBC Crypted\n"); + + res = rf230_aes_decrypt_ebc(aes_key, aes_c, aes_p); + if(!res) { + printf("ERR decryption\n"); + exit(0); + } + for(i = 0; i < 16; i++) { + printf("%02X", aes_p[i]); + } + printf(" Decrypted \n"); + + res = rf230_aes_encrypt_cbc(aes_key, aes_s, sizeof(aes_s), aes_c); + if(!res) { + printf("ERR encryption\n"); + exit(0); + } + for(i = 0; i < 16; i++) { + printf("%02X", aes_c[i]); + } + printf(" AES-128 MIC\n"); + + PROCESS_END(); +} + diff --git a/examples/avr-rss2/AES128HW_test/Makefile b/examples/avr-rss2/AES128HW_test/Makefile new file mode 100644 index 000000000..44c80fb3b --- /dev/null +++ b/examples/avr-rss2/AES128HW_test/Makefile @@ -0,0 +1,18 @@ +CFLAGS += -DPROJECT_CONF_H=\"project-conf.h\" +CONTIKI_PROJECT = AES128HW_test +all: $(CONTIKI_PROJECT) + +# We use floating vars. Add library. +PRINTF_LIB_FLT = -Wl,-u,vfprintf -lprintf_flt -lm +PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min +PRINTF_LIB = $(PRINTF_LIB_FLT) +CLIBS = $(PRINTF_LIB) + +CUSTOM_RULE_LINK = 1 +%.$(TARGET): %.co $(PROJECT_OBJECTFILES) $(PROJECT_LIBRARIES) contiki-$(TARGET).a + $(LD) $(LDFLAGS) $(TARGET_STARTFILES) ${filter-out %.a,$^} ${filter %.a,$^} $(TARGET_LIBFILES) -o $@ $(CLIBS) + +CONTIKI_WITH_RIME = 1 + +CONTIKI = ../../.. +include $(CONTIKI)/Makefile.include diff --git a/examples/avr-rss2/AES128HW_test/README.md b/examples/avr-rss2/AES128HW_test/README.md new file mode 100644 index 000000000..ebcaaa7fb --- /dev/null +++ b/examples/avr-rss2/AES128HW_test/README.md @@ -0,0 +1,24 @@ +AES128HW_test +============= + +Scope +----- +Simple demo to use the AES crypto engine in the Atmel radios. + +Build +----- +make TARGET=avr-rss2 + +Program output +-------------- +*******Booting Contiki-3.x-3252-g0783591******* +I2C: AT24MAC +MAC address 7d:c2: +PAN=0xABCD, MAC=nullmac, RDC=nullrdc, NETWORK=Rime, channel=26, check-rate-Hz=128, tx-power=0 +Routing Enabled + +54657374737472696E675F5F5F5F5F5F Uncrypted +6FDE14E8F9453C6714B7B45B24876CBF AES-128 EBC Crypted +54657374737472696E675F5F5F5F5F5F Decrypted +215C9836DCDB443F15AFED576E9F7F72 AES-128 MIC + diff --git a/examples/avr-rss2/AES128HW_test/project-conf.h b/examples/avr-rss2/AES128HW_test/project-conf.h new file mode 100644 index 000000000..5ae870b6f --- /dev/null +++ b/examples/avr-rss2/AES128HW_test/project-conf.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2015, Copyright Robert Olsson / Radio Sensors AB + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * This file is part of the Contiki operating system. + * + * + * Author : Robert Olsson robert@radio-sensors.com + * Created : 2017-04-22 + */ + +/** + * \file + * Project specific configuration defines for example + * + */ + +#ifndef PROJECT_CONF_H_ +#define PROJECT_CONF_H_ + +#define AES_128_HW_CONF 1 + +#endif /* PROJECT_CONF_H_ */ From e97f3bca269d92375c617ccd96574f5f28523558 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Fri, 16 Jun 2017 10:48:52 +0200 Subject: [PATCH 3/3] Fix misspelled copyright for AES128HW_test pointed out by Nicolas Tsiftes --- examples/avr-rss2/AES128HW_test/AES128HW_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/avr-rss2/AES128HW_test/AES128HW_test.c b/examples/avr-rss2/AES128HW_test/AES128HW_test.c index da7935838..00de029ee 100644 --- a/examples/avr-rss2/AES128HW_test/AES128HW_test.c +++ b/examples/avr-rss2/AES128HW_test/AES128HW_test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Copyright Robert Olsson + * Copyright (c) 2017, Robert Olsson * All rights reserved. * * Redistribution and use in source and binary forms, with or without