1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #20673 from Einhornhool/pr/update-cryptoauth-shell-command

sys/shell: Update cryptoauthlib shell commands
This commit is contained in:
mguetschow 2024-07-11 06:54:52 +00:00 committed by GitHub
commit 3e712a54ca
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 827 additions and 44 deletions

View File

@ -0,0 +1,116 @@
/*
* Copyright (C) 2024 HAW Hamburg
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @file
* @brief Example configuration for Microchip CryptoAuth devices
*
* This is an example configuration for an ATECC608A device with
* some explanation on what the bits mean (for more details
* see complete datasheet).
*
* @note This configuration works with the example/psa_crypto application.
*
* @warning Parts of this config are insecure (e.g. some key slots can be
* written to repeatedly), so it should only be used for
* testing and development. If you want to use your device for
* production, please refer to the datasheet and change the bits
* accordingly.
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
*
*/
#ifndef ATECC608A_CONFIG_H
#define ATECC608A_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* @brief Example device configuration for the atecc608a.
*
*/
const uint8_t atecc608a_config[] = {
0x00, 0x00, 0x00, 0x00, /* Read only serial number */
0x00, 0x00, 0x00, 0x00, /* Read only revision number */
0x00, 0x00, 0x00, 0x00, /* Read only serial number */
0x00, 0x00, 0x00, 0x00, /* Read only reserved, I2C enable, reserved */
0xC0, 0x00, 0x00, 0x00, /* I2C address, reserved, CountMatch, chip mode*/
/* Private keys:
0x8720 = 1 0 0 0 | 0 1 1 1 | 0 0 1 0 | 0 0 0 0
7 - 4 | 3 - 0 | 15 - 12 | 11 - 8
- External signatures of arbitrary messages enabled
- Internal signatures of messages by GenDig/GenKey enabled
- ECDH operations permitted
- ECDH Master Secret will be output in the clear
- No write by write command */
0x87, 0x20, 0x87, 0x20, /* Slot 0, Slot 1 */
0x87, 0x20, 0x87, 0x20, /* Slot 2, Slot 3 */
/* Private Keys, write always allowed (use only for testing!!!)*/
0x87, 0x00, 0x87, 0x00,
/* Private key:
- as above but
- ECDH Master Secret will be written into slot n + 1 (7)*/
0x8F, 0x20, 0x87, 0x20, /* Slot 6, Slot 7 */
/* Data storage and public keys, anything goes */
0x00, 0x00, 0x00, 0x00, /* Slot 8, Slot 9 */
0x00, 0x00, 0x00, 0x00, /* Slot 10, Slot 11 */
0x00, 0x00, 0x00, 0x00, /* Slot 12, Slot 13 */
0x00, 0x00, 0x00, 0x00, /* Slot 14, Slot 15 */
0xFF, 0xFF, 0xFF, 0xFF, /* Counter 0 */
0x00, 0x00, 0x00, 0x00, /* Counter 0 */
0xFF, 0xFF, 0xFF, 0xFF, /* Counter 1 */
0x00, 0x00, 0x00, 0x00, /* Counter 1 */
0x00, 0x00, 0x00, 0x00, /* UseLock, VolatileKeyPermission, Secure Boot */
0x00, 0x00, 0x00, 0x00, /* KdflvLoc, KdflvStr, KdflcStr, Reserved */
0x00, 0x00, 0x00, 0x00, /* Reserved */
0x00, 0x00, 0x00, 0x00, /* Reserved */
0x00, 0x00, 0x55, 0x55, /* UserExtra, UserExtraAdd, LockValue, LockConfig */
0xFF, 0xFF, 0x00, 0x00, /* 2x SlotLocked, 2x ChipOptions */
0x00, 0x00, 0x00, 0x00, /* X509format */
/* Private Key, access only with Sign, GenKey, PrivWrite cmds
Public Version can always be generated
Slots are individually lockable with Lock command */
0x13, 0x00, 0x13, 0x00, /* KeyConfig 0, KeyConfig 1 */
0x13, 0x00, 0x13, 0x00, /* KeyConfig 2, KeyConfig 3 */
/* AES Key */
0x18, 0x00, 0x18, 0x00, /* KeyConfig 4, KeyConfig 5 -> not usable as AES keys! */
/* Private Key
- Used for ECDH
- Slot 7 will contain corresponding Master Secret */
0x13, 0x00, 0x1F, 0x00, /* KeyConfig 6, KeyConfig 7 */
/* SHA Key or other data */
0x1C, 0x00, /* KeyConfig 8 */
/* ECC Public Keys */
0x10, 0x00, /* KeyConfig 9 */
0x10, 0x00, 0x10, 0x00, /* KeyConfig 10, KeyConfig 11 */
0x10, 0x00, 0x10, 0x00, /* KeyConfig 12, KeyConfig 13 */
/* SHA Key or other data */
0x1C, 0x00, 0x1C, 0x00 /* KeyConfig 14, KeyConfig 15 */
};
#ifdef __cplusplus
}
#endif
#endif /* ATECC608A_CONFIG_H */

