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

securechip: add initial Optiga implementation #1341

Open
wants to merge 2 commits 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,17 @@ set(PLATFORM-BITBOX02-SOURCES ${PLATFORM-BITBOX02-SOURCES} PARENT_SCOPE)
set(SECURECHIP-SOURCES
${CMAKE_SOURCE_DIR}/src/atecc/atecc.c
${CMAKE_SOURCE_DIR}/src/securechip/securechip.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_gpio.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_i2c.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_ifx_i2c_config.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_logger.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_os_datastore.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_os_event.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_os_lock.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_os_timer.c
${CMAKE_SOURCE_DIR}/src/optiga/pal/pal_os_memory.c
${CMAKE_SOURCE_DIR}/src/optiga/optiga.c
)
set(SECURECHIP-SOURCES ${SECURECHIP-SOURCES} PARENT_SCOPE)

Expand Down
20 changes: 10 additions & 10 deletions src/atecc/atecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ static ATCA_STATUS _lock_slot(atecc_slot_t slot)
static ATCA_STATUS _factory_setup(void)
{
if (_interface_functions == NULL) {
return (ATCA_STATUS)ATECC_ERR_IFS;
return (ATCA_STATUS)SC_ERR_IFS;
}
bool is_config_locked = false;
ATCA_STATUS result = atcab_is_locked(LOCK_ZONE_CONFIG, &is_config_locked);
Expand Down Expand Up @@ -336,14 +336,14 @@ static int _verify_config(void)
return result;
}
if (!is_locked) {
return ATECC_ERR_ZONE_UNLOCKED_CONFIG;
return SC_ATECC_ERR_ZONE_UNLOCKED_CONFIG;
}
result = atcab_is_locked(LOCK_ZONE_DATA, &is_locked);
if (result != ATCA_SUCCESS) {
return result;
}
if (!is_locked) {
return ATECC_ERR_ZONE_UNLOCKED_DATA;
return SC_ATECC_ERR_ZONE_UNLOCKED_DATA;
}

bool same_config = false;
Expand All @@ -352,7 +352,7 @@ static int _verify_config(void)
return result;
}
if (!same_config) {
return ATECC_ERR_CONFIG_MISMATCH;
return SC_ERR_CONFIG_MISMATCH;
}

// Check that the slots are individually locked.
Expand All @@ -361,29 +361,29 @@ static int _verify_config(void)
return result;
}
if (!is_locked) {
return ATECC_ERR_SLOT_UNLOCKED_IO;
return SC_ATECC_ERR_SLOT_UNLOCKED_IO;
}
result = atcab_is_slot_locked(ATECC_SLOT_AUTHKEY, &is_locked);
if (result != ATCA_SUCCESS) {
return result;
}
if (!is_locked) {
return ATECC_ERR_SLOT_UNLOCKED_AUTH;
return SC_ATECC_ERR_SLOT_UNLOCKED_AUTH;
}
result = atcab_is_slot_locked(ATECC_SLOT_ENCRYPTION_KEY, &is_locked);
if (result != ATCA_SUCCESS) {
return result;
}
if (!is_locked) {
return ATECC_ERR_SLOT_UNLOCKED_ENC;
return SC_ATECC_ERR_SLOT_UNLOCKED_ENC;
}
return ATCA_SUCCESS;
}

