Skip to content

Commit 109e9d1

Browse files
committed
Add Atmel CryptoAuthLib to extras
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.
1 parent 8f378b4 commit 109e9d1

File tree

15 files changed

+918
-0
lines changed

15 files changed

+918
-0
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,6 @@
4646
[submodule "lvgl/lv_examples"]
4747
path = lvgl/lv_examples
4848
url = https://github.com/littlevgl/lv_examples.git
49+
[submodule "extras/cryptoauthlib/CryptoAuthLib"]
50+
path = extras/cryptoauthlib/CryptoAuthLib
51+
url = https://github.com/Petezah/CryptoAuthLib.git

examples/atcatool/FreeRTOSConfig.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/* Terminal FreeRTOSConfig overrides.
2+
3+
This is intended as an example of overriding some of the default FreeRTOSConfig settings,
4+
which are otherwise found in FreeRTOS/Source/include/FreeRTOSConfig.h
5+
*/
6+
7+
/* The serial driver depends on counting semaphores */
8+
#define configUSE_COUNTING_SEMAPHORES 1
9+
10+
/* Use the defaults for everything else */
11+
#include_next<FreeRTOSConfig.h>
12+

examples/atcatool/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
PROGRAM=atcatool
2+
EXTRA_COMPONENTS=extras/stdin_uart_interrupt extras/i2c extras/cryptoauthlib
3+
EXTRA_CFLAGS += -DATCAPRINTF
4+
ATEC_PRINTF_ENABLE = 1
5+
include ../../common.mk

examples/atcatool/cmd_ecdh.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
#include "uart_cmds.h"
3+
#include <stdint.h>
4+
#include <sys/types.h>
5+
#include <stdlib.h>
6+
#include <unistd.h>
7+
#include <string.h>
8+
#include <esp8266.h>
9+
#include <esp/uart.h>
10+
#include <stdio.h>
11+
#include "FreeRTOS.h"
12+
#include "task.h"
13+
14+
ATCA_STATUS cmd_ecdh(uint32_t argc, char *argv[])
15+
{
16+
ATCA_STATUS status;
17+
if (argc >= 2) {
18+
uint8_t slot_num = atoi(argv[1]);
19+
if (slot_num > 0x7){
20+
LOG("Invalid slot number %d; must be between 0 and 7 for private keys", slot_num);
21+
return ATCA_BAD_PARAM;
22+
}
23+
24+
printf("Performing ECDH key exchange in slot %d\n", slot_num);
25+
uint8_t pubkeybytes[100];
26+
int pubkeylen = sizeof(pubkeybytes);
27+
status = read_pubkey_stdin(pubkeybytes, &pubkeylen);
28+
if (status != ATCA_SUCCESS)
29+
{
30+
RETURN(status, "Failed to read public key");
31+
}
32+
33+
LOG("Got valid looking pubkey; does this look correct?");
34+
uint8_t *keyptr = pubkeybytes + (pubkeylen - ATCA_PUB_KEY_SIZE);
35+
atcab_printbin_label((const uint8_t*)"pubkey ", keyptr, ATCA_PUB_KEY_SIZE);
36+
37+
if (!prompt_user()) {
38+
printf("Aborting\n");
39+
}else{
40+
printf("Performing ECDH key exchange\n");
41+
}
42+
43+
// Write key to device
44+
uint8_t pmk[ATCA_PRIV_KEY_SIZE];
45+
status = atcab_ecdh(slot_num, keyptr, pmk);
46+
if(status != ATCA_SUCCESS){
47+
RETURN(status, "Failed to obtain pre-master key");
48+
}
49+
atcab_printbin_label((const uint8_t*)"pmk ", pmk, ATCA_PRIV_KEY_SIZE);
50+
51+
return ATCA_SUCCESS;
52+
} else {
53+
printf("Error: missing slot number.\n");
54+
return ATCA_BAD_PARAM;
55+
}
56+
}

