-
Notifications
You must be signed in to change notification settings - Fork 492
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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
Showing
15 changed files
with
918 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
} |
Oops, something went wrong.