From 58517dfcbde0467034f341bb77f3b9b5067ecfe5 Mon Sep 17 00:00:00 2001 From: Robert Olsson Date: Mon, 24 Apr 2017 14:34:01 +0200 Subject: [PATCH] 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