Skip to content

Commit

Permalink
Add Atmel CryptoAuthLib to extras
Browse files Browse the repository at this point in the history
This is a library for interfacing to the Atmel ATECC508 chip.  Additionally, this includes the HAL necessary to use this library in esp_open_rtos using the i2c library in extras/i2c.  Also, I have included a tool I wrote to play with the chip as an example under examples/atcatool.
  • Loading branch information
Petezah committed Nov 22, 2017
1 parent 9b4a58c commit 79d0153
Show file tree
Hide file tree
Showing 15 changed files with 918 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,6 @@
[submodule "extras/libesphttpd/libesphttpd/lib/heatshrink"]
path = extras/libesphttpd/libesphttpd/lib/heatshrink
url = https://github.com/atomicobject/heatshrink
[submodule "extras/cryptoauthlib/CryptoAuthLib"]
path = extras/cryptoauthlib/CryptoAuthLib
url = https://github.com/Petezah/CryptoAuthLib.git
12 changes: 12 additions & 0 deletions examples/atcatool/FreeRTOSConfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/* Terminal FreeRTOSConfig overrides.
This is intended as an example of overriding some of the default FreeRTOSConfig settings,
which are otherwise found in FreeRTOS/Source/include/FreeRTOSConfig.h
*/

/* The serial driver depends on counting semaphores */
#define configUSE_COUNTING_SEMAPHORES 1

/* Use the defaults for everything else */
#include_next<FreeRTOSConfig.h>

5 changes: 5 additions & 0 deletions examples/atcatool/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
PROGRAM=atcatool
EXTRA_COMPONENTS=extras/stdin_uart_interrupt extras/i2c extras/cryptoauthlib
EXTRA_CFLAGS += -DATCAPRINTF
ATEC_PRINTF_ENABLE = 1
include ../../common.mk
56 changes: 56 additions & 0 deletions examples/atcatool/cmd_ecdh.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@

#include "uart_cmds.h"
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <esp8266.h>
#include <esp/uart.h>
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"

ATCA_STATUS cmd_ecdh(uint32_t argc, char *argv[])
{
ATCA_STATUS status;
if (argc >= 2) {
uint8_t slot_num = atoi(argv[1]);
if (slot_num > 0x7){
LOG("Invalid slot number %d; must be between 0 and 7 for private keys", slot_num);
return ATCA_BAD_PARAM;
}

printf("Performing ECDH key exchange in slot %d\n", slot_num);
uint8_t pubkeybytes[100];
int pubkeylen = sizeof(pubkeybytes);
status = read_pubkey_stdin(pubkeybytes, &pubkeylen);
if (status != ATCA_SUCCESS)
{
RETURN(status, "Failed to read public key");
}

LOG("Got valid looking pubkey; does this look correct?");
uint8_t *keyptr = pubkeybytes + (pubkeylen - ATCA_PUB_KEY_SIZE);
atcab_printbin_label((const uint8_t*)"pubkey ", keyptr, ATCA_PUB_KEY_SIZE);

if (!prompt_user()) {
printf("Aborting\n");
}else{
printf("Performing ECDH key exchange\n");
}

// Write key to device
uint8_t pmk[ATCA_PRIV_KEY_SIZE];
status = atcab_ecdh(slot_num, keyptr, pmk);
if(status != ATCA_SUCCESS){
RETURN(status, "Failed to obtain pre-master key");
}
atcab_printbin_label((const uint8_t*)"pmk ", pmk, ATCA_PRIV_KEY_SIZE);

return ATCA_SUCCESS;
} else {
printf("Error: missing slot number.\n");
return ATCA_BAD_PARAM;
}
}
91 changes: 91 additions & 0 deletions examples/atcatool/cmd_priv.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@

#include "uart_cmds.h"
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <esp8266.h>
#include <esp/uart.h>
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"

// get cert and priv key
//> openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp256r1) -keyout cert.key -out cert.crt -days 3650

//#define PEM_PRIV_KEY_OFFSET 5
#define PEM_PRIV_KEY_OFFSET 7