examples/atcatool/cmd_priv.c

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
2+
#include "uart_cmds.h"
3+
#include <stdint.h>
4+
#include <sys/types.h>
5+
#include <stdlib.h>
6+
#include <unistd.h>
7+
#include <string.h>
8+
#include <esp8266.h>
9+
#include <esp/uart.h>
10+
#include <stdio.h>
11+
#include "FreeRTOS.h"
12+
#include "task.h"
13+
14+
// get cert and priv key
15+
//> openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp256r1) -keyout cert.key -out cert.crt -days 3650
16+
17+
//#define PEM_PRIV_KEY_OFFSET 5
18+
#define PEM_PRIV_KEY_OFFSET 7
19+
20+
ATCA_STATUS cmd_priv(uint32_t argc, char *argv[])
21+
{
22+
ATCA_STATUS status;
23+
if (argc >= 2) {
24+
uint8_t slot_num = atoi(argv[1]);
25+
if (slot_num > 0x7){
26+
LOG("Invalid slot number %d; must be between 0 and 7 for private keys", slot_num);
27+
return ATCA_BAD_PARAM;
28+
}
29+
30+
uint8_t write_key_slot = 0;
31+
uint8_t *write_key = NULL;
32+
uint8_t random_num[RANDOM_NUM_SIZE];
33+
if (argc >= 3) {
34+
write_key_slot = atoi(argv[2]);
35+
if (write_key_slot == slot_num || write_key_slot < 0x0 || write_key_slot > 0xF) {
36+
LOG("Invalid slot for write key (%d); trying unencrypted write", (int)write_key_slot);
37+
write_key_slot = 0;
38+
write_key = NULL;
39+
} else {
40+
LOG("Writing write key to slot %d", (int)write_key_slot);
41+
if((status = atcab_random(random_num)) != ATCA_SUCCESS){
42+
RETURN(status, "Could not make random number");
43+
}
44+
write_key = random_num;
45+
if((status = atcab_write_bytes_zone(ATCA_ZONE_DATA, write_key_slot, 0, write_key, RANDOM_NUM_SIZE)) != ATCA_SUCCESS){
46+
RETURN(status, "Could not commit write key");
47+
}
48+
}
49+
}
50+
51+
printf("Programming private key in slot %d\n", slot_num);
52+
uint8_t privkeybytes[200];
53+
int privkeylen = sizeof(privkeybytes);
54+
status = read_privkey_stdin(privkeybytes, &privkeylen);
55+
if (status != ATCA_SUCCESS)
56+
{
57+
RETURN(status, "Failed to read private key");
58+
}
59+
60+
LOG("Got valid looking private key; does this look correct?");
61+
uint8_t *keyptr = privkeybytes + PEM_PRIV_KEY_OFFSET;
62+
atcab_printbin_label((const uint8_t*)"privkey ", keyptr, ATCA_PRIV_KEY_SIZE);
63+
64+
if (!prompt_user()) {
65+
printf("Aborting\n");
66+
return ATCA_SUCCESS;
67+
}else{
68+
printf("Writing key\n");
69+
}
70+
71+
// Write key to device
72+
uint8_t priv_key[ATCA_PRIV_KEY_SIZE + 4] = {0};
73+
memcpy(priv_key + 4, keyptr, ATCA_PRIV_KEY_SIZE);
74+
status = atcab_priv_write(slot_num, priv_key, write_key_slot, write_key);
75+
if(status != ATCA_SUCCESS){
76+
RETURN(status, "Failed to write key to slot");
77+
}
78+
79+
// Read public key
80+
uint8_t pub_key[ATCA_PUB_KEY_SIZE] = {0};
81+
if((status = atcab_get_pubkey(slot_num, pub_key)) != ATCA_SUCCESS){
82+
RETURN(status, "Could not get public key");
83+
}
84+
atcab_printbin_label((const uint8_t*)"pubkey ", pub_key, sizeof(pub_key));
85+
86+
return ATCA_SUCCESS;
87+
} else {
88+
printf("Error: missing slot number.\n");
89+
return ATCA_BAD_PARAM;
90+
}
91+
}

examples/atcatool/cmd_pub.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
2+
#include "uart_cmds.h"
3+
#include <stdint.h>
4+
#include <sys/types.h>
5+
#include <stdlib.h>
6+
#include <unistd.h>
7+
#include <string.h>
8+
#include <esp8266.h>
9+
#include <esp/uart.h>
10+
#include <stdio.h>
11+
#include "FreeRTOS.h"
12+
#include "task.h"
13+
14+
// get cert and priv key
15+
//> openssl req -new -x509 -nodes -newkey ec:<(openssl ecparam -name secp256r1) -keyout cert.key -out cert.crt -days 3650
16+
// get pub key
17+
//> openssl x509 -in cert.crt -pubkey -noout > pubkey.pem
18+
19+
ATCA_STATUS cmd_pub(uint32_t argc, char *argv[])
20+
{
21+
ATCA_STATUS status;
22+
if (argc >= 2) {
23+
uint8_t slot_num = atoi(argv[1]);
24+
if (slot_num < 0x8 || slot_num > 0xF){
25+
LOG("Invalid slot number %d; must be between 8 and 15 for public keys", slot_num);
26+
return ATCA_BAD_PARAM;
27+
}
28+
29+
printf("Programming public key in slot %d\n", slot_num);
30+
uint8_t pubkeybytes[100];
31+
int pubkeylen = sizeof(pubkeybytes);
32+
status = read_pubkey_stdin(pubkeybytes, &pubkeylen);
33+
if (status != ATCA_SUCCESS)
34+
{
35+
RETURN(status, "Failed to read public key");
36+
}
37+
38+
LOG("Got valid looking pubkey; does this look correct?");
39+
uint8_t *keyptr = pubkeybytes + (pubkeylen - ATCA_PUB_KEY_SIZE);
40+
atcab_printbin_label((const uint8_t*)"pubkey ", keyptr, ATCA_PUB_KEY_SIZE);
41+
42+
if (!prompt_user()) {
43+
printf("Aborting\n");
44+
}else{
45+
printf("Writing key\n");
46+
}
47+
48+
// Write key to device
49+
status = atcab_write_pubkey(slot_num, keyptr);
50+
if(status != ATCA_SUCCESS){
51+
RETURN(status, "Failed to write key to slot");
52+
}
53+
54+
return ATCA_SUCCESS;
55+
} else {
56+
printf("Error: missing slot number.\n");
57+
return ATCA_BAD_PARAM;
58+
}
59+
}