int atecc_setup(const securechip_interface_functions_t* ifs)
{
if (ifs == NULL) {
return ATECC_ERR_IFS;
return SC_ERR_IFS;
}
_interface_functions = ifs;
ATCA_STATUS result = atcab_init(&cfg);
Expand Down Expand Up @@ -527,10 +527,10 @@ bool atecc_update_keys(void)
static int _atecc_kdf(atecc_slot_t slot, const uint8_t* msg, size_t len, uint8_t* kdf_out)
{
if (len > 127 || (slot != ATECC_SLOT_ROLLKEY && slot != ATECC_SLOT_KDF)) {
return ATECC_ERR_INVALID_ARGS;
return SC_ERR_INVALID_ARGS;
}
if (msg == kdf_out) {
return ATECC_ERR_INVALID_ARGS;
return SC_ERR_INVALID_ARGS;
}

ATCA_STATUS result = _authorize_key();
Expand Down
88 changes: 3 additions & 85 deletions src/atecc/atecc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,112 +15,30 @@
#ifndef _ATECC_H_
#define _ATECC_H_

/* ATECC implementation of the secure chip functions. */
/* See securechip.h for the docstrings of the individual functions. */

#include "compiler_util.h"
#include "securechip/securechip.h"
#include <platform/platform_config.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>

typedef enum {
ATECC_ERR_ZONE_UNLOCKED_CONFIG = -1,
ATECC_ERR_ZONE_UNLOCKED_DATA = -2,
ATECC_ERR_CONFIG_MISMATCH = -3,
ATECC_ERR_SLOT_UNLOCKED_IO = -4,
ATECC_ERR_SLOT_UNLOCKED_AUTH = -5,
ATECC_ERR_SLOT_UNLOCKED_ENC = -6,
ATECC_ERR_IFS = -7,
ATECC_ERR_INVALID_ARGS = -8,
} atecc_error_t;

/**
* Initializes the cryptoauthlib communication, by providing a custom i2c chip
* communication interface/bridge to cryptoauthlib. On first call, the chip
* is configured and locked.
* @param[in] ifs Interface functions.
* @return values of `atecc_error_t` if negative, values of `ATCA_STATUS` if positive, 0 on
* success.
*/
USE_RESULT int atecc_setup(const securechip_interface_functions_t* ifs);

/**
* Updates the two KDF keys (rollkey and kdf key). The previous keys are lost
* and cannot be restored. Calling this function does not increment the
* monotonic counter Counter0.
* @return true on success.
*/
USE_RESULT bool atecc_update_keys(void);

/**
* Perform HMAC using the key in KDF slot with the input msg.
* @param[in] msg Use this msg as input
* @param[in] len Must be <= 127.
* @param[out] kdf_out Must have size 32. Result of the kdf will be stored here.
* Cannot be the same as `msg`.
* @return values of `atecc_error_t` if negative, values of `ATCA_STATUS` if positive, 0 on
*/
USE_RESULT int atecc_kdf(const uint8_t* msg, size_t len, uint8_t* kdf_out);

/**
* Perform KDF using the key in rollkey slot with the input msg.
* Calling this function increments the
* monotonic counter Counter0.
* @param[in] msg Use this msg as input
* @param[in] len Must be <= 127.
* @param[out] kdf_out Must have size 32. Result of the kdf will be stored here.
* Cannot be the same as `msg`.
* @return values of `securechip_error_t` if negative, values of `ATCA_STATUS` if positive, 0 on
*/
USE_RESULT int atecc_kdf_rollkey(const uint8_t* msg, size_t len, uint8_t* kdf_out);

/**
* Generates a new attestation device key and outputs the public key.
* @param[out] pubkey_out
*/
USE_RESULT bool atecc_gen_attestation_key(uint8_t* pubkey_out);

/**
* @param[in] msg 32 byte message to sign.
* @param[out] signature_out must be 64 bytes. R/S P256 signature.
*/
USE_RESULT bool atecc_attestation_sign(const uint8_t* challenge, uint8_t* signature_out);

/**
* Retrieves the number of remaining possible counter increments (max value - Counter0).
* The counter is increment when using `atecc_kdf()` (see its docstring).
* @param[out] remaining_out current value of the monotonic counter.
* @return false if there was a communication error with the SC.
*/
USE_RESULT bool atecc_monotonic_increments_remaining(uint32_t* remaining_out);

/**
* @param[out] rand_out must be 32 bytes.
*/
USE_RESULT bool atecc_random(uint8_t* rand_out);

#if APP_U2F == 1 || FACTORYSETUP == 1
/**
* Set the u2f counter to `counter`. Should only be used for initialization.
* @param[in] counter Value to set counter to
* @return True if success
*/
USE_RESULT bool atecc_u2f_counter_set(uint32_t counter);
#endif

#if APP_U2F == 1
/**
* Monotonically increase the U2F counter and return the current value
* @param[out] counter Next counter value
* @return True if success
*/
USE_RESULT bool atecc_u2f_counter_inc(uint32_t* counter);
#endif

/**
* Output the atecc model.
* @param[out] model_out atecc model
* @return True if success
*/
USE_RESULT bool atecc_model(securechip_model_t* model_out);

#endif
11 changes: 10 additions & 1 deletion src/memory/memory_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,14 @@ uint8_t memory_get_screen_type(void)

uint8_t memory_get_securechip_type(void)
{
return MEMORY_SECURECHIP_TYPE_ATECC;
chunk_shared_t chunk = {0};
memory_read_shared_bootdata(&chunk);
uint8_t securechip_type = chunk.fields.securechip_type;
util_zero(&chunk, sizeof(chunk));
switch (securechip_type) {
case MEMORY_SECURECHIP_TYPE_OPTIGA:
return securechip_type;
default:
return MEMORY_SECURECHIP_TYPE_ATECC;
}
}
2 changes: 1 addition & 1 deletion src/memory/memory_shared.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ typedef union {
uint8_t auto_enter;
uint8_t upside_down;
uint8_t screen_type;
uint8_t securechip_type;
// Following are used by firmware only
uint8_t reserved[1];
uint8_t io_protection_key_split[32];
uint8_t authorization_key_split[32];
uint8_t encryption_key_split[32];
Expand Down
Loading