ATCA_STATUS cmd_priv(uint32_t argc, char *argv[])
{
ATCA_STATUS status;
if (argc >= 2) {
uint8_t slot_num = atoi(argv[1]);
if (slot_num > 0x7){
LOG("Invalid slot number %d; must be between 0 and 7 for private keys", slot_num);
return ATCA_BAD_PARAM;
}

uint8_t write_key_slot = 0;
uint8_t *write_key = NULL;
uint8_t random_num[RANDOM_NUM_SIZE];
if (argc >= 3) {
write_key_slot = atoi(argv[2]);
if (write_key_slot == slot_num || write_key_slot < 0x0 || write_key_slot > 0xF) {
LOG("Invalid slot for write key (%d); trying unencrypted write", (int)write_key_slot);
write_key_slot = 0;
write_key = NULL;
} else {
LOG("Writing write key to slot %d", (int)write_key_slot);
if((status = atcab_random(random_num)) != ATCA_SUCCESS){
RETURN(status, "Could not make random number");
}
write_key = random_num;
if((status = atcab_write_bytes_zone(ATCA_ZONE_DATA, write_key_slot, 0, write_key, RANDOM_NUM_SIZE)) != ATCA_SUCCESS){
RETURN(status, "Could not commit write key");
}
}
}

printf("Programming private key in slot %d\n", slot_num);
uint8_t privkeybytes[200];
int privkeylen = sizeof(privkeybytes);
status = read_privkey_stdin(privkeybytes, &privkeylen);
if (status != ATCA_SUCCESS)
{
RETURN(status, "Failed to read private key");
}

LOG("Got valid looking private key; does this look correct?");
uint8_t *keyptr = privkeybytes + PEM_PRIV_KEY_OFFSET;
atcab_printbin_label((const uint8_t*)"privkey ", keyptr, ATCA_PRIV_KEY_SIZE);

if (!prompt_user()) {
printf("Aborting\n");
return ATCA_SUCCESS;
}else{
printf("Writing key\n");
}

// Write key to device
uint8_t priv_key[ATCA_PRIV_KEY_SIZE + 4] = {0};
memcpy(priv_key + 4, keyptr, ATCA_PRIV_KEY_SIZE);
status = atcab_priv_write(slot_num, priv_key, write_key_slot, write_key);
if(status != ATCA_SUCCESS){
RETURN(status, "Failed to write key to slot");
}

// Read public key
uint8_t pub_key[ATCA_PUB_KEY_SIZE] = {0};
if((status = atcab_get_pubkey(slot_num, pub_key)) != ATCA_SUCCESS){
RETURN(status, "Could not get public key");
}
atcab_printbin_label((const uint8_t*)"pubkey ", pub_key, sizeof(pub_key));

return ATCA_SUCCESS;
} else {
printf("Error: missing slot number.\n");
return ATCA_BAD_PARAM;
}
}
59 changes: 59 additions & 0 deletions examples/atcatool/cmd_pub.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

#include "uart_cmds.h"
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <esp8266.h>
#include <esp/uart.h>
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"

// get cert and priv key
//> openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp256r1) -keyout cert.key -out cert.crt -days 3650
// get pub key
//> openssl x509 -in cert.crt -pubkey -noout > pubkey.pem