View File

@ -13,16 +13,70 @@
* @file * @file
* @brief Shell commands for the cryptoauthlib module * @brief Shell commands for the cryptoauthlib module
* *
* Currently supported devices:
* - ATECC508A
* - ATECC608
*
* This relies on a config header file being present in
* pkg/cryptoauthlib/include.
* The present example configuration can be exchanged or
* modified if needed.
*
* @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de> * @author Lena Boeckmann <lena.boeckmann@haw-hamburg.de>
* *
* @} * @}
*/ */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdint.h> #include <stdint.h>
#include "atca.h"
#include "atca_params.h"
#include "cryptoauthlib.h" #include "cryptoauthlib.h"
#include "shell.h" #include "shell.h"
#include "atecc608a_config.h"
#define ATCA_KEY_SLOT_COUNT (16)
#define ATCA_X509_KEY_COUNT (4)
#define SERIAL_NO_START_01 (0)
#define REVISION_NO_START (4)
#define SERIAL_NO_START_02 (8)
#define AES_ENABLE (13)
#define I2C_ENABLE (14)
#define I2C_ADDRESS (16)
#define COUNT_MATCH (18)
#define OTP_MODE (18)
#define CHIP_MODE (19)
#define SLOT_CONFIG_START (20)
#define COUNTER_01_START (52)
#define COUNTER_02_START (60)
#define LAST_KEY_USE_START (68)
#define USE_LOCK (68)
#define VOLATILE_KEY_PERMIT (69)
#define SECURE_BOOT_START (70)
#define KDF_IV_LOC (72)
#define USER_EXTRA (84)
#define USER_EXTRA_ADD (85)
#define SELECTOR (85)
#define LOCK_VALUE (86)
#define LOCK_CONFIG (87)
#define SLOT_LOCKED_START (88)
#define CHIP_OPTIONS_START (90)
#define X509_FORMAT_START (92)
#define KEY_CONFIG_START (96)
uint8_t config_backup[ATCA_NUMOF][ATCA_ECC_CONFIG_SIZE];
int device_index = 0;
/**
* @brief Convert one byte into a binary number
*
* @param[out] result Will contain binary number as a string
* @param[in] byte Byte to convert
*/
void get_bin(char *result, uint8_t byte) void get_bin(char *result, uint8_t byte)
{ {
for (int i = 0; i < 8; i++) { for (int i = 0; i < 8; i++) {
@ -31,22 +85,529 @@ void get_bin(char *result, uint8_t byte)
result[8] = '\0'; result[8] = '\0';
} }
static int _read_config(void) /**
* @brief Converts an ATCA device type into a string
*
* @param devtype ATCADeviceType
* @return char* Device type as string
*/
static char* _convert_atca_devtype(ATCADeviceType devtype)
{
switch(devtype) {
case ATECC508A:
return "ATECC508A";
case ATECC608:
return "ATECC608";
default:
return "Unsupported device";
}
}
/**
* @brief Print read-only section of the configuration zone.
*
* Reserved bytes that don't mean anything are omitted.
*
* @param[in] data Pointer to buffer with input data
* @param devtype Type of the device currently used
*/
static void _print_dev_info_ro(uint8_t* data, ATCADeviceType devtype)
{
printf("Serial No (Pt. 1) | ");
for (int i = 0; i < 4; i++) {
printf("0x%02x ", data[SERIAL_NO_START_01+i]);
}
puts("");
printf("Revision No. | ");
for (int i = 0; i < 4; i++) {
printf("0x%02x ", data[REVISION_NO_START+i]);
}
puts("");
printf("Serial No (Pt. 2) | ");
for (int i = 0; i < 5; i++) {
printf("0x%02x ", data[SERIAL_NO_START_02+i]);
}
puts("");
if (devtype == ATECC608) {
if (data[AES_ENABLE] & 0x01) {
printf("AES Enabled | True\n");
}
else {
printf("AES Enabled | False\n");
}
}
if (data[I2C_ENABLE] & 0x01) {
printf("I2C Enabled | True\n");
printf("Single Wire | False\n");
}
else {
printf("I2C Enabled | False\n");
printf("Single Wire | True\n");
}
}
/**
* @brief Get authorization mode
*
* @param data Byte of data to interpret
* @return char* Data interpretation as string
*/
static char* _get_authorization_mode(uint8_t data)
{
uint8_t auth_mode = data & 0x08;
return auth_mode ? "Authorization Output Mode" : "Intrustion Detection Mode";
}
/**
* @brief Prints the I2C address when I2C is enabled or the
* GPIO mode when Single Wire communication is enabled
*
* @param data Byte of data to interpret
* @param communications Device communications mode (0 = Single Wire, 1 = I2C)
*/
static void _print_i2c_addr_or_gpio_mode(uint8_t data, uint8_t communications)
{
if (communications) {
/* I2C enabled */
printf("I2C Address | 0x%02x\n", data);
}
else {
/* Single Wire enabled */
uint8_t gpio_mode = data & 0x03;
printf("GPIO Mode | ");
switch(gpio_mode) {
case 0x01:
printf("%s\n", _get_authorization_mode(data));
break;
case 0x10:
puts("Input");
break;
case 0x11:
puts("Output");
break;
default:
puts("Disabled");
}
uint8_t gpio_default = data & 0x04;
if (gpio_default) {
puts("GPIO Default | high");
}
else {
puts("GPIO Default | low");
}
if (gpio_mode) {
if (gpio_mode == 0x01) {
printf("SignalKey for authorization has ID %d\n", data & 0xF0);
}
else {
printf("SignalKey/KeyID is non-zero and invalid: 0x%02x\n", data & 0xF0);
}
}
}
}
/**
* @brief Prints the OTP mode or CountMatch, depending on device type.
*
* @param data Byte of data to interpret
*/
static void _print_countmatch_or_otp_mode(uint8_t data, ATCADeviceType devtype)
{
if (devtype == ATECC608) {
if (data & 0x01) {
puts("Counter Match | Enabled");
printf("CountMatchKey stored in slot %d\n", data & 0xF0);
}
else {
puts("Counter Match | Disabled");
}
}
else {
switch(data) {
case 0xAA:
printf("OTP Mode | Read-only\n");
break;
case 0x55:
printf("OTP Mode | Consumption\n");
break;
default:
printf("OTP Mode | None\n");
}
}
}
/**
* @brief Prints the chip mode
*
* @param data Byte of data to interpret
*/
static void _print_chip_mode(uint8_t data, ATCADeviceType devtype)
{
puts("ChipMode:");
if (devtype == ATECC608) {
if (data & 0x01) {
puts("I2C Address | I2C address was set by user and is stored in UserExtraAdd");
}
else {
puts("I2C Address | Default address");
}
}
else {
if (data & 0x01) {
puts("SelectorMode | Only writeable if zero");
}
else {
puts("SelectorMode | Always writeable");
}
}
if (data & 0x02) {
puts("TTLenable | Input levels VCC referenced");
}
else {
puts("TTLenable | Fixed input levels");
}
if (data & 0x04) {
puts("Watchdog | 10 sec (not recommended)");
}
else {
puts("Watchdog | 1.3 sec (recommended)");
}
if (devtype == ATECC608) {
printf("Clock Divider | 0x%02x\n", data & 0xF0);
}
}
/**
* @brief Print Key Slot Configurations in hexadecimal and binary format
*
* @param[in] data Pointer to buffer with input data
*/
static void _print_slot_config(uint8_t* data)
{
char binary[9];
puts("Slot Config");
puts("----------------------------------------");
puts("SlotID | Hex | Binary");
puts(" | | 7 0 | 15 8");
puts("--------+--------+----------------------");
int slotcount = 0;
for (size_t i = 0; i < ATCA_KEY_SLOT_COUNT*2; i += 2) {
if (slotcount < 10) {
printf("%d | 0x%02x%02x | ", slotcount, data[SLOT_CONFIG_START+i], data[SLOT_CONFIG_START+i+1]);
}
else {
printf("%d | 0x%02x%02x | ", slotcount, data[SLOT_CONFIG_START+i], data[SLOT_CONFIG_START+i+1]);
}
for (int j = 0; j < 2; j++) {
get_bin(binary, data[i]);
printf("%s | ", binary);
}
puts("");
slotcount++;
}
puts("");
}
/**
* @brief Print lock status of key slots
*
* @param[in] data Pointer to buffer with input data
*/
static void _print_slot_lock(uint8_t* data)
{
puts("\nSlotLocked (X = locked, - = unlocked):");
puts("Slot | 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
printf("Locked | ");
for (int j = 0; j < 2; j++) {
for (int i = 0; i < 8; i++) {
if ((data[SLOT_LOCKED_START+j] >> i) & 0x01) {
printf(" - ");
}
else {
printf(" X ");
}
}
}
puts("");
}
static void _print_chip_options(uint8_t* data)
{
puts("Chip Options:");
if (data[CHIP_OPTIONS_START] & 0x01) {
puts("Power On Self Test| Enabled");
}
else {
puts("Power On Self Test| Disabled");
}
if (data[CHIP_OPTIONS_START] & 0x02) {
puts("IO Prot Key | Enabled");
}
else {
puts("IO Prot Key | Disabled");
}
if (data[CHIP_OPTIONS_START] & 0x04) {
puts("AES KDF | Enabled");
}
else {
puts("AES KDF | Disabled");
}
uint8_t ecdh_prot = data[CHIP_OPTIONS_START+1] & 0x03;
switch(ecdh_prot) {
case 0x00:
puts("ECDH | Clear Output on Bus OK");
break;
case 0x01:
puts("ECDH | Encrypted Output on Bus OK");
break;
case 0x10:
puts("ECDH | Result stored in TempKey or EEPROM Key Slot");
break;
default:
puts("ECDH | Usage Not permitted");
}
uint8_t kdf_prot = data[CHIP_OPTIONS_START+1] & 0x0C;
switch(kdf_prot) {
case 0x00:
puts("KDF | Clear Output on Bus OK");
break;
case 0x01:
puts("KDF | Encrypted Output on Bus OK");
break;
case 0x10:
puts("KDF | Result stored in TempKey or EEPROM Key Slot");
break;
default:
puts("KDF | Usage Not permitted");
}
printf("IO Protection Key stored in slot %d\n", data[CHIP_OPTIONS_START+1] & 0xF0);
}
/**
* @brief Print X509 format restrictions
*
* @param[in] data Pointer to buffer with input data
*/
static void _print_x509_format(uint8_t* data)
{
puts("\nX509 Format:");
for (int i = 0; i < 4; i++) {
if (data[X509_FORMAT_START+i] == 0x00) {
printf("PubKey %d | No restrictions\n", i);
}
else {
printf("PubKey %d:\n", i);
printf("- PublicPosition | 0x%02x\n", data[X509_FORMAT_START+i] & 0x0F);
printf("- TemplateLength | 0x%02x\n", data[X509_FORMAT_START+i] & 0xF0);
}
}
}
/**
* @brief Print key configurations
*
* @param[in] data Pointer to buffer with input data
*/
static void _print_key_config(uint8_t* data)
{
size_t atca_key_config_bytes = ATCA_KEY_SLOT_COUNT*2;
char binary[9];
puts("\nKey Config");
puts("----------------------------------------");
puts("SlotID | Hex | Binary");
puts(" | | 7 0 | 15 8");
puts("--------+--------+----------------------");
int slotcount = 0;
for (size_t i = 0; i < atca_key_config_bytes; i += 2) {
if (slotcount < 10) {
printf("%d | 0x%02x%02x | ", slotcount, data[KEY_CONFIG_START+i], data[KEY_CONFIG_START+i+1]);
}
else {
printf("%d | 0x%02x%02x | ", slotcount, data[KEY_CONFIG_START+i], data[KEY_CONFIG_START+i+1]);
}
for (int j = 0; j < 2; j++) {
get_bin(binary, data[KEY_CONFIG_START+i]);
printf("%s | ", binary);
}
puts("");
slotcount++;
}
puts("");
}
static void _print_secure_boot(uint8_t* data)
{
uint8_t secure_boot_mode = data[SECURE_BOOT_START] & 0x03;
switch(secure_boot_mode) {
case 0x01:
puts("SecureBootMode | Full");
break;
case 0x10:
puts("SecureBootMode | Stored signature");
break;
case 0x11:
puts("SecureBootMode | Stored digest");
break;
default:
puts("SecureBootMode | Disabled");
}
if (data[SECURE_BOOT_START] & 0x08) {
puts("SecureBootPersist | Enabled");
}
else {
puts("SecureBootPersist | Disabled");
}
if (data[SECURE_BOOT_START] & 0x10) {
puts("SecureBootNonce | Required, must use ATECC608 RNG");
}
else {
puts("SecureBootNonce | Optional, controlled by SecureBootMode");
}
printf("Secure Boot Signature or Digest stored in slot %d\n", data[SECURE_BOOT_START+1] & 0x0F);
printf("Secure Boot Public Key stored in slot %d\n", data[SECURE_BOOT_START+1] & 0xF0);
}
static int _read_config(ATCADevice dev)
{ {
uint8_t data[ATCA_ECC_CONFIG_SIZE]; uint8_t data[ATCA_ECC_CONFIG_SIZE];
uint8_t data_count = 0;
char binary[9];
memset(data, 0, ATCA_ECC_CONFIG_SIZE); memset(data, 0, ATCA_ECC_CONFIG_SIZE);
if (atcab_read_config_zone(data) != ATCA_SUCCESS) { int status = calib_read_config_zone(dev, data);
if (status != ATCA_SUCCESS) {
printf("Error reading config zone\n"); printf("Error reading config zone\n");
return 1; return 1;
} }
printf("Config zone: \n\n"); printf("Config Zone\n");
puts("Device Info (Read Only)");
puts("--------------------------------------------");
ATCADeviceType devtype = dev->mIface.mIfaceCFG->devtype;
printf("Device Type | %s\n", _convert_atca_devtype(devtype));
printf("%03d:%03d ", data_count, data_count+3); _print_dev_info_ro(data, devtype);
puts("--------------------------------------------\n");
puts("Device Info (Writable)");
puts("---------------------------------------------");
_print_i2c_addr_or_gpio_mode(data[I2C_ADDRESS], data[I2C_ENABLE] & 0x01);
_print_countmatch_or_otp_mode(data[OTP_MODE], devtype);
_print_chip_mode(data[CHIP_MODE], devtype);
puts("");
_print_slot_config(data);
printf("Counter 0 | 0x%02x 0x%02x 0x%02x 0x%02x\n", data[COUNTER_01_START],
data[COUNTER_01_START+1],
data[COUNTER_01_START+2],
data[COUNTER_01_START+3]);
printf("Counter 1 | 0x%02x 0x%02x 0x%02x 0x%02x\n", data[COUNTER_02_START],
data[COUNTER_02_START+1],
data[COUNTER_02_START+2],
data[COUNTER_02_START+3]);
if (devtype == ATECC608) {
if ((data[USE_LOCK] & 0x0F) == 0x0A) {
puts("UseLockEnable | True");
printf("UseLockKey is stored in slot %d\n", data[USE_LOCK] & 0xF0);
}
else {
puts("UseLockEnable | False");
}
if (data[VOLATILE_KEY_PERMIT] & 0x80) {
puts("VolatileKeyPermit | Enabled");
printf("Volatile Key Permit key stored in slot %d\n", data[VOLATILE_KEY_PERMIT] & 0x0F);
}
else {
puts("VolatileKeyPermit | Disabled");
}
_print_secure_boot(data);
printf("KDF IV Loc | %d\n", data[KDF_IV_LOC]);
}
else {
for (int i = LAST_KEY_USE_START; i < ATCA_KEY_SLOT_COUNT; i++) {
printf("LastKeyUse %d | 0x%02x\n", i, data[i]);
}
}
printf("UserExtra | 0x%02x\n", data[USER_EXTRA]);
if (devtype == ATECC608) {
printf("UserExtraAdd (I2C)| 0x%02x\n", data[USER_EXTRA_ADD]);
}
else{
printf("Selector | 0x%02x\n", data[SELECTOR]);
}
if (data[LOCK_VALUE] == 0x00) {
puts("LockValue | Data and OTP Locked");
}
else {
puts("LockValue | Data and OTP Unlocked");
}
if (data[LOCK_CONFIG] == 0x00) {
puts("LockConfig | Config Zone Locked");
}
else {
puts("LockConfig | Config Zone Unlocked");
}
_print_slot_lock(data);
if (devtype == ATECC608) {
_print_chip_options(data);
}
_print_x509_format(data);
_print_key_config(data);
return 0;
}
static int _read_config_bin(ATCADevice dev)
{
uint8_t data[ATCA_ECC_CONFIG_SIZE];
int data_count = 0;
char binary[9];
memset(data, 0, ATCA_ECC_CONFIG_SIZE);
int status = calib_read_config_zone(dev, data);
if (status != ATCA_SUCCESS) {
printf("Error reading config zone\n");
return 1;
}
puts("ConfigZone Binary Data:");
puts("---------------------------------------------------");
puts("Bytes \\ Bits | 7 0 7 0 7 0 7 0");
puts("-------------+-------------------------------------");
printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -54,7 +615,7 @@ static int _read_config(void)
} }
printf("SN0 SN1 SN2 SN3\n"); printf("SN0 SN1 SN2 SN3\n");
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -62,7 +623,7 @@ static int _read_config(void)
} }
printf("RN0 RN1 RN2 RN3\n"); printf("RN0 RN1 RN2 RN3\n");
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -70,7 +631,7 @@ static int _read_config(void)
} }
printf("SN4 SN5 SN6 SN7\n"); printf("SN4 SN5 SN6 SN7\n");
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -78,17 +639,21 @@ static int _read_config(void)
} }
printf("SN8 RSVD I2CE RSVD\n"); printf("SN8 RSVD I2CE RSVD\n");
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
data_count++; data_count++;
} }
printf("I2CA RSVD OTPM CM\n"); printf("I2CA RSVD OTPM CM\n\n");
puts("Slot Config");
puts("---------------------------------------------------");
puts("Bytes \\ Bits | 7 0 15 8 7 0 15 8");
puts("-------------+-------------------------------------");
for (int i = 0; i < 32; i += 4) { for (int i = 0; i < 32; i += 4) {
static int slotcount = 0; static int slotcount = 0;
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -103,7 +668,7 @@ static int _read_config(void)
for (int k = 0; k < 2; k++) { for (int k = 0; k < 2; k++) {
static int cnt_no = 0; static int cnt_no = 0;
for (int i = 0; i < 8; i += 4) { for (int i = 0; i < 8; i += 4) {
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -115,7 +680,7 @@ static int _read_config(void)
} }
for (int i = 0; i < 16; i += 4) { for (int i = 0; i < 16; i += 4) {
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -124,7 +689,7 @@ static int _read_config(void)
printf("LKU%d LKU%d LKU%d LKU%d\n", i, i+1, i+2, i+3); printf("LKU%d LKU%d LKU%d LKU%d\n", i, i+1, i+2, i+3);
} }
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -132,7 +697,7 @@ static int _read_config(void)
} }
printf("UE SEL LV LC\n"); printf("UE SEL LV LC\n");
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -140,17 +705,21 @@ static int _read_config(void)
} }
printf("SL0 SL1 RFU0 RFU1\n"); printf("SL0 SL1 RFU0 RFU1\n");
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
data_count++; data_count++;
} }
printf("X509-0 X509-1 X509-2 X509-3\n"); printf("X509-0 X509-1 X509-2 X509-3\n\n");
puts("Key Config");
puts("---------------------------------------------------");
puts("Bytes \\ Bits | 7 0 15 8 7 0 15 8");
puts("-------------+-------------------------------------");
for (int i = 0; i < 32; i += 4) { for (int i = 0; i < 32; i += 4) {
static int key_cnt = 0; static int key_cnt = 0;
printf("%03d:%03d ", data_count, data_count+3); printf("%03d:%03d | ", data_count, data_count+3);
for (int j = 0; j < 4; j++) { for (int j = 0; j < 4; j++) {
get_bin(binary, data[data_count]); get_bin(binary, data[data_count]);
printf("%s ", binary); printf("%s ", binary);
@ -161,16 +730,15 @@ static int _read_config(void)
printf("KC%d KC%d\n", key_cnt, key_cnt); printf("KC%d KC%d\n", key_cnt, key_cnt);
key_cnt++; key_cnt++;
} }
return 0; return 0;
} }
static int _check_lock_config(void) static int _check_lock_config(ATCADevice dev)
{ {
bool is_locked = false; bool is_locked_config = false;
atcab_is_locked(LOCK_ZONE_CONFIG, &is_locked); calib_is_locked(dev, LOCK_ZONE_CONFIG, &is_locked_config);
if (is_locked) { if (is_locked_config) {
printf("Config zone is locked\n"); printf("Config zone is locked\n");
} }
else { else {
@ -180,12 +748,12 @@ static int _check_lock_config(void)
return 0; return 0;
} }
static int _check_lock_data(void) static int _check_lock_data(ATCADevice dev)
{ {
bool is_locked = false; bool is_locked_data = false;
atcab_is_locked(LOCK_ZONE_DATA, &is_locked); calib_is_locked(dev, LOCK_ZONE_DATA, &is_locked_data);
if (is_locked) { if (is_locked_data) {
printf("Data zone is locked\n"); printf("Data zone is locked\n");
} }
else { else {
@ -195,50 +763,149 @@ static int _check_lock_data(void)
return 0; return 0;
} }
static int _lock_config(void) static int _lock_config(ATCADevice dev)
{ {
bool is_locked = false; bool is_locked_config = false;
atcab_is_locked(LOCK_ZONE_CONFIG, &is_locked); calib_is_locked(dev, LOCK_ZONE_CONFIG, &is_locked_config);
if (is_locked) { if (is_locked_config) {
printf("Error: Config zone is already locked\n"); printf("Error: Config zone is already locked\n");
return 1; return 1;
} }
if (atcab_lock_config_zone() != ATCA_SUCCESS) { if (calib_lock_config_zone(dev) != ATCA_SUCCESS) {
printf("Error: Locking failed\n"); printf("Error: Locking failed\n");
return 1; return 1;
} }
printf("Device successfully locked\n"); printf("Config Zone successfully locked\n");
return 0; return 0;
} }
static int _cryptoauth(int argc, char **argv) static int _lock_data(ATCADevice dev)
{
bool is_locked_data = false;
calib_is_locked(dev, LOCK_ZONE_DATA, &is_locked_data);
if (is_locked_data) {
printf("Error: Data zone is already locked\n");
return 1;
}
if (calib_lock_data_zone(dev) != ATCA_SUCCESS) {
printf("Error: Locking failed\n");
return 1;
}
printf("Data Zone successfully locked\n");
return 0;
}
static int _set_dev(char* id)
{
int index = atoi(id);
if (index > (int)ATCA_NUMOF-1) {
printf("Invalid ID, can be 0 - %d\n", ATCA_NUMOF-1);
return 1;
}
device_index = index;
return 0;
}
static int _show_dev(void)
{
puts("Set | ID | DevType | I2C Addr");
puts("----|----|-----------|---------");
for (size_t i = 0; i < ATCA_NUMOF; i++) {
char dev_set = ((size_t)device_index == i ? '*' : ' ');
ATCADeviceType devtype = atca_devs_ptr[i]->mIface.mIfaceCFG->devtype;
printf("%c | %d | %s | 0x%02x\n",
dev_set,
i,
_convert_atca_devtype(devtype),
atca_devs_ptr[i]->mIface.mIfaceCFG->atcai2c.address);
}
return 0;
}
static int _write_config(ATCADevice dev)
{
ATCA_STATUS status = calib_read_config_zone(dev, config_backup[device_index]);
if (status != ATCA_SUCCESS) {
printf("Error reading config zone\n");
return 1;
}
status = calib_write_config_zone(dev, atecc608a_config);
if (status != ATCA_SUCCESS) {
printf("Writing config zone failed: 0x%02x\n", status);
return 1;
}
return 0;
}
static int _restore_config(ATCADevice dev)
{
ATCA_STATUS status = calib_write_config_zone(dev, config_backup[device_index]);
if (status != ATCA_SUCCESS) {
printf("Restoring config zone failed: 0x%02x\n", status);
return 1;
}
return 0;
}
static int _atca(int argc, char **argv)
{ {
if (argc > 1) { if (argc > 1) {
if ((strcmp(argv[1], "read") == 0)) { if ((strcmp(argv[1], "show_dev") == 0)) {
return _read_config(); return _show_dev();
}
else if ((strcmp(argv[1], "set_dev") == 0)) {
if (argc < 3) {
puts("Please enter valid device index number");
return 1;
}
return _set_dev(argv[2]);
}
else if ((strcmp(argv[1], "write") == 0)) {
return _write_config(atca_devs_ptr[device_index]);
}
else if ((strcmp(argv[1], "restore") == 0)) {
return _restore_config(atca_devs_ptr[device_index]);
}
else if ((strcmp(argv[1], "read") == 0)) {
return _read_config(atca_devs_ptr[device_index]);
}
else if ((strcmp(argv[1], "read_bin") == 0)) {
return _read_config_bin(atca_devs_ptr[device_index]);
} }
else if ((strcmp(argv[1], "lock_c") == 0)) { else if ((strcmp(argv[1], "lock_c") == 0)) {
return _lock_config(); return _lock_config(atca_devs_ptr[device_index]);
}
else if ((strcmp(argv[1], "lock_d") == 0)) {
return _lock_data(atca_devs_ptr[device_index]);
} }
else if ((strcmp(argv[1], "check_lc") == 0)) { else if ((strcmp(argv[1], "check_lc") == 0)) {
return _check_lock_config(); return _check_lock_config(atca_devs_ptr[device_index]);
} }
else if ((strcmp(argv[1], "check_ld") == 0)) { else if ((strcmp(argv[1], "check_ld") == 0)) {
return _check_lock_data(); return _check_lock_data(atca_devs_ptr[device_index]);
} }
} }
else { else {
printf("* show_dev - list available devices and IDs\n");
printf("* set_dev <number> - set and initialize an atca device (defaults to ID 0)\n");
printf("* write - write configuration to config zone (stores backup of current config)\n");
printf("* restore - restore device config zone to previous state\n");
printf("* read - read Microchip CryptoAuth device's config zone\n"); printf("* read - read Microchip CryptoAuth device's config zone\n");
printf("* lock_c - PERMANENTLY lock Microchip CryptoAuth device's config \ printf("* read_bin - read config zone and print binary data\n");
zone (cannot be undone!)\n"); printf("* lock_c - PERMANENTLY lock Microchip CryptoAuth device's config zone (cannot be undone!)\n");
printf("* lock_d - PERMANENTLY lock Microchip CryptoAuth device's data zone (cannot be undone!)\n");
printf("* check_lc - check if Microchip CryptoAuth device's config zone is locked\n"); printf("* check_lc - check if Microchip CryptoAuth device's config zone is locked\n");
printf("* check_ld - check if Microchip CryptoAuth device's data zone is locked\n"); printf("* check_ld - check if Microchip CryptoAuth device's data zone is locked\n");
} }
return 0; return 0;
} }
SHELL_COMMAND(cryptoauth, "Commands for Microchip CryptoAuth devices", SHELL_COMMAND(atca, "Commands for Microchip CryptoAuth devices",
_cryptoauth); _atca);