Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Atmel CryptoAuthLib to extras #490

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,6 @@
[submodule "lvgl/lv_examples"]
path = lvgl/lv_examples
url = https://github.com/littlevgl/lv_examples.git
[submodule "extras/cryptoauthlib/cryptoauthlib"]
path = extras/cryptoauthlib/cryptoauthlib
url = https://github.com/MicrochipTech/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;
}
}