examples/atcatool/cmd_verify.c

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
2+
#include "uart_cmds.h"
3+
#include <stdint.h>
4+
#include <sys/types.h>
5+
#include <stdlib.h>
6+
#include <unistd.h>
7+
#include <string.h>
8+
#include <esp8266.h>
9+
#include <esp/uart.h>
10+
#include <stdio.h>
11+
#include "FreeRTOS.h"
12+
#include "task.h"
13+
14+
// make test hash
15+
//> openssl sha -sha256 cmd_pub.c
16+
// sign test hash
17+
//> openssl sha -sha256 -sign cert.key -hex cmd_pub.c
18+
19+
void get_line(char *buf, size_t buflen)
20+
{
21+
char ch;
22+
char cmd[200];
23+
int i = 0;
24+
while(1) {
25+
if (read(0, (void*)&ch, 1)) { // 0 is stdin
26+
printf("%c", ch);
27+
if (ch == '\n' || ch == '\r') {
28+
cmd[i] = 0;
29+
i = 0;
30+
printf("\n");
31+
strcpy(buf, cmd);
32+
return;
33+
} else {
34+
if (i < sizeof(cmd)) cmd[i++] = ch;
35+
}
36+
}
37+
}
38+
}
39+
40+
ATCA_STATUS cmd_verify(uint32_t argc, char *argv[])
41+
{
42+
ATCA_STATUS status;
43+
if (argc >= 2) {
44+
uint8_t slot_num = atoi(argv[1]);
45+
if (slot_num < 0x8 || slot_num > 0xF){
46+
LOG("Invalid slot number %d; must be between 8 and 15 for public keys", slot_num);
47+
return ATCA_BAD_PARAM;
48+
}
49+
50+
printf("Verifying with public key in slot %d\n", slot_num);
51+
char hash[100]; uint8_t hashbin[100]; int hashlen = sizeof(hashbin);
52+
char sig[200]; uint8_t sigbin[200]; int siglen = sizeof(sigbin);
53+
54+
printf("Please paste hash in the terminal (hex format)\n");
55+
get_line(hash, sizeof(hash));
56+
57+
status = atcab_hex2bin(hash, strlen(hash), hashbin, &hashlen);
58+
if(status != ATCA_SUCCESS){
59+
RETURN(status, "Could not parse hash hex");
60+
}
61+
62+
printf("Please paste signature in the terminal (hex format)\n");
63+
get_line(sig, sizeof(sig));
64+
65+
status = atcab_hex2bin(sig, strlen(sig), sigbin, &siglen);
66+
if(status != ATCA_SUCCESS){
67+
RETURN(status, "Could not parse signature hex");
68+
}
69+
70+
bool isVerified = false;
71+
printf("Trying to verify with\n");
72+
atcab_printbin_label((const uint8_t*)"hash ", hashbin, hashlen);
73+
printf("Len %d\n", hashlen);
74+
atcab_printbin_label((const uint8_t*)"sig ", sigbin, siglen);
75+
printf("Len %d\n", siglen);
76+
77+
uint8_t atca_sig[ATCA_SIG_SIZE] = {0};
78+
if(!parse_asn1_signature(sigbin, siglen, atca_sig))
79+
{
80+
RETURN(ATCA_PARSE_ERROR, "Could not parse ASN.1 signature");
81+
}
82+
83+
atcab_printbin_label((const uint8_t*)"atca_sig ", atca_sig, ATCA_SIG_SIZE);
84+
printf("Len %d\n", ATCA_SIG_SIZE);
85+
86+
status = atcab_verify_stored(hashbin, atca_sig, slot_num, &isVerified);
87+
if(status != ATCA_SUCCESS){
88+
RETURN(status, "Could not verify signature");
89+
}
90+
91+
printf(isVerified ? "Signature is valid\n" : "Signature is invalid\n");
92+
RETURN(status, "Done");
93+
} else {
94+
printf("Error: missing slot number.\n");
95+
return ATCA_BAD_PARAM;
96+
}
97+
}

0 commit comments

Comments
 (0)