ATCA_STATUS cmd_pub(uint32_t argc, char *argv[])
{
ATCA_STATUS status;
if (argc >= 2) {
uint8_t slot_num = atoi(argv[1]);
if (slot_num < 0x8 || slot_num > 0xF){
LOG("Invalid slot number %d; must be between 8 and 15 for public keys", slot_num);
return ATCA_BAD_PARAM;
}

printf("Programming public key in slot %d\n", slot_num);
uint8_t pubkeybytes[100];
int pubkeylen = sizeof(pubkeybytes);
status = read_pubkey_stdin(pubkeybytes, &pubkeylen);
if (status != ATCA_SUCCESS)
{
RETURN(status, "Failed to read public key");
}

LOG("Got valid looking pubkey; does this look correct?");
uint8_t *keyptr = pubkeybytes + (pubkeylen - ATCA_PUB_KEY_SIZE);
atcab_printbin_label((const uint8_t*)"pubkey ", keyptr, ATCA_PUB_KEY_SIZE);

if (!prompt_user()) {
printf("Aborting\n");
}else{
printf("Writing key\n");
}

// Write key to device
status = atcab_write_pubkey(slot_num, keyptr);
if(status != ATCA_SUCCESS){
RETURN(status, "Failed to write key to slot");
}

return ATCA_SUCCESS;
} else {
printf("Error: missing slot number.\n");
return ATCA_BAD_PARAM;
}
}
97 changes: 97 additions & 0 deletions examples/atcatool/cmd_verify.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@

#include "uart_cmds.h"
#include <stdint.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <esp8266.h>
#include <esp/uart.h>
#include <stdio.h>
#include "FreeRTOS.h"
#include "task.h"

// make test hash
//> openssl sha -sha256 cmd_pub.c
// sign test hash
//> openssl sha -sha256 -sign cert.key -hex cmd_pub.c

void get_line(char *buf, size_t buflen)
{
char ch;
char cmd[200];
int i = 0;
while(1) {
if (read(0, (void*)&ch, 1)) { // 0 is stdin
printf("%c", ch);
if (ch == '\n' || ch == '\r') {
cmd[i] = 0;
i = 0;
printf("\n");
strcpy(buf, cmd);
return;
} else {
if (i < sizeof(cmd)) cmd[i++] = ch;
}
}
}
}

ATCA_STATUS cmd_verify(uint32_t argc, char *argv[])
{
ATCA_STATUS status;
if (argc >= 2) {
uint8_t slot_num = atoi(argv[1]);
if (slot_num < 0x8 || slot_num > 0xF){
LOG("Invalid slot number %d; must be between 8 and 15 for public keys", slot_num);
return ATCA_BAD_PARAM;
}

printf("Verifying with public key in slot %d\n", slot_num);
char hash[100]; uint8_t hashbin[100]; int hashlen = sizeof(hashbin);
char sig[200]; uint8_t sigbin[200]; int siglen = sizeof(sigbin);

printf("Please paste hash in the terminal (hex format)\n");
get_line(hash, sizeof(hash));

status = atcab_hex2bin(hash, strlen(hash), hashbin, &hashlen);
if(status != ATCA_SUCCESS){
RETURN(status, "Could not parse hash hex");
}

printf("Please paste signature in the terminal (hex format)\n");
get_line(sig, sizeof(sig));

status = atcab_hex2bin(sig, strlen(sig), sigbin, &siglen);
if(status != ATCA_SUCCESS){
RETURN(status, "Could not parse signature hex");
}

bool isVerified = false;
printf("Trying to verify with\n");
atcab_printbin_label((const uint8_t*)"hash ", hashbin, hashlen);
printf("Len %d\n", hashlen);
atcab_printbin_label((const uint8_t*)"sig ", sigbin, siglen);
printf("Len %d\n", siglen);

uint8_t atca_sig[ATCA_SIG_SIZE] = {0};
if(!parse_asn1_signature(sigbin, siglen, atca_sig))
{
RETURN(ATCA_PARSE_ERROR, "Could not parse ASN.1 signature");
}

atcab_printbin_label((const uint8_t*)"atca_sig ", atca_sig, ATCA_SIG_SIZE);
printf("Len %d\n", ATCA_SIG_SIZE);

status = atcab_verify_stored(hashbin, atca_sig, slot_num, &isVerified);
if(status != ATCA_SUCCESS){
RETURN(status, "Could not verify signature");
}

printf(isVerified ? "Signature is valid\n" : "Signature is invalid\n");
RETURN(status, "Done");
} else {
printf("Error: missing slot number.\n");
return ATCA_BAD_PARAM;
}
}

0 comments on commit 79d0153

Please sign in to comment.