diff --git a/.gitignore b/.gitignore index 9909a2e84..b3350c6e6 100644 --- a/.gitignore +++ b/.gitignore @@ -48,6 +48,7 @@ local.properties *.o .vs +.vscode # Python .tox/ @@ -61,3 +62,14 @@ dist/ /python/venv* /python/cryptoauthlib.egg-info /python/VERSION + +# Documents +docs/**/* +docs/html/**/* +docs/latex/**/* +dist-tools/cryptoauthlib* + +# Third party libraries +third_party/mbedtls/* +third_party/wolfssl/* + diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ae930d10..9d25ebcba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,15 +1,20 @@ -cmake_minimum_required(VERSION 2.6.4) +cmake_minimum_required(VERSION 3.1.0) project (cryptoauthlib C) # Set the current release version -set(VERSION "3.3.3") +set(VERSION "3.4.0") set(VERSION_MAJOR 3) -set(VERSION_MINOR 3) -set(VERSION_PATCH 3) +set(VERSION_MINOR 4) +set(VERSION_PATCH 0) # Build Options option(BUILD_TESTS "Create Test Application with library" OFF) -#set(ATCA_PKCS11 ON CACHE INTERNAL "") + +if(UNIX) +option(SETUP_INSTALLER "Setup installation and packaging as well" ON) +else() +set(SETUP_INSTALLER OFF CACHE INTERNAL "Disabling installation on this platform") +endif() # Default install root which is normally /usr/local/ set(CMAKE_INSTALL_PREFIX "/" CACHE INTERNAL "") @@ -17,52 +22,7 @@ set(CMAKE_INSTALL_PREFIX "/" CACHE INTERNAL "") # If including certificate definitions into the library then include them as ATCACERT_DEF_SRC #file(GLOB ATCACERT_DEF_SRC ABSOLUTE "app/*.c") -if(WIN32) -string(REPLACE "\\" "/" LOCAL_APP_DATA "$ENV{LOCALAPPDATA}/Microchip") -set(DEFAULT_LIB_PATH "${LOCAL_APP_DATA}" CACHE - STRING "The default absolute library path") -set(DEFAULT_INC_PATH "${LOCAL_APP_DATA}/${PROJECT_NAME}" CACHE - STRING "The default include install path") -set(DEFAULT_CONF_PATH "${LOCAL_APP_DATA}" CACHE - STRING "The default location of ${PROJECT_NAME}.conf") -set(DEFAULT_STORE_PATH "${LOCAL_APP_DATA}/${PROJECT_NAME}" CACHE - STRING "The default location of the filestore directory") -else() -include(GNUInstallDirs) -set(DEFAULT_LIB_PATH "${CMAKE_INSTALL_FULL_LIBDIR}" CACHE - STRING "The default absolute library path") -set(DEFAULT_INC_PATH "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}" CACHE - STRING "The default include install path") -set(DEFAULT_CONF_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/${PROJECT_NAME}" CACHE - STRING "The default location of ${PROJECT_NAME}.conf") -set(DEFAULT_STORE_PATH "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/${PROJECT_NAME}" CACHE - STRING "The default location of the filestore directory") -endif() - -set(DEFAULT_CONF_FILE_NAME "${PROJECT_NAME}.conf" CACHE - STRING "The default file for library configuration") - -if(NOT CMAKE_BUILD_TYPE) -if(WIN32) -set(CMAKE_BUILD_TYPE Release CACHE STRING "Default build type" FORCE) -else() -set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Default build type" FORCE) -endif() -endif() - -# Set up a default configuration file to install -configure_file(${PROJECT_SOURCE_DIR}/app/pkcs11/cryptoauthlib.conf.in ${PROJECT_BINARY_DIR}/${DEFAULT_CONF_FILE_NAME}) - -# Packaging -set(CPACK_PACKAGE_VENDOR "Microchip Technology Inc") -set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) -set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) -set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH}) -set(CPACK_GENERATOR "TGZ") -set(CPACK_SOURCE_GENERATOR "TGZ") -set(CPACK_SOURCE_IGNORE_FILES "build/*;\\.git/*") - -include(CPack) +include(cmake/check_environment.cmake) # Make sure when testing that everything goes where it should if(BUILD_TESTS) @@ -78,23 +38,7 @@ add_subdirectory(test) set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT cryptoauth_test) endif(BUILD_TESTS) -# Installation -install(DIRECTORY DESTINATION ${DEFAULT_CONF_PATH}) -install(CODE " - if(NOT EXISTS ${DEFAULT_CONF_PATH}/${DEFAULT_CONF_FILE_NAME}) - file(INSTALL ${PROJECT_BINARY_DIR}/${DEFAULT_CONF_FILE_NAME} - DESTINATION ${DEFAULT_CONF_PATH}) - endif() - ") -install(DIRECTORY DESTINATION ${DEFAULT_STORE_PATH} - DIRECTORY_PERMISSIONS - OWNER_EXECUTE OWNER_WRITE OWNER_READ - GROUP_EXECUTE GROUP_WRITE GROUP_READ - WORLD_EXECUTE WORLD_WRITE WORLD_READ - ) -install(CODE " - if(NOT EXISTS ${DEFAULT_STORE_PATH}/slot.conf.tmpl) - file(INSTALL ${PROJECT_SOURCE_DIR}/app/pkcs11/slot.conf.tmpl - DESTINATION ${DEFAULT_STORE_PATH}) - endif() - ") +# If we're installing the library then we'll add the global configuration files +if(SETUP_INSTALLER) +include(cmake/config_install.cmake) +endif() diff --git a/README.md b/README.md index 51a6c37d8..40f9689b4 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,9 @@ There are two major compiler defines that affect the operation of the library. changes required. The lower-level API will no longer use the new/delete functions and the init/release functions should be used directly. +Some specific options are available in the fully documented configuration files `lib/calib/calib_config.h`, +`atca_configuration.h`, `lib/crypto/crypto_config.h`, `lib/host/atca_host_config.h` which is also the place where features can be selected. + We provide some configurations focused on specific use cases and the checks are enabled by default. Release notes ----------- diff --git a/SECURITY.md b/SECURITY.md index 2888fbdbc..7e87f9e4e 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -12,6 +12,7 @@ The previous API version is maintained for a year after a new version is release | Version | Supported | Notes | | ------- | ------------------ | ----- | +| 3.4.x | :heavy_check_mark: | | | 3.3.x | :heavy_check_mark: | | | 3.2.x | :x: | Security updates until January 2022 | | < 3.2 | :x: | | diff --git a/app/pkcs11/example_pkcs11_config.c b/app/pkcs11/example_pkcs11_config.c index 4eadc3ca4..120d2e020 100644 --- a/app/pkcs11/example_pkcs11_config.c +++ b/app/pkcs11/example_pkcs11_config.c @@ -127,7 +127,7 @@ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Slot 0 - Device Private Key */ @@ -140,7 +140,7 @@ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Slot 0 - Device Public Key */ @@ -153,7 +153,7 @@ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Slot 0 - Device Public Key */ @@ -166,7 +166,7 @@ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Slot 0 - Device Public Key */ diff --git a/app/pkcs11/trust_pkcs11_config.c b/app/pkcs11/trust_pkcs11_config.c index ed0ab18b7..d7b2edf94 100644 --- a/app/pkcs11/trust_pkcs11_config.c +++ b/app/pkcs11/trust_pkcs11_config.c @@ -164,7 +164,7 @@ CK_RV pkcs11_trust_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Slot 0 - Device Private Key */ @@ -177,7 +177,7 @@ CK_RV pkcs11_trust_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Slot 0 - Device Public Key */ @@ -190,7 +190,7 @@ CK_RV pkcs11_trust_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Device Certificate */ @@ -203,7 +203,7 @@ CK_RV pkcs11_trust_load_objects(pkcs11_slot_ctx_ptr pSlot) if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(pSlot->slot_id, &pObject); if (pObject) { /* Signer Certificate */ diff --git a/app/wpc/atca_config.h b/app/wpc/atca_config.h new file mode 100644 index 000000000..d2d4ae6f4 --- /dev/null +++ b/app/wpc/atca_config.h @@ -0,0 +1,139 @@ +/* Auto-generated config file atca_config.h */ +#ifndef ATCA_CONFIG_H +#define ATCA_CONFIG_H + +/* MPLAB Harmony Common Include */ +#include "definitions.h" + +#ifndef ATCA_HAL_I2C +#define ATCA_HAL_I2C +#endif + + + +/** Include Device Support Options */ +#define ATCA_ATECC608_SUPPORT + + + + +/* Polling Configuration Options */ +#ifndef ATCA_POLLING_INIT_TIME_MSEC +#define ATCA_POLLING_INIT_TIME_MSEC 1 +#endif +#ifndef ATCA_POLLING_FREQUENCY_TIME_MSEC +#define ATCA_POLLING_FREQUENCY_TIME_MSEC 2 +#endif +#ifndef ATCA_POLLING_MAX_TIME_MSEC +#define ATCA_POLLING_MAX_TIME_MSEC 2500 +#endif + +/** Define if the library is not to use malloc/free */ +#define ATCA_NO_HEAP + +#define atca_delay_ms hal_delay_ms +#define atca_delay_us hal_delay_us + +/* \brief How long to wait after an initial wake failure for the POST to + * complete. + * If Power-on self test (POST) is enabled, the self test will run on waking + * from sleep or during power-on, which delays the wake reply. + */ +#ifndef ATCA_POST_DELAY_MSEC +#define ATCA_POST_DELAY_MSEC 25 +#endif + + +/* Define generic interfaces to the processor libraries */ + +#define PLIB_I2C_ERROR SERCOM_I2C_ERROR +#define PLIB_I2C_ERROR_NONE SERCOM_I2C_ERROR_NONE +#define PLIB_I2C_TRANSFER_SETUP SERCOM_I2C_TRANSFER_SETUP + +typedef bool (* atca_i2c_plib_read)(uint16_t, uint8_t *, uint32_t); +typedef bool (* atca_i2c_plib_write)(uint16_t, uint8_t *, uint32_t); +typedef bool (* atca_i2c_plib_is_busy)(void); +typedef PLIB_I2C_ERROR (* atca_i2c_error_get)(void); +typedef bool (* atca_i2c_plib_transfer_setup)(PLIB_I2C_TRANSFER_SETUP* setup, uint32_t srcClkFreq); + +typedef struct atca_plib_i2c_api +{ + atca_i2c_plib_read read; + atca_i2c_plib_write write; + atca_i2c_plib_is_busy is_busy; + atca_i2c_error_get error_get; + atca_i2c_plib_transfer_setup transfer_setup; +} atca_plib_i2c_api_t; + + + + +extern atca_plib_i2c_api_t sercom2_plib_i2c_api; + +/* WPC Configuration */ +#define WPC_CHAIN_DIGEST_HANDLE_0 0x03 +#define WPC_CHAIN_CERT_DEF_0 g_cert_def_2_device + +/* Define for a simple mapping of slot to certificate */ +#define WPC_STRICT_SLOT_INDEX + +/* One of the certificate format options is to generate the certificate serial + number from a hash of several data elements - this saves storage in the device + at the expense of code space and time */ +#define WPC_CERT_SN_FROM_HASH_EN FEATURE_DISABLED + +/* Enable the Power Transmitter API */ +#define WPC_MSG_PT_EN FEATURE_ENABLED + +/* Disable the Power Receiver API since this project is demonstrating the transmitter */ +#define WPC_MSG_PR_EN FEATURE_DISABLED + + +/* Turn off parameter checking in the library - enable for easier debugging in development */ +//#define ATCA_CHECK_PARAMS_EN FEATURE_DISABLED + +/* API Configuration Options */ +#define ATCAB_AES_EN FEATURE_DISABLED +#define ATCAB_AES_GCM_EN FEATURE_DISABLED +#define ATCAB_COUNTER_EN FEATURE_DISABLED +#define ATCAB_DERIVEKEY_EN FEATURE_DISABLED +#define ATCAB_ECDH_EN FEATURE_DISABLED +#define ATCAB_ECDH_ENC_EN FEATURE_DISABLED +#define ATCAB_GENDIG_EN FEATURE_DISABLED +#define ATCAB_GENKEY_MAC_EN FEATURE_DISABLED +#define ATCAB_HMAC_EN FEATURE_DISABLED +#define ATCAB_INFO_LATCH_EN FEATURE_DISABLED +#define ATCAB_KDF_EN FEATURE_DISABLED +#define ATCAB_LOCK_EN FEATURE_DISABLED +#define ATCAB_MAC_EN FEATURE_DISABLED +#define ATCAB_PRIVWRITE_EN FEATURE_DISABLED +/* By default the random command is only required for the power receiver to generate + challenges - because a health check on the rng before a sign can return failures + the power transmitter has a choice - enable the random command which will use more + code or retry the sign operation if a health check failure occurs. */ +#define ATCAB_RANDOM_EN WPC_MSG_PR_EN +#define ATCAB_READ_ENC_EN FEATURE_DISABLED +#define ATCAB_SECUREBOOT_EN FEATURE_DISABLED +#define ATCAB_SECUREBOOT_MAC_EN FEATURE_DISABLED +#define ATCAB_SELFTEST_EN FEATURE_DISABLED +#define ATCAB_SHA_HMAC_EN FEATURE_DISABLED +#define ATCAB_SIGN_INTERNAL_EN FEATURE_DISABLED +#define ATCAB_UPDATEEXTRA_EN FEATURE_DISABLED +/* Enable the verify command when the power receiver api is enabled - this helps + with testing - it is unnecessary for the power transmitter */ +#define ATCAB_VERIFY_EN WPC_MSG_PR_EN +#define ATCAB_WRITE_EN FEATURE_DISABLED + +/* Disable software cryptography */ +#define ATCAC_SHA1_EN FEATURE_DISABLED +#define ATCAC_SHA256_EN FEATURE_DISABLED + +/* Certificate Processing Configuration */ +#define ATCACERT_DATEFMT_UTC_EN FEATURE_ENABLED +#define ATCACERT_DATEFMT_GEN_EN FEATURE_ENABLED + +#define ATCACERT_DATEFMT_ISO_EN FEATURE_DISABLED +#define ATCACERT_DATEFMT_POSIX_EN FEATURE_DISABLED + + +#endif // ATCA_CONFIG_H diff --git a/app/wpc/wpc_apis.c b/app/wpc/wpc_apis.c new file mode 100644 index 000000000..c45cbab47 --- /dev/null +++ b/app/wpc/wpc_apis.c @@ -0,0 +1,452 @@ +/** + * \file + * \brief Provides api interfaces for WPC authentication. + * + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" +#include "wpc_apis.h" +#include "wpccert_client.h" +#include "atcacert/atcacert_client.h" + +#if WPC_MSG_PR_EN +/** \brief WPC API - Builds the CHALLENGE message + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpc_msg_challenge( + ATCADevice device, /**< [in] Device Context */ + uint8_t *const message, /**< [out] Message Buffer */ + uint16_t *const msg_len, /**< [in/out] In: message buffer size, Out: message length */ + const uint8_t slot /**< [in] Slot number */ + ) +{ + ATCA_STATUS status; + uint8_t nonce[32]; + + ATCA_CHECK_INVALID_MSG((!message || !msg_len), ATCA_BAD_PARAM, "NULL pointer received"); + + message[0] = WPC_CHALLENGE_HEADER; + message[1] = slot & 0x03; + +#if ATCAC_RANDOM_EN + if (!device) + { + status = ATCA_TRACE(atcac_sw_random(nonce, WPC_CHALLENGE_NONCE_LENGTH), "atcac_sw_random failed"); + } + else +#endif + { + status = ATCA_TRACE(atcab_random_ext(device, nonce), "atcab_random failed"); + } + + if (ATCA_SUCCESS == status) + { + memcpy(&message[2], nonce, WPC_CHALLENGE_NONCE_LENGTH); + *msg_len = WPC_CHALLENGE_LENGTH; + } + + return status; +} + +/** \brief WPC API - Builds the GET_DIGESTS message + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpc_msg_get_digests( + uint8_t *const message, /**< [out] Message Buffer */ + uint16_t *const msg_len, /**< [in/out] In: message buffer size, Out: message length */ + const uint8_t slot_mask /**< [in] Slots to request */ + ) +{ + ATCA_CHECK_INVALID_MSG((!message || !msg_len), ATCA_BAD_PARAM, "NULL pointer received"); + + message[0] = WPC_GET_DIGESTS_HEADER; + message[1] = slot_mask & 0x0F; + + *msg_len = WPC_GET_DIGESTS_LENGTH; + + return ATCA_SUCCESS; +} + +/** \brief WPC API - Builds the GET_CERTIFICATE message + * + * \note Offset and length are actually 11 bits + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpc_msg_get_certificate( + uint8_t *const message, /**< [out] Message Buffer */ + uint16_t *const msg_len, /**< [in/out] In: message buffer size, Out: message length */ + const uint8_t slot, /**< [in] Slot number */ + const uint16_t offset, /**< [in] byte offset requested */ + const uint16_t length /**< [in] length requested */ + ) +{ + ATCA_CHECK_INVALID_MSG((!message || !msg_len), ATCA_BAD_PARAM, "NULL pointer received"); + + uint8_t offset_a8 = (uint8_t)((offset >> 3) & 0xE0); + uint8_t length_a8 = (uint8_t)((length >> 5) & 0x1C); + + message[0] = WPC_GET_CERTIFICATE_HEADER; + message[1] = offset_a8 | length_a8 | (slot & 0x03); + message[2] = (offset & 0xFF); + message[3] = (length & 0xFF); + + *msg_len = WPC_GET_CERTIFICATE_LENGTH; + + return ATCA_SUCCESS; +} +#endif + +#if WPC_MSG_PT_EN +/** \brief WPC API - Builds the WPC Error response based on code and data + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpc_msg_error( + uint8_t *const response, /**< [out] Response Message */ + uint16_t *const resp_len, /**< [in/out] In: response buffer size, Out: response length */ + const uint8_t error_code, /**< [in] Error code to include in the Error response */ + const uint8_t error_data /**< [in] Error data to include in the Error response*/ + ) +{ + ATCA_CHECK_INVALID_MSG((!response || !resp_len), ATCA_BAD_PARAM, "NULL pointer received"); + ATCA_CHECK_INVALID_MSG((*resp_len < 3), ATCA_BAD_PARAM, "Buffer too small"); + + response[0] = WPC_ERROR_HEADER; + response[1] = error_code; + response[2] = error_data; + *resp_len = WPC_ERROR_LENGTH; + + return ATCA_FUNC_FAIL; +} + +/** \brief WPC API - Builds the WPC Authentication Challenge response + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpc_msg_challenge_auth( + ATCADevice device, /**< [in] Device Context */ + uint8_t *const response, /**< [out] Response Message */ + uint16_t *const resp_len, /**< [in/out] In: response buffer size, Out: response length */ + const uint8_t * request /**< [in] Request Message */ + ) +{ + ATCA_STATUS status; + uint8_t chain_digest[ATCA_SHA_DIGEST_SIZE]; + uint8_t slot; + uint16_t handle = 0; + const atcacert_def_t * cert_def; + + ATCA_CHECK_INVALID_MSG((!response || !resp_len || !request), ATCA_BAD_PARAM, "NULL pointer received"); + + slot = request[1] & 0x03; + + response[0] = WPC_CHALLENGE_AUTH_HEADER; + response[1] = (WPC_PROTOCOL_MAX_VERSION << 4) | wpccert_get_slots_populated(); + + if (ATCA_SUCCESS != (status = wpccert_get_slot_info(&handle, &cert_def, slot))) + { + return wpc_msg_error(response, resp_len, WPC_ERROR_INVALID_REQUEST, 0); + } + + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, ATCA_ZONE_DATA, handle, 0, + chain_digest, sizeof(chain_digest)))) + { + ATCA_TRACE(status, "atcab_read_bytes_zone execution is failed"); + return wpc_msg_error(response, resp_len, WPC_ERROR_UNSPECIFIED, 0); + } + + /* Return the LSB of the digest - SHA digests are stored as big endian */ + response[2] = chain_digest[ATCA_SHA_DIGEST_SIZE - 1]; + + /* Generate the signature */ + if (ATCA_SUCCESS != (status = wpc_auth_signature(device, chain_digest, cert_def->private_key_slot, request, + response, &response[3]))) + { + ATCA_TRACE(status, "wpc_auth_signature execution is failed"); + return wpc_msg_error(response, resp_len, WPC_ERROR_UNSPECIFIED, 0); + } + + *resp_len = WPC_CHALLENGE_AUTH_LENGTH; + + return ATCA_SUCCESS; +} + +ATCA_STATUS wpc_msg_digests( + ATCADevice device, /**< [in] Device Context */ + uint8_t *const response, /**< [out] Response Message */ + uint16_t *const resp_len, /**< [in/out] In: response buffer size, Out: response length */ + const uint8_t * request /**< [in] Request Message */ + ) +{ + ATCA_STATUS status; + uint8_t slot; + uint8_t * digest; + + ATCA_CHECK_INVALID_MSG((!request || !response), ATCA_BAD_PARAM, "NULL pointer received"); + + response[0] = WPC_DIGESTS_HEADER; + response[1] = (wpccert_get_slots_populated() << 4); + + digest = &response[2]; + for (slot = 0; slot < wpccert_get_slot_count(); slot++) + { + uint16_t handle = 0; + uint8_t slot_mask = (1 << slot); + if (request[1] & slot_mask) + { + if (ATCA_SUCCESS == wpccert_get_slot_info(&handle, NULL, slot)) + { + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, ATCA_ZONE_DATA, handle, 0, + digest, ATCA_SHA256_DIGEST_SIZE+1))) + { + ATCA_TRACE(status, "atcab_read_bytes_zone execution failed"); + return wpc_msg_error(response, resp_len, WPC_ERROR_UNSPECIFIED, 0); + } + else + { + response[1] |= slot_mask; + digest += ATCA_SHA256_DIGEST_SIZE; + } + } + } + } + *resp_len = (uint16_t)(digest - response); + + return ATCA_SUCCESS; +} + +/** \brief WPC API - Provides response to certificates request + * + * WPC Certificate chain format: + * [0-1] Length Total Length of the chain - Big endian + * [2-(1+n_rh)] Root Hash Hash of the root certificate - len: n_rh = 32 + * [2+n_rh ... Manufacturer Signing certificate - len: n_mc + * 1+n_rh+n_mc] + * [2+n_rh+n_mc ... Product Product certificate - len: n_puc + * 1+n_rh+n_mc+n_puc + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpc_msg_certificate( + ATCADevice device, /**< [in] Device Context */ + uint8_t *const response, /**< [out] WPC authentication challenge response from device */ + uint16_t *const resp_len, /**< [in] response buffer size + [out] data size on response */ + const uint8_t * request, /**< [in] WPC authentication challenge request from host */ + uint8_t * buffer, /**< [in] Temporary buffer - large enough to hold a certificate */ + const uint16_t buflen /**< [in] Length of the temporary buffer */ +) +{ + ATCA_STATUS status; + size_t n_mc = 0; + size_t n_puc = 0; + uint16_t offset; + uint16_t length; + uint8_t * data; + const atcacert_def_t * cert_def; + + ATCA_CHECK_INVALID_MSG((!buffer || !request || !response || !resp_len), + ATCA_BAD_PARAM, "NULL pointer received"); + + if (ATCA_SUCCESS != (status = wpccert_get_slot_info(NULL, &cert_def, request[1] & 0x03))) + { + return wpc_msg_error(response, resp_len, WPC_ERROR_INVALID_REQUEST, 0); + } + + offset = (((uint16_t)(request[1] & 0xE0)) << 8) | request[2]; + length = (((uint16_t)(request[1] & 0x1C)) << 8) | request[3]; + + /* Get the manufacturer certificate length if read will cross the region in anyway or include + * the total length of the chain */ + if ((offset < 2) || ((offset < WPC_CONST_OS_MC) && ((length == 0) || (length + offset > WPC_CONST_OS_MC))) + || ((offset > WPC_CONST_OS_MC) && (0x600 > offset))) + { + /* Get the manufacturer certificate length */ + if (ATCA_SUCCESS != (status = atcacert_read_cert_size(cert_def->ca_cert_def, &n_mc))) + { + status = ATCA_TRACE(status, "atcacert_read_cert_size execution is failed for mfg cert"); + return status; + } + } + + /* Get the product certificate length if the read will include it or the total chain length */ + if ((length == 0) || (offset < 2) || ((WPC_CONST_OS_MC < offset) && ((0x600 <= offset) || (n_mc < offset + length)))) + { + if (ATCA_SUCCESS != (status = atcacert_read_cert_size(cert_def, &n_puc))) + { + status = ATCA_TRACE(status, "atcacert_read_cert_size execution is failed for pdu cert"); + return status; + } + } + ATCA_CHECK_INVALID_MSG((n_puc > buflen || n_mc > buflen), ATCA_SMALL_BUFFER, "temporary buffer is too small for certificates"); + + /* Adjustment the total length if required */ + if (length == 0) + { + if (offset < 0x600) + { + length = WPC_CONST_OS_MC + (uint16_t)n_mc + (uint16_t)n_puc - offset; + } + else + { + length = (uint16_t)n_puc - (offset - 0x600); + } + } + + ATCA_CHECK_INVALID_MSG((length > *resp_len), ATCA_SMALL_BUFFER, "response buffer is too small"); + + *resp_len = length; + + /* Start the response creation */ + data = response; + *data++ = WPC_CERTIFICATE_HEADER; + + /* Skip over most of the chain if the special product certificate offset is being used */ + if (offset < 0x600) + { + /* Include chain length if the offset includes it */ + if (offset < 2) + { + uint16_t chain_length = WPC_CONST_OS_MC + n_mc + n_puc; + if (0 == offset) + { + *data++ = ((chain_length >> 8) & 0xFF); + length--; + } + *data++ = (chain_length & 0xFF); + length--; + } + + /* Copy in the root hash if the read includes it */ + if (offset < WPC_CONST_OS_MC) + { + uint16_t rh_length = length < WPC_CONST_N_RH ? length : WPC_CONST_N_RH; + memcpy(data, g_root_ca_digest, rh_length); + data += rh_length; + length -= rh_length; + } + + /* Read the manufacturer certificate */ + if ((offset > WPC_CONST_OS_MC) && (offset < (WPC_CONST_OS_MC + n_mc))) + { + uint16_t mc_length = length < n_mc ? length : n_mc; + if (ATCA_SUCCESS != (status = wpccert_read_cert(device, cert_def->ca_cert_def, buffer, &n_mc))) + { + return ATCA_TRACE(status, "wpccert_read_cert execution is failed for mfg cert"); + } + memcpy(data, &buffer[offset - WPC_CONST_OS_MC], mc_length); + data += mc_length; + length -= mc_length; + } + } + else + { + if ((size_t)(offset - 0x600) > n_puc) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Offset provided exceeds the length of the product certificate"); + } + } + + /* Read the product cert if there is remaining bytes to be read */ + if (length) + { + uint16_t puc_length = length < n_puc ? length : n_puc; + + if (offset < 0x600) + { + if (offset > WPC_CONST_OS_MC + n_mc) + { + offset -= WPC_CONST_OS_MC + n_mc; + } + else + { + offset = 0; + } + } + else + { + offset -= 0x600; + } + + if (ATCA_SUCCESS != (status = wpccert_read_cert(device, cert_def, buffer, &n_puc))) + { + return ATCA_TRACE(status, "wpccert_read_cert execution is failed for mfg cert"); + } + + memcpy(data, &buffer[offset], puc_length); + data += puc_length; + length -= puc_length; + } + + return status; +} + +/** \brief WPC API - Calculated the TBS Auth Signature for the given Chain digest + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpc_auth_signature( + ATCADevice device, /**< [in] Device Context */ + const uint8_t *chain_digest, /**< [in] WPC Authentication Cert Chain digest*/ + const uint16_t private_key_slot, /**< [in] WPC Authentication private key slot*/ + const uint8_t *request, /**< [in] WPC authentication challenge request from host */ + const uint8_t *other_data, /**< [in] Challegen response b0, b1 and Digest LSB*/ + uint8_t *const signature /**< [out] Signature for WPC authentication TBS */ + ) +{ + ATCA_STATUS status; + + uint8_t TBSAuth_data[53]; + uint8_t tbs_digest[ATCA_SHA_DIGEST_SIZE]; + uint8_t *data = TBSAuth_data; + + ATCA_CHECK_INVALID_MSG((!chain_digest || !request || !other_data || !signature), + ATCA_BAD_PARAM, "NULL pointer received"); + + *data++ = WPC_TBS_AUTH_PREFIX; + memcpy(data, chain_digest, ATCA_SHA_DIGEST_SIZE); + data += ATCA_SHA_DIGEST_SIZE; + memcpy(data, request, WPC_CHALLENGE_LENGTH); + data += WPC_CHALLENGE_LENGTH; + memcpy(data, other_data, 3); + data += 3; + + if (ATCA_SUCCESS != (status = atcab_hw_sha2_256(TBSAuth_data, sizeof(TBSAuth_data), tbs_digest))) + { + status = ATCA_TRACE(status, "atcab_hw_sha2_256 execution is failed"); + return status; + } + + if (ATCA_SUCCESS != (status = atcab_sign_ext(device, private_key_slot, tbs_digest, signature))) + { + status = ATCA_TRACE(status, "atcab_sign execution is failed"); + return status; + } + + return status; +} + +#endif diff --git a/app/wpc/wpc_apis.h b/app/wpc/wpc_apis.h new file mode 100644 index 000000000..3dd47bd00 --- /dev/null +++ b/app/wpc/wpc_apis.h @@ -0,0 +1,113 @@ +/** + * \file + * \brief Provides api interfaces for WPC authentication. + * + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef WPC_APIS_H +#define WPC_APIS_H + +#include "wpc_check_config.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* WPC Protocol Definitions */ + +#define WPC_PROTOCOL_VERSION 0x01 +#define WPC_PROTOCOL_MAX_VERSION 0x01 + +#define WPC_TBS_AUTH_PREFIX 0x41 +#define WPC_CONST_N_RH ATCA_SHA256_DIGEST_SIZE +#define WPC_CONST_OS_MC (2 + WPC_CONST_N_RH) + +/* WPC Header Format Macro */ +#define WPC_HEADER(x) ((WPC_PROTOCOL_VERSION << 4) | x) + +/* WPC Message Definitions */ + +/* Requests */ +#define WPC_GET_DIGESTS_TYPE 0x09 +#define WPC_GET_DIGESTS_HEADER WPC_HEADER(WPC_GET_DIGESTS_TYPE) +#define WPC_GET_DIGESTS_LENGTH (2) + +#define WPC_GET_CERTIFICATE_TYPE 0x0A +#define WPC_GET_CERTIFICATE_HEADER WPC_HEADER(WPC_GET_CERTIFICATE_TYPE) +#define WPC_GET_CERTIFICATE_LENGTH (4) + +#define WPC_CHALLENGE_TYPE 0x0B +#define WPC_CHALLENGE_HEADER WPC_HEADER(WPC_CHALLENGE_TYPE) +#define WPC_CHALLENGE_NONCE_LENGTH (16) +#define WPC_CHALLENGE_LENGTH (2 + WPC_CHALLENGE_NONCE_LENGTH) + +/* Responses */ +#define WPC_DIGESTS_TYPE 0x01 +#define WPC_DIGESTS_HEADER WPC_HEADER(WPC_DIGESTS_TYPE) +#define WPC_DIGESTS_LENGTH(x) (2 + (ATCA_SHA256_DIGEST_SIZE * x)) + +#define WPC_CERTIFICATE_TYPE 0x02 +#define WPC_CERTIFICATE_HEADER WPC_HEADER(WPC_CERTIFICATE_TYPE) +#define WPC_CERTIFICATE_LENGTH(x) (1 + x) + +#define WPC_CHALLENGE_AUTH_TYPE 0x03 +#define WPC_CHALLENGE_AUTH_HEADER WPC_HEADER(WPC_CHALLENGE_AUTH_TYPE) +#define WPC_CHALLENGE_AUTH_LENGTH (67) + +#define WPC_ERROR_TYPE 0x07 +#define WPC_ERROR_HEADER WPC_HEADER(WPC_ERROR_TYPE) +#define WPC_ERROR_LENGTH (3) +#define WPC_ERROR_INVALID_REQUEST (0x01) +#define WPC_ERROR_UNSUPPORTED_PROTOCOL (0x02) +#define WPC_ERROR_BUSY (0x03) +#define WPC_ERROR_UNSPECIFIED (0x04) + +extern const uint8_t g_root_ca_digest[]; + +#if WPC_MSG_PR_EN +ATCA_STATUS wpc_msg_get_digests(uint8_t *const message, uint16_t *const msg_len, const uint8_t slot_mask); +ATCA_STATUS wpc_msg_get_certificate(uint8_t *const message, uint16_t *const msg_len, + const uint8_t slot, const uint16_t offset, const uint16_t length); +ATCA_STATUS wpc_msg_challenge(ATCADevice device, uint8_t *const message, uint16_t *const msg_len, const uint8_t slot); +#endif + +#if WPC_MSG_PT_EN +ATCA_STATUS wpc_msg_digests(ATCADevice device, uint8_t *const response, + uint16_t *const resp_len, const uint8_t *request); +ATCA_STATUS wpc_msg_certificate(ATCADevice device, uint8_t *const response, uint16_t *const resp_len, + const uint8_t *request, uint8_t *buffer, const uint16_t buf_len); +ATCA_STATUS wpc_msg_challenge_auth(ATCADevice device, uint8_t *const response, + uint16_t *const resp_len, const uint8_t *request); +ATCA_STATUS wpc_msg_error(uint8_t *const response, uint16_t *const resp_len, const uint8_t error_code, + const uint8_t error_data); +ATCA_STATUS wpc_auth_signature(ATCADevice device, const uint8_t *chain_digest, const uint16_t handle, + const uint8_t *request, const uint8_t *other_data, uint8_t *const signature); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/app/wpc/wpc_check_config.h b/app/wpc/wpc_check_config.h new file mode 100644 index 000000000..a149eb3f6 --- /dev/null +++ b/app/wpc/wpc_check_config.h @@ -0,0 +1,90 @@ +#ifndef WPC_CHECK_CONFIG_H +#define WPC_CHECK_CONFIG_H + +/* Pick up the global configuration and library checks */ +#include "cryptoauthlib.h" + +/* WPC "Slot" Configuration follows the WPC nomenclature where a slot is + defined as a certificate chain which also has a uniquely defined format + + Configuring a chain for cryptoauth parts: + WPC_CHAIN_DIGEST_HANDLE_ + WPC_CHAIN_CERT_DEF_ + WPC_CHAIN_ROOT_DIGEST_ + + Configuring a chain for trust anchor parts: + WPC_CHAIN_DIGEST_HANDLE_ + WPC_CHAIN_HANDLE_ + WPC_CHAIN_ROOT_DIGEST_ + +*/ + +/* Enable the Power Transmitter APIs */ +#ifndef WPC_MSG_PT_EN +#define WPC_MSG_PT_EN DEFAULT_ENABLED +#endif + +/* Enable the Power Reciever APIs */ +#ifndef WPC_MSG_PR_EN +#define WPC_MSG_PR_EN DEFAULT_ENABLED +#endif + +/** Use the option WPC_STRICT_SLOT_INDEX to configure simple mapping of slot to certificate */ +#ifndef WPC_STRICT_SLOT_INDEX_EN +#define WPC_STRICT_SLOT_INDEX_EN DEFAULT_DISABLED +#endif + +/* One of the certificate format options is to generate the certificate serial + number from a hash of several data elements - this saves storage in the device + at the expense of code space and time */ +#ifndef WPC_CERT_SN_FROM_HASH_EN +#define WPC_CERT_SN_FROM_HASH_EN DEFAULT_DISABLED +#endif + +/* These are defaults set up for the testing environment */ +#ifdef ATCA_TESTS_ENABLED +#if !(defined(WPC_CHAIN_DIGEST_HANDLE_0) || defined(WPC_CHAIN_CERT_DEF_0) || defined(WPC_CHAIN_ROOT_DIGEST_0)) +#define WPC_CHAIN_DIGEST_HANDLE_0 0x03 +#define WPC_CHAIN_CERT_DEF_0 g_cert_def_2_device +#define WPC_CHAIN_ROOT_DIGEST_0 g_root_ca_digest +#endif +#endif /* ATCA_TESTS_ENABLED */ + +#if ATCA_CA_SUPPORT && ATCA_TA_SUPPORT +#error "The WPC application reference is not designed to work with both cryptoauth and trust anchor support enabled" +#endif + +/* Check for extraneous configuration options set for cryptoauth parts */ +#if ATCA_CA_SUPPORT +#if (defined(WPC_CHAIN_HANDLE_0) || defined(WPC_CHAIN_HANDLE_1) || defined(WPC_CHAIN_HANDLE_2) || defined(WPC_CHAIN_HANDLE_3)) +#warning "The WPC_CHAIN_HANDLE_n configurations will be ignored for cryptoauth devices - use WPC_CHAIN_CERT_DEF_n instead" +#endif +#endif + +/* Check for extraneous configuration options set for trust anchor parts */ +#if ATCA_TA_SUPPORT +#if (defined(WPC_CHAIN_CERT_DEF_0) || defined(WPC_CHAIN_CERT_DEF_1) || defined(WPC_CHAIN_CERT_DEF_2) || defined(WPC_CHAIN_CERT_DEF_3)) +#warning "The WPC_CHAIN_CERT_DEF_n configurations will be ignored for trust anchor devices - use WPC_CHAIN_HANDLE_n instead" +#endif +#endif + +/* Chain 0 must always be defined per the WPC */ +#if !(defined(WPC_CHAIN_HANDLE_0) || defined(WPC_CHAIN_CERT_DEF_0)) +#error "WPC Requires that slot 0 always contains a valid chain" +#endif + +/* Check that the definitions are complete for a given chain */ +#if (defined(WPC_CHAIN_HANDLE_0) || defined(WPC_CHAIN_CERT_DEF_0)) != (defined(WPC_CHAIN_DIGEST_HANDLE_0) && defined(WPC_CHAIN_ROOT_DIGEST_0)) +#error "WPC Slot 0 definition is incomplete" +#endif +#if (defined(WPC_CHAIN_HANDLE_1) || defined(WPC_CHAIN_CERT_DEF_1)) != (defined(WPC_CHAIN_DIGEST_HANDLE_1) && defined(WPC_CHAIN_ROOT_DIGEST_1)) +#error "WPC Slot 1 definition is incomplete" +#endif +#if (defined(WPC_CHAIN_HANDLE_2) || defined(WPC_CHAIN_CERT_DEF_2)) != (defined(WPC_CHAIN_DIGEST_HANDLE_2) && defined(WPC_CHAIN_ROOT_DIGEST_2)) +#error "WPC Slot 2 definition is incomplete" +#endif +#if (defined(WPC_CHAIN_HANDLE_3) || defined(WPC_CHAIN_CERT_DEF_3)) != (defined(WPC_CHAIN_DIGEST_HANDLE_3) && defined(WPC_CHAIN_ROOT_DIGEST_3)) +#error "WPC Slot 3 definition is incomplete" +#endif + +#endif /* WPC_CHECK_CONFIG_H */ diff --git a/app/wpc/wpccert_client.c b/app/wpc/wpccert_client.c new file mode 100644 index 000000000..11c1ec154 --- /dev/null +++ b/app/wpc/wpccert_client.c @@ -0,0 +1,519 @@ +/** + * \file + * \brief Provides api interfaces for accessing WPC certificates from device. + * + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "wpc_check_config.h" +#include "wpccert_client.h" + +#include "atcacert/atcacert_def.h" +#include "atcacert/atcacert_der.h" +#include "atcacert/atcacert_client.h" +#include "atca_basic.h" + +#if WPC_MSG_PT_EN + +#ifdef WPC_CHAIN_CERT_DEF_0 +extern const atcacert_def_t WPC_CHAIN_CERT_DEF_0; +#endif + +#ifdef WPC_CHAIN_CERT_DEF_1 +extern const atcacert_def_t WPC_CHAIN_CERT_DEF_1; +#endif + +#ifdef WPC_CHAIN_CERT_DEF_2 +extern const atcacert_def_t WPC_CHAIN_CERT_DEF_2; +#endif + +#ifdef WPC_CHAIN_CERT_DEF_3 +extern const atcacert_def_t WPC_CHAIN_CERT_DEF_3; +#endif + +#ifdef WPC_CHAIN_ROOT_DIGEST_0 +extern const uint8_t WPC_CHAIN_ROOT_DIGEST_0[]; +#endif + +#ifdef WPC_CHAIN_ROOT_DIGEST_1 +extern const uint8_t WPC_CHAIN_ROOT_DIGEST_1[]; +#endif + +#ifdef WPC_CHAIN_ROOT_DIGEST_2 +extern const uint8_t WPC_CHAIN_ROOT_DIGEST_2[]; +#endif + +#ifdef WPC_CHAIN_ROOT_DIGEST_3 +extern const uint8_t WPC_CHAIN_ROOT_DIGEST_3[]; +#endif + +typedef struct wpc_slot_info_s +{ +#if !WPC_STRICT_SLOT_INDEX_EN + uint8_t id; +#endif + uint16_t handle; + const uint8_t* root; + const atcacert_def_t* def; +} wpc_slot_info_t; + +#if !WPC_STRICT_SLOT_INDEX_EN +#define WPC_INFO(n) {n, WPC_CHAIN_DIGEST_HANDLE_##n, WPC_CHAIN_ROOT_DIGEST_##n, &WPC_CHAIN_CERT_DEF_##n } +#else +#define WPC_INFO(n) {WPC_CHAIN_DIGEST_HANDLE_##n, WPC_CHAIN_ROOT_DIGEST_##n, &WPC_CHAIN_CERT_DEF_##n } +#endif + +static const wpc_slot_info_t wpc_slot_info[] = { +#ifdef WPC_CHAIN_DIGEST_HANDLE_0 + WPC_INFO(0), +#endif +#ifdef WPC_CHAIN_DIGEST_HANDLE_1 + WPC_INFO(1), +#endif +#ifdef WPC_CHAIN_DIGEST_HANDLE_2 + WPC_INFO(2), +#endif +#ifdef WPC_CHAIN_DIGEST_HANDLE_3 + WPC_INFO(3), +#endif +}; + +static const uint8_t wpc_slot_info_count = (uint8_t)(sizeof(wpc_slot_info) / sizeof(wpc_slot_info_t)); + +uint8_t wpccert_get_slot_count(void) +{ + return wpc_slot_info_count; +} + +uint8_t wpccert_get_slots_populated(void) +{ + uint8_t i, populated; + + for (i = 0, populated = 0; i < wpc_slot_info_count; i++) + { +#if WPC_STRICT_SLOT_INDEX_EN + populated |= (1 << wpc_slot_info[i].id); +#else + populated |= (1 << i); +#endif + } + return ATCA_SUCCESS; +} + +ATCA_STATUS wpccert_get_slot_info( + uint16_t * handle, /**< [out] Digest handle */ + const atcacert_def_t** def, /**< [out] Chain definition (device) */ + uint8_t slot /**< [in] Chain slot number */ +) +{ +#if WPC_STRICT_SLOT_INDEX_EN + ATCA_CHECK_INVALID_MSG(!(slot < wpc_slot_info_count), ATCA_BAD_PARAM, "Index out of range"); + if (handle) + { + *handle = wpc_slot_info[slot].handle; + } + if (def) + { + *def = wpc_slot_info[slot].def; + } + return ATCA_SUCCESS; +#else + uint8_t i; + for (i = 0; (i < wpc_slot_info_count); i++) + { + if (wpc_slot_info[i].id == slot) + { + if (handle) + { + *handle = wpc_slot_info[i].handle; + } + if (def) + { + *def = wpc_slot_info[i].def; + } + return ATCA_SUCCESS; + } + } + return ATCA_FUNC_FAIL; +#endif +} +#endif + +/** \brief WPC API - + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS wpccert_read_cert( + ATCADevice device, + const atcacert_def_t *cert_def, + uint8_t * cert, + size_t * cert_size) +{ + ATCA_STATUS status = ATCA_UNIMPLEMENTED; + uint8_t subj_public_key[72]; + uint8_t buffer[75], enc_dates[3]; + size_t buflen = sizeof(buffer); + size_t max_cert_size; + atcacert_device_loc_t comp_cert_loc = cert_def->comp_cert_dev_loc; + atcacert_device_loc_t cert_sn_loc = cert_def->cert_sn_dev_loc; + atcacert_tm_utc_t issue_date, expire_date; + uint8_t formatted_date[DATEFMT_MAX_SIZE]; + size_t formatted_date_size = ATCACERT_DATE_FORMAT_SIZES[cert_def->issue_date_format]; + + + ATCA_CHECK_INVALID_MSG((cert_def == NULL || cert_size == NULL), ATCA_BAD_PARAM, "NULL pointer received"); + + /* Read cert size */ + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, comp_cert_loc.zone, comp_cert_loc.slot, 0, &buffer[8], 64))) + { + status = ATCA_TRACE(status, "read_sig failed"); + return status; + } + + if (ATCA_SUCCESS != (status = atcacert_der_enc_ecdsa_sig_value(&buffer[8], buffer, &buflen))) + { + status = ATCA_TRACE(status, "ecdsa signature encode failed"); + return status; + } + + max_cert_size = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset + buflen; + *cert_size = max_cert_size; + + if (*cert_size > cert_def->cert_template_size) + { + *cert_size = cert_def->cert_template_size; + } + + memcpy(cert, cert_def->cert_template, *cert_size); + + // set comp_cert + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, comp_cert_loc.zone, comp_cert_loc.slot, + comp_cert_loc.offset, buffer, comp_cert_loc.count))) + { + status = ATCA_TRACE(status, "read comp cert failed"); + return status; + } + + // set signature + if (ATCA_SUCCESS != (status = atcacert_set_signature(cert_def, cert, cert_size, max_cert_size, buffer))) + { + status = ATCA_TRACE(status, "set signature failed"); + return status; + } + + memcpy(enc_dates, &buffer[64], 3); + if (ATCA_SUCCESS != (status = atcacert_date_dec_compcert(enc_dates, cert_def->expire_date_format, + &issue_date, &expire_date))) + { + status = ATCA_TRACE(status, "atcacert_date_dec_compcert failed"); + return status; + } + + // set issue date + if (ATCA_SUCCESS != (status = atcacert_date_enc(cert_def->issue_date_format, &issue_date, + formatted_date, &formatted_date_size))) + { + status = ATCA_TRACE(status, "date encoding failed"); + return status; + } + memcpy(&cert[cert_def->std_cert_elements[STDCERT_ISSUE_DATE].offset], formatted_date, formatted_date_size); + + // set cert_sn + if (cert_sn_loc.zone != DEVZONE_NONE) + { + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, cert_sn_loc.zone, cert_sn_loc.slot, + cert_sn_loc.offset, buffer, cert_sn_loc.count))) + { + status = ATCA_TRACE(status, "read cert sn failed"); + return status; + } + memcpy(&cert[cert_def->std_cert_elements[STDCERT_CERT_SN].offset], buffer, cert_sn_loc.count); + } + + // set subj_public_key + if (ATCA_SUCCESS != (status = wpccert_public_key(cert_def, subj_public_key, NULL))) + { + status = ATCA_TRACE(status, "subj public key read failed"); + return status; + } + + // set cert elements + for (uint8_t i = 0; i < cert_def->cert_elements_count; i++) + { + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, cert_def->cert_elements[i].device_loc.zone, + cert_def->cert_elements[i].device_loc.slot, + cert_def->cert_elements[i].device_loc.offset, + buffer, cert_def->cert_elements[i].device_loc.count))) + { + status = ATCA_TRACE(status, "read cert elements failed"); + return status; + } + + memcpy(&cert[cert_def->cert_elements[i].cert_loc.offset], buffer, cert_def->cert_elements[i].cert_loc.count); + } +#ifdef WPC_CERT_SN_FROM_HASH + if (cert_def->sn_source == SNSRC_PUB_KEY_HASH) + { + uint8_t cert_sn_msg[64 + 3], sn[32]; + + // Add public key to hash input + memcpy(&cert_sn_msg[0], &cert[cert_def->std_cert_elements[STDCERT_PUBLIC_KEY].offset], 64); + + // Add compressed/encoded dates to hash input + memcpy(formatted_date, &cert[cert_def->std_cert_elements[STDCERT_ISSUE_DATE].offset], formatted_date_size); + + if (ATCA_SUCCESS != (status = atcacert_date_dec(cert_def->issue_date_format, formatted_date, formatted_date_size, &issue_date))) + { + status = ATCA_TRACE(status, "cert date decoding failed"); + return status; + } + + // Issue and expire dates are compressed/encoded + memset(&cert_sn_msg[64], 0, 3); + + cert_sn_msg[64] = (cert_sn_msg[64] & 0x07) | (uint8_t)(((issue_date.tm_year + 1900 - 2000) & 0x1F) << 3); + cert_sn_msg[64] = (uint8_t)((cert_sn_msg[64] & 0xF8) | (((issue_date.tm_mon + 1) & 0x0F) >> 1)); + cert_sn_msg[65] = (uint8_t)((cert_sn_msg[65] & 0x7F) | (((issue_date.tm_mon + 1) & 0x0F) << 7)); + cert_sn_msg[65] = (uint8_t)((cert_sn_msg[65] & 0x83) | ((issue_date.tm_mday & 0x1F) << 2)); + cert_sn_msg[65] = (uint8_t)((cert_sn_msg[65] & 0xFC) | ((issue_date.tm_hour & 0x1F) >> 3)); + cert_sn_msg[66] = (uint8_t)((cert_sn_msg[66] & 0x1F) | ((issue_date.tm_hour & 0x1F) << 5)); + cert_sn_msg[66] = (uint8_t)((cert_sn_msg[66] & 0xE0) | (cert_def->expire_years & 0x1F)); + + if (ATCA_SUCCESS != (status = atcab_hw_sha2_256(cert_sn_msg, 64 + 3, sn))) + { + status = ATCA_TRACE(status, "sha failed"); + return status; + } + + sn[0] &= 0x7F; // Ensure the SN is positive + sn[0] |= 0x40; // Ensure the SN doesn't have any trimmable bytes + + memcpy(&cert[cert_def->std_cert_elements[STDCERT_CERT_SN].offset], sn, cert_def->std_cert_elements[STDCERT_CERT_SN].count); + } +#endif + + return status; +} + +#if ATCAB_WRITE_EN +ATCA_STATUS wpccert_write_cert(ATCADevice device, const atcacert_def_t* cert_def, const uint8_t* cert, size_t cert_size) +{ + ATCA_STATUS status; + atcacert_device_loc_t comp_cert_loc = cert_def->comp_cert_dev_loc; + atcacert_device_loc_t public_key_loc = cert_def->public_key_dev_loc; + atcacert_device_loc_t cert_sn_loc = cert_def->cert_sn_dev_loc; + uint8_t temp_buf[256]; // Must be at least 72 bytes + uint8_t formatted_date[DATEFMT_MAX_SIZE]; + size_t der_sig_size = 0; + size_t formatted_date_size = ATCACERT_DATE_FORMAT_SIZES[cert_def->issue_date_format]; + size_t sig_offset = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset; + atcacert_tm_utc_t issue_date; + + if (cert_def == NULL || cert == NULL) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + return status; + } + + // get comp cert + der_sig_size = cert_size - sig_offset; + + if (ATCA_SUCCESS != (status = atcacert_der_dec_ecdsa_sig_value(&cert[sig_offset], &der_sig_size, &temp_buf[0]))) + { + status = ATCA_TRACE(status, "atcacert_der_dec_ecdsa_sig_value failed"); + return status; + } + memcpy(formatted_date, &cert[cert_def->std_cert_elements[STDCERT_ISSUE_DATE].offset], formatted_date_size); + + if (ATCA_SUCCESS != (status = atcacert_date_dec(cert_def->issue_date_format, formatted_date, formatted_date_size, &issue_date))) + { + status = ATCA_TRACE(status, "date decoding failed"); + return status; + } + + memset(&temp_buf[64], 0, 3); + + temp_buf[64] = (temp_buf[64] & 0x07) | (uint8_t)(((issue_date.tm_year + 1900 - 2000) & 0x1F) << 3); + temp_buf[64] = (uint8_t)((temp_buf[64] & 0xF8) | (((issue_date.tm_mon + 1) & 0x0F) >> 1)); + temp_buf[65] = (uint8_t)((temp_buf[65] & 0x7F) | (((issue_date.tm_mon + 1) & 0x0F) << 7)); + temp_buf[65] = (uint8_t)((temp_buf[65] & 0x83) | ((issue_date.tm_mday & 0x1F) << 2)); + temp_buf[65] = (uint8_t)((temp_buf[65] & 0xFC) | ((issue_date.tm_hour & 0x1F) >> 3)); + temp_buf[66] = (uint8_t)((temp_buf[66] & 0x1F) | ((issue_date.tm_hour & 0x1F) << 5)); + temp_buf[66] = (uint8_t)((temp_buf[66] & 0xE0) | (cert_def->expire_years & 0x1F)); + + memset(&temp_buf[67], 0, sizeof(uint16_t)); // no signer_id in cert use 0 + + temp_buf[69] = (uint8_t)(((cert_def->template_id & 0x0F) << 4) | (cert_def->chain_id & 0x0F)); + temp_buf[70] = (uint8_t)(((cert_def->sn_source & 0x0F) << 4) | 0); + temp_buf[71] = 0; + + if (ATCA_SUCCESS != (status = atcab_write_bytes_zone_ext(device, + comp_cert_loc.zone, + comp_cert_loc.slot, + comp_cert_loc.offset, + temp_buf, comp_cert_loc.count))) + { + status = ATCA_TRACE(status, "compcert write failed"); + return status; + } + + // get certificate serial number + if (cert_sn_loc.count != 0) + { + memcpy(temp_buf, &cert[cert_def->std_cert_elements[STDCERT_CERT_SN].offset], cert_sn_loc.count); + if (ATCA_SUCCESS != (status = atcab_write_bytes_zone_ext(device, + cert_sn_loc.zone, + cert_sn_loc.slot, + cert_sn_loc.offset, + temp_buf, cert_sn_loc.count))) + { + status = ATCA_TRACE(status, "write cert serial number failed"); + return status; + } + } + + if (public_key_loc.is_genkey == 0) + { + //get subj public key + memcpy(temp_buf, &cert[cert_def->std_cert_elements[STDCERT_PUBLIC_KEY].offset], 64); + + if (public_key_loc.count == 72) + { + // Public key is formatted with padding bytes in front of the X and Y components + memmove(&temp_buf[40], &temp_buf[32], 32); // Move Y to padded position + memset(&temp_buf[36], 0, sizeof(uint32_t)); // Add Y padding bytes + memmove(&temp_buf[4], &temp_buf[0], 32); // Move X to padded position + memset(&temp_buf[0], 0, sizeof(uint32_t)); // Add X padding bytes + } + else if (public_key_loc.count != 64) + { + status = ATCA_TRACE(status, "public key count not valid"); + return status; // Unexpected public key size + } + + if (ATCA_SUCCESS != (status = atcab_write_bytes_zone_ext(device, + public_key_loc.zone, + public_key_loc.slot, + public_key_loc.offset, + temp_buf, public_key_loc.count))) + { + status = ATCA_TRACE(status, "write subj public key failed"); + return status; + } + } + + //get cert elements + for (uint8_t i = 0; i < cert_def->cert_elements_count; i++) + { + memcpy(temp_buf, &cert[cert_def->cert_elements[i].cert_loc.offset], cert_def->cert_elements[i].cert_loc.count); + comp_cert_loc = cert_def->cert_elements[i].device_loc; + if (ATCA_SUCCESS != (status = atcab_write_bytes_zone_ext(device, + comp_cert_loc.zone, + comp_cert_loc.slot, + comp_cert_loc.offset, + temp_buf, comp_cert_loc.count))) + { + status = ATCA_TRACE(status, "write cert elements failed"); + return status; + } + } + + return status; +} +#endif + +ATCA_STATUS wpccert_read_pdu_cert(ATCADevice device, uint8_t* cert, size_t* cert_size, uint8_t slot) +{ + ATCA_STATUS status; + const atcacert_def_t* chain; + if (ATCA_SUCCESS == (status = wpccert_get_slot_info(NULL, &chain, slot))) + { + status = wpccert_read_cert(device, chain, cert, cert_size); + } + return status; +} + +ATCA_STATUS wpccert_read_mfg_cert(ATCADevice device, uint8_t* cert, size_t* cert_size, uint8_t slot) +{ + ATCA_STATUS status; + const atcacert_def_t* chain; + if (ATCA_SUCCESS == (status = wpccert_get_slot_info(NULL, &chain, slot))) + { + status = wpccert_read_cert(device, chain->ca_cert_def, cert, cert_size); + } + return status; +} + +ATCA_STATUS wpccert_public_key(const atcacert_def_t* cert_def, uint8_t* public_key, uint8_t* cert) +{ + ATCA_STATUS status; + + if (public_key == NULL || cert_def == NULL) + { + return ATCACERT_E_BAD_PARAMS; + } + + if (cert == NULL) + { + atcacert_device_loc_t public_key_loc = cert_def->public_key_dev_loc; + uint8_t raw_public_key[72]; + + if (public_key_loc.is_genkey) + { + uint8_t pub_key[ATCA_PUB_KEY_SIZE]; + + if (ATCA_SUCCESS != (status = atcab_get_pubkey(public_key_loc.slot, pub_key))) + { + status = ATCA_TRACE(status, "subj public key read failed"); + return status; + } + memcpy(raw_public_key, &pub_key[public_key_loc.offset], public_key_loc.count); + } + else + { + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone(public_key_loc.zone, public_key_loc.slot, public_key_loc.offset, + raw_public_key, public_key_loc.count))) + { + status = ATCA_TRACE(status, "subj public key read failed"); + return status; + } + } + + if (public_key_loc.count == 72) + { + // Public key is formatted with padding bytes in front of the X and Y components + memmove(&public_key[0], &raw_public_key[4], 32); // Move X + memmove(&public_key[32], &raw_public_key[40], 32); // Move Y + } + else + { + memcpy(public_key, raw_public_key, 64); + } + } + else + { + memcpy(public_key, &cert[cert_def->std_cert_elements[STDCERT_PUBLIC_KEY].offset], 64); + } + + return ATCA_SUCCESS; +} diff --git a/test/api_crypto/test_crypto_pbkdf2.h b/app/wpc/wpccert_client.h similarity index 52% rename from test/api_crypto/test_crypto_pbkdf2.h rename to app/wpc/wpccert_client.h index f544257b7..65f0c1ff1 100644 --- a/test/api_crypto/test_crypto_pbkdf2.h +++ b/app/wpc/wpccert_client.h @@ -1,8 +1,8 @@ /** * \file - * \brief Unity tests for the CryptoAuthLib software crypto API. + * \brief Provides api interfaces for accessing WPC certificates from device. * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. * * \page License * @@ -25,35 +25,34 @@ * THIS SOFTWARE. */ -#ifndef ATCA_CRYPTO_TESTS_H_ -#define ATCA_CRYPTO_TESTS_H_ +#ifndef WPCCERT_CLIENT_H +#define WPCCERT_CLIENT_H -#include "third_party/unity/unity.h" +#ifdef __cplusplus +extern "C" +{ +#endif + +#include "cryptoauthlib.h" +#include "atcacert/atcacert_def.h" + +uint8_t wpccert_get_slots_populated(void); +uint8_t wpccert_get_slot_count(void); -int atca_crypto_sw_tests(int argc, char* argv[]); +ATCA_STATUS wpccert_get_slot_info(uint16_t * dig_handle, const atcacert_def_t** def, uint8_t slot); -void test_atcac_sw_sha1_nist1(void); -void test_atcac_sw_sha1_nist2(void); -void test_atcac_sw_sha1_nist3(void); -void test_atcac_sw_sha1_nist_short(void); -void test_atcac_sw_sha1_nist_long(void); -void test_atcac_sw_sha1_nist_monte(void); -void test_atcac_sw_sha2_256_nist1(void); -void test_atcac_sw_sha2_256_nist2(void); -void test_atcac_sw_sha2_256_nist3(void); -void test_atcac_sw_sha2_256_nist_short(void); -void test_atcac_sw_sha2_256_nist_long(void); -void test_atcac_sw_sha2_256_nist_monte(void); +ATCA_STATUS wpccert_read_cert(ATCADevice device, const atcacert_def_t *cert_def, uint8_t *cert, size_t *cert_size); -void test_atcac_aes128_gcm(void); -void test_atcac_aes128_cmac(void); -void test_atcac_sha256_hmac(void); -void test_atcac_sha256_hmac_nist(void); +ATCA_STATUS wpccert_write_cert(ATCADevice device, const atcacert_def_t* cert_def, const uint8_t* cert, size_t cert_size); -void test_atcac_verify_nist(void); -void test_atcac_public(void); -void test_atcac_sign(void); -void test_atcac_derive_nist(void); +ATCA_STATUS wpccert_read_pdu_cert(ATCADevice device, uint8_t* cert, size_t* cert_size, uint8_t slot); +ATCA_STATUS wpccert_read_mfg_cert(ATCADevice device, uint8_t* cert, size_t* cert_size, uint8_t slot); + +ATCA_STATUS wpccert_public_key(const atcacert_def_t* cert_def, uint8_t* public_key, uint8_t* cert); + +#ifdef __cplusplus +} +#endif #endif diff --git a/app/wpc/zcust_def_1_signer.c b/app/wpc/zcust_def_1_signer.c new file mode 100644 index 000000000..1bdd577c3 --- /dev/null +++ b/app/wpc/zcust_def_1_signer.c @@ -0,0 +1,169 @@ +#include "atcacert/atcacert_def.h" + +const uint8_t g_root_ca_digest[32] = { + 0x41, 0x78, 0x1d, 0x15, 0xa1, 0x52, 0x23, 0x44, 0xf3, 0x85, 0x39, 0x06, 0x5c, 0x6d, 0xea, 0x24, + 0xee, 0xfe, 0xdd, 0x39, 0xc3, 0xb7, 0x67, 0x0a, 0x00, 0x0a, 0x70, 0xb6, 0x70, 0xc7, 0xf7, 0xbd, +}; + +const uint8_t g_template_1_signer[327] = { + 0x30, 0x82, 0x01, 0x43, 0x30, 0x81, 0xeb, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x6b, 0x04, + 0xbe, 0x1b, 0x02, 0x97, 0xe9, 0x56, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x03, 0x02, 0x30, 0x11, 0x31, 0x0f, 0x30, 0x0d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x06, 0x57, + 0x50, 0x43, 0x43, 0x41, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x32, 0x32, 0x34, 0x30, + 0x36, 0x31, 0x38, 0x31, 0x35, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, + 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x07, 0x30, 0x30, 0x34, 0x45, 0x2d, 0x31, 0x41, 0x30, 0x59, 0x30, 0x13, 0x06, + 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, + 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x62, 0x84, 0xd0, 0x99, 0x2d, 0x48, 0x27, 0x89, 0xff, 0xab, + 0x7f, 0x58, 0x11, 0x46, 0x66, 0x71, 0x7c, 0x0c, 0x77, 0x0c, 0x7d, 0xf0, 0x28, 0x6f, 0x16, 0xc8, + 0x55, 0xff, 0xdd, 0xd3, 0x46, 0xae, 0x9d, 0x34, 0xc6, 0x3a, 0xc0, 0x8f, 0x6b, 0x19, 0x30, 0x0c, + 0xca, 0xd0, 0xe0, 0xcc, 0x0a, 0x38, 0x78, 0x6e, 0xb0, 0x31, 0x6c, 0xfe, 0x52, 0x2c, 0x63, 0x76, + 0x17, 0xdc, 0xd8, 0xf1, 0xa0, 0x9b, 0xa3, 0x2a, 0x30, 0x28, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, 0x00, 0x30, 0x12, + 0x06, 0x05, 0x67, 0x81, 0x14, 0x01, 0x01, 0x01, 0x01, 0xff, 0x04, 0x06, 0x04, 0x04, 0x00, 0x00, + 0x00, 0x01, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, + 0x00, 0x30, 0x44, 0x02, 0x20, 0x3f, 0x59, 0x32, 0x78, 0xb5, 0x21, 0x36, 0xef, 0x11, 0xae, 0xeb, + 0xeb, 0x64, 0x70, 0x88, 0x77, 0x0c, 0x7f, 0xe2, 0xa2, 0x52, 0xe2, 0xcc, 0x1f, 0x32, 0xad, 0xd2, + 0x0b, 0x5b, 0xfa, 0x1a, 0x0a, 0x02, 0x20, 0x37, 0x85, 0xb9, 0x66, 0x23, 0x24, 0x89, 0x47, 0x11, + 0x68, 0xa6, 0x79, 0xac, 0xe1, 0x67, 0x74, 0xec, 0x6d, 0x40, 0x0e, 0x18, 0x95, 0x54, 0xbb, 0x2e, + 0x41, 0xec, 0x9a, 0x97, 0xb6, 0x28, 0xdc, +}; + +const uint8_t g_cert_ca_public_key_1_signer[64] = { + 0x51, 0x1d, 0xe1, 0xff, 0x26, 0x4d, 0x5b, 0x19, 0x02, 0xdc, 0x03, 0xdd, 0x74, 0x6e, 0xfc, 0xd5, + 0x20, 0x59, 0x35, 0x95, 0xa4, 0xe9, 0x2a, 0xe2, 0x7f, 0x80, 0xdc, 0x42, 0x87, 0x00, 0xba, 0x9a, + 0x67, 0xdc, 0xe1, 0xdd, 0x03, 0x08, 0x50, 0xb7, 0x02, 0x3c, 0x96, 0xf5, 0x6e, 0xf3, 0x67, 0x61, + 0xa1, 0xe1, 0xee, 0x44, 0x95, 0x23, 0x2b, 0xf4, 0xe9, 0x9a, 0xe5, 0x94, 0xed, 0xe5, 0xa2, 0x99, +}; + +const atcacert_cert_element_t g_cert_elements_1_signer[3] = { + { + .id = "IssueDate", + .device_loc ={ + .zone = DEVZONE_DATA, + .slot = 4, + .is_genkey = 0, + .offset = 12, + .count = 13 + }, + .cert_loc ={ + .offset = 57, + .count = 13 + }, + .transforms ={ + TF_NONE, + TF_NONE + } + }, + { + .id = "subject", + .device_loc ={ + .zone = DEVZONE_DATA, + .slot = 4, + .is_genkey = 0, + .offset = 25, + .count = 7 + }, + .cert_loc ={ + .offset = 100, + .count = 7 + }, + .transforms ={ + TF_NONE, + TF_NONE + } + }, + { + .id = "qiPolicy", + .device_loc ={ + .zone = DEVZONE_DATA, + .slot = 4, + .is_genkey = 0, + .offset = 32, + .count = 4 + }, + .cert_loc ={ + .offset = 238, + .count = 4 + }, + .transforms ={ + TF_NONE, + TF_NONE + } + } +}; + +const atcacert_def_t g_cert_def_1_signer = { + .type = CERTTYPE_X509, + .template_id = 1, + .chain_id = 3, + .private_key_slot = 0, + .sn_source = SNSRC_STORED_DYNAMIC, + .cert_sn_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 4, + .is_genkey = 0, + .offset = 0, + .count = 9 + }, + .issue_date_format = DATEFMT_RFC5280_UTC, + .expire_date_format = DATEFMT_RFC5280_GEN, + .tbs_cert_loc = { + .offset = 4, + .count = 238 + }, + .expire_years = 0, + .public_key_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 9, + .is_genkey = 0, + .offset = 0, + .count = 72 + }, + .comp_cert_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 14, + .is_genkey = 0, + .offset = 0, + .count = 72 + }, + .std_cert_elements = { + { // STDCERT_PUBLIC_KEY + .offset = 134, + .count = 64 + }, + { // STDCERT_SIGNATURE + .offset = 254, + .count = 64 + }, + { // STDCERT_ISSUE_DATE + .offset = 57, + .count = 13 + }, + { // STDCERT_EXPIRE_DATE + .offset = 0, + .count = 0 + }, + { // STDCERT_SIGNER_ID + .offset = 0, + .count = 0 + }, + { // STDCERT_CERT_SN + .offset = 13, + .count = 9 + }, + { // STDCERT_AUTH_KEY_ID + .offset = 0, + .count = 0 + }, + { // STDCERT_SUBJ_KEY_ID + .offset = 0, + .count = 0 + }, + }, + .cert_elements = g_cert_elements_1_signer, + .cert_elements_count = sizeof(g_cert_elements_1_signer) / sizeof(g_cert_elements_1_signer[0]), + .cert_template = g_template_1_signer, + .cert_template_size = sizeof(g_template_1_signer), + .ca_cert_def = NULL +}; diff --git a/app/wpc/zcust_def_1_signer.h b/app/wpc/zcust_def_1_signer.h new file mode 100644 index 000000000..931d56658 --- /dev/null +++ b/app/wpc/zcust_def_1_signer.h @@ -0,0 +1,19 @@ +#ifndef ZCUST_DEF_1_SIGNER_H +#define ZCUST_DEF_1_SIGNER_H + +#include "atcacert/atcacert_def.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +extern const atcacert_def_t g_cert_def_1_signer; +extern const uint8_t g_cert_ca_public_key_1_signer[]; +extern const uint8_t g_root_ca_digest[]; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/app/wpc/zcust_def_2_device.c b/app/wpc/zcust_def_2_device.c new file mode 100644 index 000000000..34588f1db --- /dev/null +++ b/app/wpc/zcust_def_2_device.c @@ -0,0 +1,139 @@ +#include "atcacert/atcacert_def.h" +#include "zcust_def_1_signer.h" + +const uint8_t g_template_2_device[316] = { + 0x30, 0x82, 0x01, 0x38, 0x30, 0x81, 0xde, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x55, 0x3a, + 0x49, 0x4e, 0x6c, 0x8c, 0x47, 0xc6, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, + 0x03, 0x02, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x30, + 0x30, 0x34, 0x45, 0x2d, 0x31, 0x41, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x32, 0x34, 0x30, 0x36, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, + 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x11, 0x31, 0x0f, 0x30, 0x0d, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x06, 0x30, 0x31, 0x31, 0x34, 0x33, 0x30, 0x30, 0x59, 0x30, + 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x63, 0x91, 0xf3, 0x5a, 0x89, 0x09, 0x8c, 0x21, + 0x0b, 0x4a, 0x5f, 0xee, 0xa8, 0x0f, 0x78, 0xff, 0xd4, 0x4c, 0x24, 0x14, 0x08, 0x86, 0xe4, 0x91, + 0xa6, 0xcd, 0xe9, 0xf0, 0x11, 0x55, 0xab, 0x11, 0x76, 0xaf, 0xa5, 0xba, 0x0f, 0x99, 0x88, 0xd7, + 0x4b, 0x81, 0x2d, 0x6f, 0x03, 0xce, 0xb6, 0x40, 0xba, 0x51, 0x68, 0xff, 0xdc, 0x05, 0x8b, 0xd2, + 0x60, 0x67, 0x00, 0xce, 0xb0, 0x03, 0xaa, 0x69, 0xa3, 0x1b, 0x30, 0x19, 0x30, 0x17, 0x06, 0x05, + 0x67, 0x81, 0x14, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x0b, 0x04, 0x09, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x30, 0x30, 0x30, 0x30, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, + 0x02, 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xb7, 0xa3, 0xab, 0x33, 0x5d, 0x4d, 0x70, + 0xd4, 0x79, 0x5d, 0x03, 0x48, 0x73, 0xda, 0x5d, 0x7f, 0x45, 0x35, 0x19, 0x18, 0xf1, 0xd6, 0x1f, + 0x6d, 0xae, 0xd8, 0xc4, 0x36, 0x63, 0x38, 0xd7, 0xef, 0x02, 0x21, 0x00, 0x9d, 0x10, 0xf3, 0xf8, + 0x99, 0x67, 0xc8, 0x3d, 0xd2, 0x7e, 0x99, 0xc7, 0x60, 0x0f, 0xa9, 0xbe, 0x84, 0xcf, 0x9a, 0x15, + 0xa4, 0xdc, 0x5d, 0xc6, 0x2c, 0x1c, 0x5e, 0x6b, 0xbb, 0xd8, 0x14, 0x70, +}; + +const atcacert_cert_element_t g_cert_elements_2_device[2] = { + { + .id = "issuer", + .device_loc ={ + .zone = DEVZONE_DATA, + .slot = 5, + .is_genkey = 0, + .offset = 25, + .count = 7 + }, + .cert_loc ={ + .offset = 47, + .count = 7 + }, + .transforms ={ + TF_NONE, + TF_NONE + } + }, + { + .id = "RSID", + .device_loc ={ + .zone = DEVZONE_DATA, + .slot = 5, + .is_genkey = 0, + .offset = 1, + .count = 9 + }, + .cert_loc ={ + .offset = 220, + .count = 9 + }, + .transforms ={ + TF_NONE, + TF_NONE + } + } +}; + +const atcacert_def_t g_cert_def_2_device = { + .type = CERTTYPE_X509, + .template_id = 2, + .chain_id = 3, + .private_key_slot = 0, + .sn_source = SNSRC_PUB_KEY_HASH, + .cert_sn_dev_loc = { + .zone = DEVZONE_NONE, + .slot = 0, + .is_genkey = 0, + .offset = 0, + .count = 0 + }, + .issue_date_format = DATEFMT_RFC5280_GEN, + .expire_date_format = DATEFMT_RFC5280_GEN, + .tbs_cert_loc = { + .offset = 4, + .count = 225 + }, + .expire_years = 0, + .public_key_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 0, + .is_genkey = 1, + .offset = 0, + .count = 64 + }, + .comp_cert_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 13, + .is_genkey = 0, + .offset = 0, + .count = 72 + }, + .std_cert_elements = { + { // STDCERT_PUBLIC_KEY + .offset = 136, + .count = 64 + }, + { // STDCERT_SIGNATURE + .offset = 241, + .count = 64 + }, + { // STDCERT_ISSUE_DATE + .offset = 58, + .count = 15 + }, + { // STDCERT_EXPIRE_DATE + .offset = 0, + .count = 0 + }, + { // STDCERT_SIGNER_ID + .offset = 0, + .count = 0 + }, + { // STDCERT_CERT_SN + .offset = 14, + .count = 8 + }, + { // STDCERT_AUTH_KEY_ID + .offset = 0, + .count = 0 + }, + { // STDCERT_SUBJ_KEY_ID + .offset = 0, + .count = 0 + }, + }, + .cert_elements = g_cert_elements_2_device, + .cert_elements_count = sizeof(g_cert_elements_2_device) / sizeof(g_cert_elements_2_device[0]), + .cert_template = g_template_2_device, + .cert_template_size = sizeof(g_template_2_device), + .ca_cert_def = &g_cert_def_1_signer +}; diff --git a/app/wpc/zcust_def_2_device.h b/app/wpc/zcust_def_2_device.h new file mode 100644 index 000000000..419dc7fb3 --- /dev/null +++ b/app/wpc/zcust_def_2_device.h @@ -0,0 +1,14 @@ +#ifndef ZCUST_DEF_2_DEVICE_H +#define ZCUST_DEF_2_DEVICE_H + +#include "atcacert/atcacert_def.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern const atcacert_def_t g_cert_def_2_device; +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cmake/check_environment.cmake b/cmake/check_environment.cmake new file mode 100644 index 000000000..f0215cc06 --- /dev/null +++ b/cmake/check_environment.cmake @@ -0,0 +1,51 @@ + + +# RTOS Selection +if (TARGET zephyr_interface) +SET(ATCA_ZEPHYR_SUPPORT ON CACHE INTERNAL "Build is part of a zephyr project") +endif() + +if (UNIX AND NOT ATCA_ZEPHYR_SUPPORT) +include(GNUInstallDirs) +include(CheckSymbolExists) + +# Check for gnu extensions +if (NOT DEFINED _GNU_SOURCE) + check_symbol_exists(__GNU_LIBRARY__ "features.h" _GNU_SOURCE) +endif() + +if(_GNU_SOURCE) + set(CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE) + add_definitions(-D_GNU_SOURCE) +endif() + +# Check and configure packaging options +set(DEFAULT_LIB_PATH "${CMAKE_INSTALL_FULL_LIBDIR}" CACHE + STRING "The default absolute library path") +set(DEFAULT_INC_PATH "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}" CACHE + STRING "The default include install path") +set(DEFAULT_CONF_PATH "${CMAKE_INSTALL_FULL_SYSCONFDIR}/${PROJECT_NAME}" CACHE + STRING "The default location of ${PROJECT_NAME}.conf") +set(DEFAULT_STORE_PATH "${CMAKE_INSTALL_FULL_LOCALSTATEDIR}/lib/${PROJECT_NAME}" CACHE + STRING "The default location of the filestore directory") +set(DEFAULT_CONF_FILE_NAME "${PROJECT_NAME}.conf" CACHE + STRING "The default file for library configuration") + +if(NOT CMAKE_BUILD_TYPE) +set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Default build type" FORCE) +endif() + +# Packaging +set(CPACK_PACKAGE_VENDOR "Microchip Technology Inc") +set(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH}) +set(CPACK_GENERATOR "TGZ") +set(CPACK_SOURCE_GENERATOR "TGZ") +set(CPACK_SOURCE_IGNORE_FILES "build/*;\\.git/*") + +include(CPack) + +endif() + + diff --git a/cmake/config_install.cmake b/cmake/config_install.cmake new file mode 100644 index 000000000..d13931f4c --- /dev/null +++ b/cmake/config_install.cmake @@ -0,0 +1,27 @@ + +# Installation +if(ATCA_PKCS11) + +# Set up a default configuration file to install +configure_file(${PROJECT_SOURCE_DIR}/app/pkcs11/cryptoauthlib.conf.in ${PROJECT_BINARY_DIR}/${DEFAULT_CONF_FILE_NAME}) + +install(DIRECTORY DESTINATION ${DEFAULT_CONF_PATH}) +install(CODE " + if(NOT EXISTS ${DEFAULT_CONF_PATH}/${DEFAULT_CONF_FILE_NAME}) + file(INSTALL ${PROJECT_BINARY_DIR}/${DEFAULT_CONF_FILE_NAME} + DESTINATION ${DEFAULT_CONF_PATH}) + endif() + ") +install(DIRECTORY DESTINATION ${DEFAULT_STORE_PATH} + DIRECTORY_PERMISSIONS + OWNER_EXECUTE OWNER_WRITE OWNER_READ + GROUP_EXECUTE GROUP_WRITE GROUP_READ + WORLD_EXECUTE WORLD_WRITE WORLD_READ + ) +install(CODE " + if(NOT EXISTS ${DEFAULT_STORE_PATH}/slot.conf.tmpl) + file(INSTALL ${PROJECT_SOURCE_DIR}/app/pkcs11/slot.conf.tmpl + DESTINATION ${DEFAULT_STORE_PATH}) + endif() + ") +endif() diff --git a/cryptoauthlib-manual.pdf b/cryptoauthlib-manual.pdf index 96c4a8a3a..f44c81390 100644 Binary files a/cryptoauthlib-manual.pdf and b/cryptoauthlib-manual.pdf differ diff --git a/harmony/config/cryptoauthlib.py b/harmony/config/cryptoauthlib.py index ef683ab31..3b29ef623 100644 --- a/harmony/config/cryptoauthlib.py +++ b/harmony/config/cryptoauthlib.py @@ -359,6 +359,434 @@ def instantiateComponent(calComponent): calPollingTimeout.setLabel('Polling Timeout (ms)') calPollingTimeout.setDefaultValue(2500) + # Symmetric Cryptography Commands + symmetricCommands = calComponent.createMenuSymbol("cal_symmetric_commands", None) + symmetricCommands.setLabel("Symmetric Cryptography Commands") + symmetricCommands.setVisible(True) + + # AES + calAesEnabledSymbol = calComponent.createBooleanSymbol("cal_aes", symmetricCommands) + calAesEnabledSymbol.setLabel("Support AES?") + calAesEnabledSymbol.setDescription("Enable support for AES Command") + calAesEnabledSymbol.setVisible(True) + calAesEnabledSymbol.setDefaultValue(True) + + calAesEcbEnabledSymbol = calComponent.createBooleanSymbol("cal_aes_ecb", calAesEnabledSymbol) + calAesEcbEnabledSymbol.setLabel("Support ECB Mode?") + calAesEcbEnabledSymbol.setDescription("Enable support for AES ECB Mode") + calAesEcbEnabledSymbol.setVisible(True) + calAesEcbEnabledSymbol.setDefaultValue(True) + calAesEcbEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_aes"]) + + calAesGfmEnabledSymbol = calComponent.createBooleanSymbol("cal_aes_gfm", calAesEnabledSymbol) + calAesGfmEnabledSymbol.setLabel("Support GFM Mode?") + calAesGfmEnabledSymbol.setDescription("Enable support for AES GFM Mode") + calAesGfmEnabledSymbol.setVisible(True) + calAesGfmEnabledSymbol.setDefaultValue(True) + calAesGfmEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_aes"]) + + calAesGcmEnabledSymbol = calComponent.createBooleanSymbol("cal_aes_gcm", calAesEnabledSymbol) + calAesGcmEnabledSymbol.setLabel("Support GCM Mode?") + calAesGcmEnabledSymbol.setDescription("Enable support for AES GCM Mode") + calAesGcmEnabledSymbol.setVisible(True) + calAesGcmEnabledSymbol.setDefaultValue(True) + calAesGcmEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_aes"]) + + # CHECKMAC + calCheckmacEnabledSymbol = calComponent.createBooleanSymbol("cal_checkmac", symmetricCommands) + calCheckmacEnabledSymbol.setLabel("Support Checkmac?") + calCheckmacEnabledSymbol.setDescription("Enable support for CHECKMAC Command") + calCheckmacEnabledSymbol.setVisible(True) + calCheckmacEnabledSymbol.setDefaultValue(True) + + # GENDIG + calGendigEnabledSymbol = calComponent.createBooleanSymbol("cal_gendig", symmetricCommands) + calGendigEnabledSymbol.setLabel("Support Gendig?") + calGendigEnabledSymbol.setDescription("Enable support for GENDIG Command") + calGendigEnabledSymbol.setVisible(True) + calGendigEnabledSymbol.setDefaultValue(True) + + # KDF + calKdfEnabledSymbol = calComponent.createBooleanSymbol("cal_kdf", symmetricCommands) + calKdfEnabledSymbol.setLabel("Support KDF?") + calKdfEnabledSymbol.setDescription("Enable support for KDF Command") + calKdfEnabledSymbol.setVisible(True) + calKdfEnabledSymbol.setDefaultValue(True) + + # MAC + calMacEnabledSymbol = calComponent.createBooleanSymbol("cal_mac", symmetricCommands) + calMacEnabledSymbol.setLabel("Support MAC?") + calMacEnabledSymbol.setDescription("Enable support for MAC Command") + calMacEnabledSymbol.setVisible(True) + calMacEnabledSymbol.setDefaultValue(True) + + # HMAC + calHmacEnabledSymbol = calComponent.createBooleanSymbol("cal_hmac", symmetricCommands) + calHmacEnabledSymbol.setLabel("Support HMAC?") + calHmacEnabledSymbol.setDescription("Enable support for Hmac Command") + calHmacEnabledSymbol.setVisible(True) + calHmacEnabledSymbol.setDefaultValue(True) + + # Asymmetric Cryptography Commands + asymmetricCommands = calComponent.createMenuSymbol("cal_asymmetric_commands", None) + asymmetricCommands.setLabel("Asymmetric Cryptography Commands") + asymmetricCommands.setVisible(True) + + # ECDH + calEcdhEnabledSymbol = calComponent.createBooleanSymbol("cal_ecdh", asymmetricCommands) + calEcdhEnabledSymbol.setLabel("Support ECDH?") + calEcdhEnabledSymbol.setDescription("Enable support for ECDH Command") + calEcdhEnabledSymbol.setVisible(True) + calEcdhEnabledSymbol.setDefaultValue(True) + + calEcdhEncEnabledSymbol = calComponent.createBooleanSymbol("cal_ecdh_enc", calEcdhEnabledSymbol) + calEcdhEncEnabledSymbol.setLabel("Support ECDH Encryption?") + calEcdhEncEnabledSymbol.setDescription("Enable support for ECDH ENC") + calEcdhEncEnabledSymbol.setVisible(True) + calEcdhEncEnabledSymbol.setDefaultValue(True) + calEcdhEncEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_ecdh"]) + + # GENKEY + calGenkeyEnabledSymbol = calComponent.createBooleanSymbol("cal_genkey", asymmetricCommands) + calGenkeyEnabledSymbol.setLabel("Support Genkey?") + calGenkeyEnabledSymbol.setDescription("Enable support for Genkey Command") + calGenkeyEnabledSymbol.setVisible(True) + calGenkeyEnabledSymbol.setDefaultValue(True) + + calGenkeyMacEnabledSymbol = calComponent.createBooleanSymbol("cal_genkey_mac", calGenkeyEnabledSymbol) + calGenkeyMacEnabledSymbol.setLabel("Support Genkey MAC?") + calGenkeyMacEnabledSymbol.setDescription("Enable support for GENKEY MAC") + calGenkeyMacEnabledSymbol.setVisible(True) + calGenkeyMacEnabledSymbol.setDefaultValue(True) + + # SIGN + calSignEnabledSymbol = calComponent.createBooleanSymbol("cal_sign", asymmetricCommands) + calSignEnabledSymbol.setLabel("Support Sign?") + calSignEnabledSymbol.setDescription("Enable support for SIGN Command") + calSignEnabledSymbol.setVisible(True) + calSignEnabledSymbol.setDefaultValue(True) + + calSignInternalEnabledSymbol = calComponent.createBooleanSymbol("cal_sign_internal", calSignEnabledSymbol) + calSignInternalEnabledSymbol.setLabel("Support Sign Internal?") + calSignInternalEnabledSymbol.setDescription("Enable support for Sign Internal") + calSignInternalEnabledSymbol.setVisible(True) + calSignInternalEnabledSymbol.setDefaultValue(True) + calSignInternalEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sign"]) + + # VERIFY + calVerifyEnabledSymbol = calComponent.createBooleanSymbol("cal_verify", asymmetricCommands) + calVerifyEnabledSymbol.setLabel("Support Verify?") + calVerifyEnabledSymbol.setDescription("Enable support for VERIFY Command") + calVerifyEnabledSymbol.setVisible(True) + calVerifyEnabledSymbol.setDefaultValue(True) + + calVerifyStoredEnabledSymbol = calComponent.createBooleanSymbol("cal_verify_stored", calVerifyEnabledSymbol) + calVerifyStoredEnabledSymbol.setLabel("Support Verify Stored?") + calVerifyStoredEnabledSymbol.setDescription("Enable support for Verify Stored") + calVerifyStoredEnabledSymbol.setVisible(True) + calVerifyStoredEnabledSymbol.setDefaultValue(True) + calVerifyStoredEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_verify"]) + + calVerifyExternEnabledSymbol = calComponent.createBooleanSymbol("cal_verify_extern", calVerifyEnabledSymbol) + calVerifyExternEnabledSymbol.setLabel("Support Verify Extern?") + calVerifyExternEnabledSymbol.setDescription("Enable support for Verify Extern") + calVerifyExternEnabledSymbol.setVisible(True) + calVerifyExternEnabledSymbol.setDefaultValue(True) + calVerifyExternEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_verify"]) + + calVerifyValidateEnabledSymbol = calComponent.createBooleanSymbol("cal_verify_validate", calVerifyEnabledSymbol) + calVerifyValidateEnabledSymbol.setLabel("Support Verify Validate?") + calVerifyValidateEnabledSymbol.setDescription("Enable support for Verify Validate") + calVerifyValidateEnabledSymbol.setVisible(True) + calVerifyValidateEnabledSymbol.setDefaultValue(True) + calVerifyValidateEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_verify"]) + + calVerifyMacEnabledSymbol = calComponent.createBooleanSymbol("cal_verify_mac", calVerifyEnabledSymbol) + calVerifyMacEnabledSymbol.setLabel("Support Verify Mac?") + calVerifyMacEnabledSymbol.setDescription("Enable support for Verify Mac") + calVerifyMacEnabledSymbol.setVisible(True) + calVerifyMacEnabledSymbol.setDefaultValue(True) + calVerifyMacEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_verify"]) + + # General Device Commands + deviceCommands = calComponent.createMenuSymbol("cal_device_commands", None) + deviceCommands.setLabel("General Device Commands") + deviceCommands.setVisible(True) + + # COUNTER + calCounterEnabledSymbol = calComponent.createBooleanSymbol("cal_counter", deviceCommands) + calCounterEnabledSymbol.setLabel("Support Counter?") + calCounterEnabledSymbol.setDescription("Enable support for COUNTER Command") + calCounterEnabledSymbol.setVisible(True) + calCounterEnabledSymbol.setDefaultValue(True) + + # DERIVEKEY + calDerivekeyEnabledSymbol = calComponent.createBooleanSymbol("cal_derivekey", deviceCommands) + calDerivekeyEnabledSymbol.setLabel("Support Derivekey?") + calDerivekeyEnabledSymbol.setDescription("Enable support for Derivekey Command") + calDerivekeyEnabledSymbol.setVisible(True) + calDerivekeyEnabledSymbol.setDefaultValue(True) + + # INFO + calInfoEnabledSymbol = calComponent.createBooleanSymbol("cal_info", deviceCommands) + calInfoEnabledSymbol.setLabel("Support Info?") + calInfoEnabledSymbol.setDescription("Enable support for INFO Command") + calInfoEnabledSymbol.setVisible(True) + calInfoEnabledSymbol.setDefaultValue(True) + + # LOCK + calLockEnabledSymbol = calComponent.createBooleanSymbol("cal_lock", deviceCommands) + calLockEnabledSymbol.setLabel("Support Lock?") + calLockEnabledSymbol.setDescription("Enable support for LOCK Command") + calLockEnabledSymbol.setVisible(True) + calLockEnabledSymbol.setDefaultValue(True) + + # NONCE + calNonceEnabledSymbol = calComponent.createBooleanSymbol("cal_nonce", deviceCommands) + calNonceEnabledSymbol.setLabel("Support Nonce?") + calNonceEnabledSymbol.setDescription("Enable support for Nonce Command") + calNonceEnabledSymbol.setVisible(True) + calNonceEnabledSymbol.setDefaultValue(True) + + # PRIVWRITE + calPrivWriteEnabledSymbol = calComponent.createBooleanSymbol("cal_privwrite", deviceCommands) + calPrivWriteEnabledSymbol.setLabel("Support PrivWrite?") + calPrivWriteEnabledSymbol.setDescription("Enable support for PrivWrite Command") + calPrivWriteEnabledSymbol.setVisible(True) + calPrivWriteEnabledSymbol.setDefaultValue(True) + + # RANDOM + calRandomEnabledSymbol = calComponent.createBooleanSymbol("cal_random", deviceCommands) + calRandomEnabledSymbol.setLabel("Support Random?") + calRandomEnabledSymbol.setDescription("Enable support for Random Command") + calRandomEnabledSymbol.setVisible(True) + calRandomEnabledSymbol.setDefaultValue(True) + + # READ + calReadEnabledSymbol = calComponent.createBooleanSymbol("cal_read", deviceCommands) + calReadEnabledSymbol.setLabel("Support Read?") + calReadEnabledSymbol.setDescription("Enable support for Read Command") + calReadEnabledSymbol.setVisible(True) + calReadEnabledSymbol.setDefaultValue(True) + + calReadEncEnabledSymbol = calComponent.createBooleanSymbol("cal_read_enc", calReadEnabledSymbol) + calReadEncEnabledSymbol.setLabel("Support Encrypted Read?") + calReadEncEnabledSymbol.setDescription("Enable support for READ ENC") + calReadEncEnabledSymbol.setVisible(True) + calReadEncEnabledSymbol.setDefaultValue(True) + calReadEncEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_read"]) + + # SECUREBOOT + calSecurebootEnabledSymbol = calComponent.createBooleanSymbol("cal_secureboot", deviceCommands) + calSecurebootEnabledSymbol.setLabel("Support Secureboot?") + calSecurebootEnabledSymbol.setDescription("Enable support for Secureboot Command") + calSecurebootEnabledSymbol.setVisible(True) + calSecurebootEnabledSymbol.setDefaultValue(True) + + calSecurebootMacEnabledSymbol = calComponent.createBooleanSymbol("cal_secureboot_mac", calSecurebootEnabledSymbol) + calSecurebootMacEnabledSymbol.setLabel("Support Secureboot MAC?") + calSecurebootMacEnabledSymbol.setDescription("Enable support for SECUREBOOT MAC") + calSecurebootMacEnabledSymbol.setVisible(True) + calSecurebootMacEnabledSymbol.setDefaultValue(True) + calSecurebootMacEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_secureboot"]) + + # SELFTEST + calSelftestEnabledSymbol = calComponent.createBooleanSymbol("cal_selftest", deviceCommands) + calSelftestEnabledSymbol.setLabel("Support Selftest?") + calSelftestEnabledSymbol.setDescription("Enable support for Selftest Command") + calSelftestEnabledSymbol.setVisible(True) + calSelftestEnabledSymbol.setDefaultValue(True) + + # SHA + calShaEnabledSymbol = calComponent.createBooleanSymbol("cal_sha", deviceCommands) + calShaEnabledSymbol.setLabel("Support SHA?") + calShaEnabledSymbol.setDescription("Enable support for Sha Command") + calShaEnabledSymbol.setVisible(True) + calShaEnabledSymbol.setDefaultValue(True) + + calShaHmacEnabledSymbol = calComponent.createBooleanSymbol("cal_sha_hmac", calShaEnabledSymbol) + calShaHmacEnabledSymbol.setLabel("Support SHA HMAC?") + calShaHmacEnabledSymbol.setDescription("Enable support for SHA HMAC") + calShaHmacEnabledSymbol.setVisible(True) + calShaHmacEnabledSymbol.setDefaultValue(True) + calShaHmacEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sha"]) + + calShaContextEnabledSymbol = calComponent.createBooleanSymbol("cal_sha_context", calShaEnabledSymbol) + calShaContextEnabledSymbol.setLabel("Support SHA Context?") + calShaContextEnabledSymbol.setDescription("Enable support for SHA CONTEXT") + calShaContextEnabledSymbol.setVisible(True) + calShaContextEnabledSymbol.setDefaultValue(True) + calShaContextEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sha"]) + + # UPDATEEXTRA + calUpdateextraEnabledSymbol = calComponent.createBooleanSymbol("cal_updateextra", deviceCommands) + calUpdateextraEnabledSymbol.setLabel("Support UpdateExtra?") + calUpdateextraEnabledSymbol.setDescription("Enable support for Updateextra Command") + calUpdateextraEnabledSymbol.setVisible(True) + calUpdateextraEnabledSymbol.setDefaultValue(True) + + # WRITE + calWriteEnabledSymbol = calComponent.createBooleanSymbol("cal_write", deviceCommands) + calWriteEnabledSymbol.setLabel("Support Write?") + calWriteEnabledSymbol.setDescription("Enable support for Write Command") + calWriteEnabledSymbol.setVisible(True) + calWriteEnabledSymbol.setDefaultValue(True) + + calWriteEncEnabledSymbol = calComponent.createBooleanSymbol("cal_write_enc", calWriteEnabledSymbol) + calWriteEncEnabledSymbol.setLabel("Support Encrypted Write?") + calWriteEncEnabledSymbol.setDescription("Enable support for WRITE ENC") + calWriteEncEnabledSymbol.setVisible(True) + calWriteEncEnabledSymbol.setDefaultValue(True) + calWriteEncEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_write"]) + + # Configurations for crypto implementations external library support + calCryptoConfig = calComponent.createMenuSymbol("cal_crypto_config", None) + calCryptoConfig.setLabel("Crypto Configurations") + calCryptoConfig.setVisible(True) + + # Crypto HW AES + calHwAesEnabledSymbol = calComponent.createBooleanSymbol("cal_hw_aes", calCryptoConfig) + calHwAesEnabledSymbol.setLabel("Support Crypto Hw AES?") + calHwAesEnabledSymbol.setDescription("Enable support for HArdware AES") + calHwAesEnabledSymbol.setVisible(True) + calHwAesEnabledSymbol.setDefaultValue(True) + + # Crypto HW AES-CBC + calCryptoHWAESCBCEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_cbc", calHwAesEnabledSymbol) + calCryptoHWAESCBCEnabledSymbol.setLabel("Support Crypto Hw AES-CBC?") + calCryptoHWAESCBCEnabledSymbol.setDescription("Enable support for Hardware AES-CBC") + calCryptoHWAESCBCEnabledSymbol.setVisible(True) + calCryptoHWAESCBCEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCBCEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_hw_aes"]) + + calCryptoHWAESCBCEncEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_cbc_encrypt", calCryptoHWAESCBCEnabledSymbol) + calCryptoHWAESCBCEncEnabledSymbol.setLabel("Support Crypto Hw AES-CBC Encrypt?") + calCryptoHWAESCBCEncEnabledSymbol.setDescription("Enable support for Hardware AES-CBC Encrypt") + calCryptoHWAESCBCEncEnabledSymbol.setVisible(True) + calCryptoHWAESCBCEncEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCBCEncEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_crypto_aes_cbc"]) + + calCryptoHWAESCBCDecEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_cbc_decrypt", calCryptoHWAESCBCEnabledSymbol) + calCryptoHWAESCBCDecEnabledSymbol.setLabel("Support Crypto Hw AES-CBC Decrypt?") + calCryptoHWAESCBCDecEnabledSymbol.setDescription("Enable support for Hardware AES-CBC Decrypt") + calCryptoHWAESCBCDecEnabledSymbol.setVisible(True) + calCryptoHWAESCBCDecEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCBCDecEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_crypto_aes_cbc"]) + + # Crypto HW AES-CBCMAC + calCryptoHWAESCBCMACEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_cbcmac", calHwAesEnabledSymbol) + calCryptoHWAESCBCMACEnabledSymbol.setLabel("Support Crypto Hw AES-CBCMAC?") + calCryptoHWAESCBCMACEnabledSymbol.setDescription("Enable support for Hardware AES-CBCMAC") + calCryptoHWAESCBCMACEnabledSymbol.setVisible(True) + calCryptoHWAESCBCMACEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCBCMACEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_hw_aes"]) + + # Crypto HW AES-CTR + calCryptoHWAESCTREnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_ctr", calHwAesEnabledSymbol) + calCryptoHWAESCTREnabledSymbol.setLabel("Support Crypto Hw AES-CTR?") + calCryptoHWAESCTREnabledSymbol.setDescription("Enable support for Hardware AES-CTR") + calCryptoHWAESCTREnabledSymbol.setVisible(True) + calCryptoHWAESCTREnabledSymbol.setDefaultValue(True) + calCryptoHWAESCTREnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_hw_aes"]) + + calCryptoHWAESCTRRANDEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_ctr_rand_iv", calCryptoHWAESCTREnabledSymbol) + calCryptoHWAESCTRRANDEnabledSymbol.setLabel("Support Crypto Hw AES-CTR Random Nonce?") + calCryptoHWAESCTRRANDEnabledSymbol.setDescription("Enable support for Hardware AES-CTR Random Nonce") + calCryptoHWAESCTRRANDEnabledSymbol.setVisible(True) + calCryptoHWAESCTRRANDEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCTRRANDEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_crypto_aes_ctr"]) + + # Crypto HW AES-CCM + calCryptoHWAESCCMEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_ccm", calHwAesEnabledSymbol) + calCryptoHWAESCCMEnabledSymbol.setLabel("Support Crypto Hw AES-CCM?") + calCryptoHWAESCCMEnabledSymbol.setDescription("Enable support for Hardware AES-CCM") + calCryptoHWAESCCMEnabledSymbol.setVisible(True) + calCryptoHWAESCCMEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCCMEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_hw_aes"]) + + calCryptoHWAESCCMRANDEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_ccm_rand_iv", calCryptoHWAESCCMEnabledSymbol) + calCryptoHWAESCCMRANDEnabledSymbol.setLabel("Support Crypto Hw AES-CCM Random Nonce?") + calCryptoHWAESCCMRANDEnabledSymbol.setDescription("Enable support for Hardware AES-CCM Random Nonce") + calCryptoHWAESCCMRANDEnabledSymbol.setVisible(True) + calCryptoHWAESCCMRANDEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCCMRANDEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_crypto_aes_ccm"]) + + # Crypto HW AES-CMAC + calCryptoHWAESCMACEnabledSymbol = calComponent.createBooleanSymbol("cal_crypto_aes_cmac", calHwAesEnabledSymbol) + calCryptoHWAESCMACEnabledSymbol.setLabel("Support Crypto Hw AES-CMAC?") + calCryptoHWAESCMACEnabledSymbol.setDescription("Enable support for Hardware AES-CMAC") + calCryptoHWAESCMACEnabledSymbol.setVisible(True) + calCryptoHWAESCMACEnabledSymbol.setDefaultValue(True) + calCryptoHWAESCMACEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_hw_aes"]) + + # Crypto SW SHA + calSwShaEnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha", calCryptoConfig) + calSwShaEnabledSymbol.setLabel("Support Crypto Sw SHA?") + calSwShaEnabledSymbol.setDescription("Enable support for Software SHA") + calSwShaEnabledSymbol.setVisible(True) + calSwShaEnabledSymbol.setDefaultValue(True) + + # Crypto SW SHA1 + calCryptoSwSha1EnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha1", calSwShaEnabledSymbol) + calCryptoSwSha1EnabledSymbol.setLabel("Support Crypto Sw SHA1?") + calCryptoSwSha1EnabledSymbol.setDescription("Enable support for Software SHA1") + calCryptoSwSha1EnabledSymbol.setVisible(True) + calCryptoSwSha1EnabledSymbol.setDefaultValue(True) + calCryptoSwSha1EnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sw_sha"]) + + # Crypto SW SHA256 + calCryptoSwSha2EnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha2", calSwShaEnabledSymbol) + calCryptoSwSha2EnabledSymbol.setLabel("Support Crypto Sw SHA256?") + calCryptoSwSha2EnabledSymbol.setDescription("Enable support for Software SHA256") + calCryptoSwSha2EnabledSymbol.setVisible(True) + calCryptoSwSha2EnabledSymbol.setDefaultValue(True) + calCryptoSwSha2EnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sw_sha"]) + + # Crypto SW SHA256 Hmac + calCryptoSwSha2HmacEnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha2_hmac", calSwShaEnabledSymbol) + calCryptoSwSha2HmacEnabledSymbol.setLabel("Support Crypto Sw SHA256 Hmac?") + calCryptoSwSha2HmacEnabledSymbol.setDescription("Enable support for Software SHA256 Hmac") + calCryptoSwSha2HmacEnabledSymbol.setVisible(True) + calCryptoSwSha2HmacEnabledSymbol.setDefaultValue(True) + calCryptoSwSha2HmacEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sw_sha"]) + + # Crypto SW SHA Hmac Counter + calCryptoSwSha2HmacCtrEnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha2_hmac_ctr", calSwShaEnabledSymbol) + calCryptoSwSha2HmacCtrEnabledSymbol.setLabel("Support Crypto Sw SHA256 Hmac Counter?") + calCryptoSwSha2HmacCtrEnabledSymbol.setDescription("Enable support for Software SHA256 Hmac Counter") + calCryptoSwSha2HmacCtrEnabledSymbol.setVisible(True) + calCryptoSwSha2HmacCtrEnabledSymbol.setDefaultValue(True) + calCryptoSwSha2HmacCtrEnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sw_sha"]) + + # Crypto SW PBKDF2 SHA256 + calCryptoSwPbkdf2EnabledSymbol = calComponent.createBooleanSymbol("cal_sw_pbkdf2_sha2", calSwShaEnabledSymbol) + calCryptoSwPbkdf2EnabledSymbol.setLabel("Support Crypto Sw PBKDF2 SHA256?") + calCryptoSwPbkdf2EnabledSymbol.setDescription("Support Crypto Sw PBKDF2 SHA256") + calCryptoSwPbkdf2EnabledSymbol.setVisible(True) + calCryptoSwPbkdf2EnabledSymbol.setDefaultValue(True) + calCryptoSwPbkdf2EnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sw_sha"]) + + # Crypto SW Random + calHostSwRandEnabledSymbol = calComponent.createBooleanSymbol("cal_sw_rand", calCryptoConfig) + calHostSwRandEnabledSymbol.setLabel("Enable SW crypto implementation to get random num") + calHostSwRandEnabledSymbol.setDescription("Enable support for Software Random") + calHostSwRandEnabledSymbol.setVisible(True) + calHostSwRandEnabledSymbol.setDefaultValue(True) + + # Crypto SW Sign + calHostSwSignEnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sign", calCryptoConfig) + calHostSwSignEnabledSymbol.setLabel("Enable SW crypto implementation to perform sign?") + calHostSwSignEnabledSymbol.setDescription("Enable Software Implementation to perform sign") + calHostSwSignEnabledSymbol.setVisible(True) + calHostSwSignEnabledSymbol.setDefaultValue(True) + + # Crypto SW Verify + calHostSwVerifyEnabledSymbol = calComponent.createBooleanSymbol("cal_sw_verify", calCryptoConfig) + calHostSwVerifyEnabledSymbol.setLabel("Enable SW crypto implementation to perform verify?") + calHostSwVerifyEnabledSymbol.setDescription("Enable Software Implementation to perform verify") + calHostSwVerifyEnabledSymbol.setVisible(True) + calHostSwVerifyEnabledSymbol.setDefaultValue(True) + # FreeRTOS Support - The hal file gets included as a symbol here and turned on/off via connections calEnableRtos = calComponent.createBooleanSymbol("CAL_ENABLE_RTOS", None) calEnableRtos.setValue(False) @@ -533,3 +961,6 @@ def instantiateComponent(calComponent): calSecurity.setDisplayMode("Key") calSecurity.setVisible(True) calSecurity.setDefaultValue(0) + +def handleParentSymbolChange(symbol, event): + symbol.setVisible(event["value"]) diff --git a/harmony/config/device_instance.py b/harmony/config/device_instance.py index df7d5100b..229685c9b 100644 --- a/harmony/config/device_instance.py +++ b/harmony/config/device_instance.py @@ -22,7 +22,7 @@ * THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. *****************************************************************************""" -_DEFAULT_I2C_ADDRESS = {'ecc': 0xC0, 'sha': 0xC8, 'ta100': 0x2e} +_DEFAULT_I2C_ADDRESS = {'ecc': 0xC0, 'sha': 0xC8, 'ecc204': 0x66, 'ta100': 0x2e} _SWI_DEVICES = ['ATSHA204A', 'ATSHA206A', 'ATECC108A', 'ATECC508A', 'ATECC608', 'ECC204'] _I2C_DEVICES = ['ATSHA204A', 'ATECC108A', 'ATECC508A', 'ATECC608', 'TA100', 'ECC204'] _SPI_DEVICES = ['TA100'] @@ -61,6 +61,8 @@ def updateSercomPlibList(plib, inc): def updateTngCapability(id, src): Database.sendMessage('cryptoauthlib_tng', 'UPDATE_TNG_TYPE', {'id': id, 'src': src}) +def updateWpcCapability(id, src): + Database.sendMessage('cryptoauthlib_wpc', 'UPDATE_WPC_TYPE', {'id': id, 'src': src}) def updateDevCfgList(dev_cfg, inc): global caldevcfglist @@ -117,9 +119,12 @@ def updatePartInterfaceSettings(symbol, event): if selected_key == "TNGTLS": Database.activateComponents(['cryptoauthlib_tng']) i2c_addr = 0x6A - elif selected_key == "TFLEX": + elif selected_key == "TFLXTLS": Database.activateComponents(['cryptoauthlib_tng']) i2c_addr = 0x6C + elif selected_key == "TFLXWPC": + Database.activateComponents(['cryptoauthlib_wpc']) + i2c_addr = 0x70 elif selected_key == "TNGLORA": Database.activateComponents(['cryptoauthlib_tng']) i2c_addr = 0xB2 @@ -128,6 +133,7 @@ def updatePartInterfaceSettings(symbol, event): symbol.getComponent().getSymbolByID('I2C_ADDR').setValue(i2c_addr) updateTngCapability(selected_key, event['namespace']) + updateWpcCapability(selected_key, event['namespace']) def sort_alphanumeric(l): @@ -165,7 +171,8 @@ def instantiateComponent(deviceComponent, index): devicePartType = deviceComponent.createKeyValueSetSymbol("PART_TYPE", interfaceType) devicePartType.setLabel("Select Part Type") devicePartType.addKey("Custom", "0", "Trust Custom") - devicePartType.addKey("TFLEX", "3", "Trust Flex") + devicePartType.addKey("TFLXTLS", "3", "Trust Flex: TLS") + devicePartType.addKey("TFLXWPC", "4", "Trust Flex: WPC") devicePartType.addKey("TNGTLS", "1", "Trust & Go: TLS") devicePartType.addKey("TNGLORA", "2", "Trust & Go: LORA") devicePartType.setDefaultValue(0) @@ -176,7 +183,9 @@ def instantiateComponent(deviceComponent, index): deviceAddress = deviceComponent.createHexSymbol("I2C_ADDR", interfaceType) deviceAddress.setLabel("I2C Address") - if 'ECC' in deviceID: + if 'ECC204' in deviceID: + deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['ecc204']) + elif 'ECC' in deviceID: deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['ecc']) elif 'SHA' in deviceID: deviceAddress.setDefaultValue(_DEFAULT_I2C_ADDRESS['sha']) diff --git a/harmony/config/test_app.py b/harmony/config/test_app.py index 953747248..999e13aa5 100644 --- a/harmony/config/test_app.py +++ b/harmony/config/test_app.py @@ -27,10 +27,9 @@ fileSymbolName = "CAL_FILE_SRC_TEST_" numFileCntr = 0 -_TEST_PATHS = ['atcacert/*', 'jwt/*', 'api_atcab/*', 'api_calib/*', 'api_crypto/*', 'api_talib/*', 'vectors/*'] -_TEST_SOURCES = ['atca_crypto_sw_tests.c', 'atca_test.c', 'atca_test_config.c', 'atca_test_console.c', - 'atca_utils_atecc608.c', 'cmd-processor.c'] -_TEST_HEADERS = ['atca_crypto_sw_tests.h', 'atca_test.h', 'cbuf.h', 'cmd-processor.h'] +_TEST_PATHS = ['atcacert/*', 'integration/*', 'jwt/*', 'api_atcab/*', 'api_calib/*', 'api_crypto/*', 'api_talib/*', 'vectors/*'] +_TEST_SOURCES = ['atca_test.c', 'atca_test_config.c', 'atca_test_console.c', 'atca_utils_atecc608.c', 'cmd-processor.c'] +_TEST_HEADERS = ['atca_test.h', 'cbuf.h', 'cmd-processor.h'] def CALSecFileUpdate(symbol, event): diff --git a/harmony/config/tng.py b/harmony/config/tng.py index ee1bf78db..75ba0609b 100644 --- a/harmony/config/tng.py +++ b/harmony/config/tng.py @@ -51,9 +51,8 @@ def updateTracker(id, src): tnglora = Database.getComponentByID('cryptoauthlib_tng').getSymbolByID('CAL_TNGLORA_SUPPORT') tnglora.setValue('TNGLORA' in values) - trustflex = Database.getComponentByID('cryptoauthlib_tng').getSymbolByID('CAL_TFLEX_SUPPORT') - trustflex.setValue('TFLEX' in values) - + tflxtls = Database.getComponentByID('cryptoauthlib_tng').getSymbolByID('CAL_TFLXTLS_SUPPORT') + tflxtls.setValue('TFLXTLS' in values) def handleMessage(messageID, args): if (messageID == 'UPDATE_TNG_TYPE'): @@ -88,7 +87,7 @@ def AddFilesDir(component, configName, dirPath): for filename in files: filepath = str(root + os.sep + filename) source_path = filepath[len(modulePath):] - destination_path = "library" + os.sep + "cryptoauthlib" + os.sep + "tng" + root[len(dirPath):] + destination_path = "library" + os.sep + "cryptoauthlib" + os.sep + os.path.basename(dirPath) + root[len(dirPath):] project_path = str("config" + os.sep + configName + os.sep + destination_path) if (".c" in filename): AddFile(component, source_path , destination_path, project_path) @@ -131,9 +130,9 @@ def instantiateComponent(tngComponent): tnglora.setLabel("TNGLORA Certificates?") tnglora.setVisible(True) - trustflex = tngComponent.createBooleanSymbol("CAL_TFLEX_SUPPORT", None) - trustflex.setLabel("Trust Flex Certificates?") - trustflex.setVisible(True) + tflxtls = tngComponent.createBooleanSymbol("CAL_TFLXTLS_SUPPORT", None) + tflxtls.setLabel("TFLXTLS Certificates?") + tflxtls.setVisible(True) trustlegacy = tngComponent.createBooleanSymbol("CAL_TNG_LEGACY_SUPPORT", None) trustlegacy.setLabel("Legacy Trust Certificates?") diff --git a/harmony/config/wpc.py b/harmony/config/wpc.py new file mode 100644 index 000000000..312531c38 --- /dev/null +++ b/harmony/config/wpc.py @@ -0,0 +1,117 @@ +# coding: utf-8 +"""***************************************************************************** +* Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries. +* +* Subject to your compliance with these terms, you may use Microchip software +* and any derivatives exclusively with Microchip products. It is your +* responsibility to comply with third party license terms applicable to your +* use of third party software (including open source software) that may +* accompany Microchip software. +* +* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER +* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED +* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A +* PARTICULAR PURPOSE. +* +* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, +* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND +* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS +* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE +* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN +* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, +* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. +*****************************************************************************""" +import os + +fileSymbolName = "CAL_FILE_SRC_WPC_" +numFileCntr = 0 + +_wpc_type_tracker = {} + + +def CALSecFileUpdate(symbol, event): + symObj = event['symbol'] + selected_key = symObj.getSelectedKey() + + if selected_key == "SECURE": + symbol.setSecurity("SECURE") + elif selected_key == "NON_SECURE": + symbol.setSecurity("NON_SECURE") + + +def updateTracker(id, src): + global _wpc_type_tracker + _wpc_type_tracker[src] = id + + values = set(_wpc_type_tracker.values()) + + tflxwpc = Database.getComponentByID('cryptoauthlib_wpc').getSymbolByID('CAL_TFLXWPC_SUPPORT') + tflxwpc.setValue('TFLXWPC' in values) + +def handleMessage(messageID, args): + if (messageID == 'UPDATE_WPC_TYPE'): + if isinstance(args, dict): + updateTracker(**args) + + return {} + +def AddFile(component, src_path, dest_path, proj_path, file_type = "SOURCE", isMarkup = False): + global fileSymbolName + global numFileCntr + srcFile = component.createFileSymbol(fileSymbolName + str(numFileCntr) , None) + srcFile.setSourcePath(src_path) + srcFile.setDestPath(dest_path) + srcFile.setProjectPath(proj_path) + srcFile.setType(file_type) + srcFile.setOutputName(os.path.basename(src_path)) + srcFile.setMarkup(isMarkup) + try: + CALSecValue = Database.getComponentByID('cryptoauthlib').getSymbolByID('CAL_NON_SECURE').getValue() + if CALSecValue == True: + srcFile.setSecurity("SECURE") + except: + pass + srcFile.setDependencies(CALSecFileUpdate, ["cryptoauthlib.CAL_NON_SECURE"]) + numFileCntr += 1 + +def AddFilesDir(component, configName, dirPath): + modulePath = Module.getPath() + dirPath = str(modulePath + dirPath) + for (root, dirs, files) in os.walk(dirPath): + for filename in files: + filepath = str(root + os.sep + filename) + source_path = filepath[len(modulePath):] + destination_path = "library" + os.sep + "cryptoauthlib" + os.sep + os.path.basename(dirPath) + root[len(dirPath):] + project_path = str("config" + os.sep + configName + os.sep + destination_path) + if (".c" in filename): + AddFile(component, source_path , destination_path, project_path) + elif (".h" in filename): + AddFile(component, source_path , destination_path, project_path, "HEADER") + + + +def onAttachmentConnected(source, target): + pass + +def onAttachmentDisconnected(source, target): + pass + +def instantiateComponent(wpcComponent): + # Makes sure the Library is included as well. + Database.activateComponents(['cryptoauthlib']) + + configName = Variables.get("__CONFIGURATION_NAME") + + targetPath = '../src/config/' + configName + '/library/cryptoauthlib/wpc' + + # Append the include paths in MPLABX IDE + defSym = wpcComponent.createSettingSymbol("CAL_XC32_INCLUDE_DIRS", None) + defSym.setCategory("C32") + defSym.setKey("extra-include-directories") + + defSym.setValue( '{0}'.format(targetPath)) + defSym.setAppend(True, ';') + defSym.setDependencies(CALSecFileUpdate, ["CAL_NON_SECURE"]) + + AddFilesDir(wpcComponent, configName, 'app/wpc') + diff --git a/harmony/module.py b/harmony/module.py index 7cd8ab204..8ee02ca84 100644 --- a/harmony/module.py +++ b/harmony/module.py @@ -37,6 +37,10 @@ def loadModule(): cryptoAuthLibTng.setDisplayType("TNGTLS & TNGLORA Certificates") cryptoAuthLibTng.addDependency("CAL_LIB_CAP", "CA_LIB", True, False) + cryptoAuthLibWpc = Module.CreateSharedComponent("cryptoauthlib_wpc", "TrustFLEX WPC", "/Libraries/Cryptoauthlib", "/harmony/config/wpc.py") + cryptoAuthLibWpc.setDisplayType("TFLXWPC Certificates") + cryptoAuthLibWpc.addDependency("CAL_LIB_CAP", "CA_LIB", True, False) + cryptoAuthLibPkcs11 = Module.CreateSharedComponent("cryptoauthlib_pkcs11", "PKCS11", "/Libraries/Cryptoauthlib", "/harmony/config/pkcs11.py") cryptoAuthLibPkcs11.setDisplayType("PKCS#11 Interface") cryptoAuthLibPkcs11.addDependency("CAL_LIB_CAP", "CA_LIB", True, False) diff --git a/harmony/templates/atca_config.h.ftl b/harmony/templates/atca_config.h.ftl index 6a4d60d56..7313e3a99 100644 --- a/harmony/templates/atca_config.h.ftl +++ b/harmony/templates/atca_config.h.ftl @@ -60,6 +60,364 @@ #endif +/** Symmetric Commands Configurations */ + +/* AES Command */ +<#if cal_aes == false> + <#lt>#define ATCAB_AES_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_AES_EN (FEATURE_ENABLED) + + <#if cal_aes_gcm == false> + <#lt>#define ATCAB_AES_GCM_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_GCM_EN (FEATURE_ENABLED) + + <#if cal_aes_gfm == false> + <#lt>#define ATCAB_AES_GFM_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_GFM_EN (FEATURE_ENABLED) + + + +/* Checkmac Command */ +<#if cal_checkmac == false> + <#lt>#define ATCAB_CHECKMAC_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_CHECKMAC_EN (FEATURE_ENABLED) + + +/* Gendig Command */ +<#if cal_gendig == false> + <#lt>#define ATCAB_GENDIG_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_GENDIG_EN (FEATURE_ENABLED) + + +/* KDF Command */ +<#if cal_kdf == false> + <#lt>#define ATCAB_KDF_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_KDF_EN (FEATURE_ENABLED) + + +/* MAC Command */ +<#if cal_mac == false> + <#lt>#define ATCAB_MAC_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_MAC_EN (FEATURE_ENABLED) + + +/* HMAC Command */ +<#if cal_hmac == false> + <#lt>#define ATCAB_HMAC_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_HMAC_EN (FEATURE_ENABLED) + + +/** Asymmetric Commands Configurations */ + +/* ECDH Command */ +<#if cal_ecdh == false> + <#lt>#define ATCAB_ECDH_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_ECDH_EN (FEATURE_ENABLED) + + <#if cal_ecdh_enc == false> + <#lt>#define ATCAB_ECDH_ENC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_ECDH_ENC_EN (FEATURE_ENABLED) + + + +/* Genkey Command */ +<#if cal_genkey == false> + <#lt>#define ATCAB_GENKEY_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_GENKEY_EN (FEATURE_ENABLED) + + <#if cal_genkey_mac == false> + <#lt>#define ATCAB_GENKEY_MAC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_GENKEY_MAC_EN (ATCAB_GENKEY_EN) + + + +/* Sign Command */ +<#if cal_sign == false> + <#lt>#define ATCAB_SIGN_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_SIGN_EN (FEATURE_ENABLED) + + <#if cal_sign_internal == false> + <#lt>#define ATCAB_SIGN_INTERNAL_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_SIGN_INTERNAL_EN (ATCAB_SIGN_EN) + + + +/* VERIFY Command */ +<#if cal_verify == false> + <#lt>#define ATCAB_VERIFY_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_VERIFY_EN (FEATURE_ENABLED) + + <#if cal_verify_stored == false> + <#lt>#define ATCAB_VERIFY_STORED_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_VERIFY_STORED_EN (ATCAB_VERIFY_EN) + + + <#if cal_verify_extern == false> + <#lt>#define ATCAB_VERIFY_EXTERN_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_VERIFY_EXTERN_EN (ATCAB_VERIFY_EN) + + + <#if cal_verify_validate == false> + <#lt>#define ATCAB_VERIFY_VALIDATE_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_VERIFY_VALIDATE_EN (ATCAB_VERIFY_EN) + + + <#if cal_verify_mac == false> + <#lt>#define ATCAB_VERIFY_EXTERN_STORED_MAC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_VERIFY_EXTERN_STORED_MAC_EN (ATCAB_VERIFY_EN) + + + +/** General Device Commands Configurations */ + +/* Counter Command */ +<#if cal_counter == false> + <#lt>#define ATCAB_COUNTER_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_COUNTER_EN (FEATURE_ENABLED) + + +/* Derivekey Command */ +<#if cal_derivekey == false> + <#lt>#define ATCAB_DERIVEKEY_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_DERIVEKEY_EN (FEATURE_ENABLED) + + +/* Info Command */ +<#if cal_info == false> + <#lt>#define ATCAB_INFO_LATCH_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_INFO_LATCH_EN (FEATURE_ENABLED) + + +/* Lock Command */ +<#if cal_lock == false> + <#lt>#define ATCAB_LOCK_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_LOCK_EN (FEATURE_ENABLED) + + +/* Nonce Command */ +<#if cal_derivekey == false> + <#lt>#define ATCAB_NONCE_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_NONCE_EN (FEATURE_ENABLED) + + +/* PrivWrite Command */ +<#if cal_privwrite == false> + <#lt>#define ATCAB_PRIVWRITE_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_PRIVWRITE_EN (FEATURE_ENABLED) + + +/* Random Command */ +<#if cal_random == false> + <#lt>#define ATCAB_RANDOM_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_RANDOM_EN (FEATURE_ENABLED) + + +/* Read Command */ +<#if cal_read == false> + <#lt>#define ATCAB_READ_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_READ_EN (FEATURE_ENABLED) + + <#if cal_read_enc == false> + <#lt>#define ATCAB_READ_ENC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_READ_ENC_EN (ATCAB_READ_EN) + + + +/* Secureboot Command */ +<#if cal_secureboot == false> + <#lt>#define ATCAB_SECUREBOOT_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_SECUREBOOT_EN (FEATURE_ENABLED) + + <#if cal_secureboot_mac == false> + <#lt>#define ATCAB_SECUREBOOT_MAC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_SECUREBOOT_MAC_EN (ATCAB_SECUREBOOT_EN) + + + +/* Selftest Command */ +<#if cal_selftest == false> + <#lt>#define ATCAB_SELFTEST_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_SELFTEST_EN (FEATURE_ENABLED) + + +/* SHA Command */ +<#if cal_sha == false> + <#lt>#define ATCAB_SHA_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_SHA_EN (FEATURE_ENABLED) + + <#if cal_sha_hmac == false> + <#lt>#define ATCAB_SHA_HMAC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_SHA_HMAC_EN (ATCAB_SHA_EN) + + + <#if cal_sha_context == false> + <#lt>#define ATCAB_SHA_CONTEXT_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_SHA_CONTEXT_EN (ATCAB_SHA_EN) + + + +/* UpdateExtra Command */ +<#if cal_updateextra == false> + <#lt>#define ATCAB_UPDATEEXTRA_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_UPDATEEXTRA_EN (FEATURE_ENABLED) + + +/* Write Command */ +<#if cal_write == false> + <#lt>#define ATCAB_WRITE_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_WRITE_EN (FEATURE_ENABLED) + + <#if cal_write_enc == false> + <#lt>#define ATCAB_WRITE_ENC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_WRITE_ENC_EN (ATCAB_WRITE_EN) + + + +/* Host side Cryptographic functionality required by the library */ + +/* Crypto Hardware AES Configurations */ +<#if cal_hw_aes == false> + <#lt>#define ATCAB_AES_EXTRAS_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAB_AES_EXTRAS_EN (CALIB_AES_EN || TALIB_AES_EN) + + <#if cal_crypto_aes_cbc_encrypt == false> + <#lt>#define ATCAB_AES_CBC_ENCRYPT_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CBC_ENCRYPT_EN (ATCAB_AES_EXTRAS_EN) + + + <#if cal_crypto_aes_cbc_decrypt == false> + <#lt>#define ATCAB_AES_CBC_DECRYPT_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CBC_DECRYPT_EN (ATCAB_AES_EXTRAS_EN) + + + <#if cal_crypto_aes_cbcmac == false> + <#lt>#define ATCAB_AES_CBCMAC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CBCMAC_EN (ATCAB_AES_CBC_ENCRYPT_EN) + + + <#if cal_crypto_aes_ctr == false> + <#lt>#define ATCAB_AES_CTR_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CTR_EN (ATCAB_AES_EXTRAS_EN) + + + <#if cal_crypto_aes_ctr_rand_iv == false> + <#lt>#define ATCAB_AES_CTR_RAND_IV_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CTR_RAND_IV_EN (ATCAB_AES_CTR_EN && ATCAB_AES_RANDOM_IV_EN) + + + <#if cal_crypto_aes_ccm == false> + <#lt>#define ATCAB_AES_CCM_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CCM_EN (ATCAB_AES_CBCMAC_EN && ATCAB_AES_CTR_EN) + + + <#if cal_crypto_aes_ccm_rand_iv == false> + <#lt>#define ATCAB_AES_CCM_RAND_IV_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CCM_RAND_IV_EN (ATCAB_AES_CCM_EN && ATCAB_AES_RANDOM_IV_EN) + + + <#if cal_crypto_aes_cmac == false> + <#lt>#define ATCAB_AES_CMAC_EN (FEATURE_DISABLED) + <#else> + <#lt>#define ATCAB_AES_CMAC_EN (ATCAB_AES_CBC_ENCRYPT_EN) + + + +/* Crypto Software SHA Configurations */ +<#if cal_sw_sha1 == false> + <#lt>#define ATCAC_SHA1_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_SHA1_EN (FEATURE_ENABLED) + + +<#if cal_sw_sha2 == false> + <#lt>#define ATCAC_SHA256_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_SHA256_EN (FEATURE_ENABLED) + + +<#if cal_sw_sha2_hmac == false> + <#lt>#define ATCAC_SHA256_HMAC_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_SHA256_HMAC_EN (ATCAC_SHA256_EN) + + +<#if cal_sw_sha2_hmac_ctr == false> + <#lt>#define ATCAC_SHA256_HMAC_CTR_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_SHA256_HMAC_CTR_EN (ATCAC_SHA256_HMAC_EN) + + +<#if cal_sw_pbkdf2_sha2 == false> + <#lt>#define ATCAC_PBKDF2_SHA256_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_PBKDF2_SHA256_EN (ATCAC_SHA256_HMAC_EN) + + +/* External Crypto libraries configurations for host side operations */ + +<#if cal_sw_rand == false> + <#lt>#define ATCAC_RANDOM_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_RANDOM_EN (ATCA_HOSTLIB_EN) + + +<#if cal_sw_sign == false> + <#lt>#define ATCAC_SIGN_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_SIGN_EN (ATCA_HOSTLIB_EN) + + +<#if cal_sw_verify == false> + <#lt>#define ATCAC_VERIFY_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_VERIFY_EN (ATCA_HOSTLIB_EN) + + <#if CAL_ENABLE_RTOS> /** Define platform malloc/free */ #define ATCA_PLATFORM_MALLOC OSAL_Malloc @@ -286,7 +644,7 @@ extern atca_plib_${plib_drv!"i2c"}_api_t ${plib_info[0]}_plib_${plib_drv!"i2c"}_ <#if cryptoauthlib_tng.CAL_TNGLORA_SUPPORT> #define ATCA_TNGLORA_SUPPORT -<#if cryptoauthlib_tng.CAL_TFLEX_SUPPORT> +<#if cryptoauthlib_tng.CAL_TFLXTLS_SUPPORT> #define ATCA_TFLEX_SUPPORT <#if cryptoauthlib_tng.CAL_TNG_LEGACY_SUPPORT> diff --git a/harmony/templates/device_instance.c.ftl b/harmony/templates/device_instance.c.ftl index 2501a6a01..b02bb43d5 100644 --- a/harmony/templates/device_instance.c.ftl +++ b/harmony/templates/device_instance.c.ftl @@ -39,6 +39,7 @@ ATCAIfaceCfg ${NAME?lower_case}_${INDEX?string}_init_data = { <#elseif INTERFACE == "ATCA_SWI_GPIO_IFACE"> <#assign plib_type = "bb"> .atcaswi.bus = ${PLIB_NAME}_PIN_${SWIBB_CRYPTO_PIN?upper_case}, + .atcaswi.address = 0x${I2C_ADDR?upper_case}, <#elseif INTERFACE == "ATCA_SWI_IFACE"> <#assign plib_type = "uart"> .atcaswi.bus = 0, diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 340161d54..9e28f8a06 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -20,6 +20,7 @@ option(ATCA_BUILD_SHARED_LIBS "Build CryptoAuthLib as shared library" ON) option(ATCA_NO_HEAP "Do not use dynamic (heap) allocation functions" OFF) option(ATCA_USE_ATCAB_FUNCTIONS "Build the atcab_ api functions rather than using macros" OFF) option(ATCA_ENABLE_DEPRECATED "Enable the use of older APIs that that been replaced" OFF) +option(ATCA_STRICT_C99 "Enable strict C99 compliance for the libray" OFF) # Software Cryptographic backend for host crypto abstractions option(ATCA_MBEDTLS "Integrate with mbedtls" OFF) @@ -32,6 +33,9 @@ option(ATCA_TNGLORA_SUPPORT "Include Trust & Go LORA Certificates") option(ATCA_TFLEX_SUPPORT "Include Trust Flex Certificates") option(ATCA_TNG_LEGACY_SUPPORT "Include previous version of Trust & Go Certificates") +# WPC Options +option(ATCA_WPC_SUPPORT "Include WPC Certificates") + # Device enablement option(ATCA_ATSHA204A_SUPPORT "Include support for ATSHA204A device" ON) option(ATCA_ATSHA206A_SUPPORT "Include support for ATSHA206A device" ON) @@ -64,6 +68,8 @@ endif() # Check Platform Information check_symbol_exists(malloc "stdlib.h" HAS_MALLOC) check_symbol_exists(free "stdlib.h" HAS_FREE) +check_symbol_exists(strcasestr "string.h" HAS_STRCASESTR) +check_symbol_exists(memset_s "string.h" HAS_MEMSET_S) set(BUILD_SHARED_LIBS ${ATCA_BUILD_SHARED_LIBS}) @@ -86,11 +92,13 @@ file(GLOB JWT_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "jwt/*.c") file(GLOB JWT_INC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "jwt/*.h") file(GLOB TNG_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../app/tng/*.c") file(GLOB TNG_INC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../app/tng/*.h") +file(GLOB WPC_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../app/wpc/*.c") +file(GLOB WPC_INC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../app/wpc/*.h") file(GLOB SHA206_API_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../app/api_206a/*.c") file(GLOB SHA206_API_INC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../app/api_206a/*.h") -if(ATCA_PKCS11) -include(cmake/pkcs11.cmake) +if(ATCA_PKCS11 AND (ATCA_TNGTLS_SUPPORT OR ATCA_TNGLORA_SUPPORT OR ATCA_TFLEX_SUPPORT)) +SET(TNG_SRC ${TNG_SRC} ../app/pkcs11/trust_pkcs11_config.c) endif() if(${CMAKE_VERSION} VERSION_GREATER "3.8.0") @@ -100,7 +108,9 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${TALIB_SRC}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CRYPTO_SRC}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${HOST_SRC}) source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${JWT_SRC}) +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${PKCS11_SRC}) source_group("App/Tng" FILES ${TNG_SRC}) +source_group("App/Wpc" FILES ${WPC_SRC}) endif() if (ATCA_MBEDTLS) @@ -116,7 +126,7 @@ file(GLOB MBEDTLS_LIB_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../third_party/m add_library(mbedtls STATIC ${MBEDTLS_LIB_SRC}) target_compile_definitions(mbedtls PUBLIC -DMBEDTLS_CMAC_C) -if(NOT WIN32) +if(NOT MSVC) target_compile_options(mbedtls PRIVATE -fPIC) endif() include_directories(mbedtls PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} @@ -125,6 +135,10 @@ endif() file(GLOB MBEDTLS_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "mbedtls/*.c") +if(NOT MSVC) +set_source_files_properties(mbedtls/atca_mbedtls_wrap.c PROPERTIES COMPILE_FLAGS -Wno-pedantic) +endif() + if(${CMAKE_VERSION} VERSION_GREATER "3.8.0") source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${MBEDTLS_SRC}) endif() @@ -148,6 +162,7 @@ set(WOLFSSL_LIB_SRC ../third_party/wolfssl/wolfcrypt/src/aes.c ../third_party/wolfssl/wolfcrypt/src/cmac.c ../third_party/wolfssl/wolfcrypt/src/coding.c ../third_party/wolfssl/wolfcrypt/src/des3.c + ../third_party/wolfssl/wolfcrypt/src/dsa.c ../third_party/wolfssl/wolfcrypt/src/ecc.c ../third_party/wolfssl/wolfcrypt/src/hash.c ../third_party/wolfssl/wolfcrypt/src/hmac.c @@ -170,7 +185,7 @@ target_compile_definitions(wolfssl PRIVATE -DWOLFSSL_USER_SETTINGS) configure_file(../third_party/wolfssl_settings.h.in user_settings.h @ONLY) set(WOLFSSL_USER_SETTINGS TRUE) -if(NOT WIN32) +if(NOT MSVC) target_compile_options(wolfssl PRIVATE -fPIC) endif() @@ -213,7 +228,6 @@ set(CRYPTOAUTH_SRC ${LIB_SRC} ${CRYPTO_SRC} ${JWT_SRC} ${TNG_SRC} - ${PKCS11_SRC} ${MBEDTLS_SRC} ${WOLFSSL_SRC} ${OPENSSL_SRC} @@ -263,7 +277,7 @@ set(USE_UDEV TRUE) elseif(LIBUSB_GOOD) set(USE_LIBUSB TRUE) else() -message(FATAL_ERROR "Missing Build Dependencies for USB - install libusb-1.0-0-dev or libudev-dev") +message(FATAL_ERROR, "Missing Build Dependencies for USB - install libusb-1.0-0-dev or libudev-dev") endif() endif(LINUX AND NEED_USB) @@ -310,11 +324,21 @@ if(ATCA_HAL_KIT_BRIDGE) set(CRYPTOAUTH_SRC ${CRYPTOAUTH_SRC} hal/hal_kit_bridge.c) endif(ATCA_HAL_KIT_BRIDGE) +if(ATCA_WPC_SUPPORT) +set(CRYPTOAUTH_SRC ${CRYPTOAUTH_SRC} ${WPC_SRC}) +endif(ATCA_WPC_SUPPORT) + # Add Remaining Sources depending on target library type if(ATCA_MBEDTLS) set(CRYPTOAUTH_SRC ${CRYPTOAUTH_SRC} ${MBEDTLS_SRC}) endif() +if(ATCA_PKCS11) +include(cmake/pkcs11.cmake) +set(CRYPTOAUTH_SRC ${CRYPTOAUTH_SRC} ${PKCS11_SRC}) +set(ATCA_LIBRARY_CONF ${DEFAULT_CONF_PATH}/${DEFAULT_CONF_FILE_NAME} CACHE STRING "" FORCE) +endif() + if(ATCA_BUILD_SHARED_LIBS) add_definitions(-DATCA_BUILD_SHARED_LIBS) set(CRYPTOAUTH_SRC ${CRYPTOAUTH_SRC} atca_utils_sizes.c) @@ -332,12 +356,18 @@ if(HAS_FREE) set(ATCA_PLATFORM_FREE free CACHE STRING "" FORCE) endif(HAS_FREE) +if(HAS_STRCASESTR) +set(ATCA_PLATFORM_STRCASESTR strcasestr CACHE STRING "" FORCE) +endif(HAS_STRCASESTR) + +if(HAS_MEMSET_S) +set(ATCA_PLATFORM_MEMSET_S memset_s CACHE STRING "" FORCE) +endif(HAS_MEMSET_S) + if(BUILD_TESTS) set(ATCA_TESTS_ENABLED ON CACHE INTERNAL "") endif(BUILD_TESTS) -set(ATCA_LIBRARY_CONF ${DEFAULT_CONF_PATH}/${DEFAULT_CONF_FILE_NAME} CACHE STRING "" FORCE) - configure_file(atca_config.h.in atca_config.h @ONLY) set(LIB_INC ${LIB_INC} ${CMAKE_CURRENT_BINARY_DIR}/atca_config.h) @@ -377,6 +407,24 @@ endif() target_link_libraries(cryptoauth rt) endif(LINUX) +if(NOT MSVC) +target_compile_options(cryptoauth PRIVATE -ffile-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=. + -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.) +#target_compile_options(cryptoauth PRIVATE -Wall -Wextra -Werror) +target_compile_options(cryptoauth PRIVATE -Wall -Wextra) +endif() + +if(ATCA_STRICT_C99) +set_property(TARGET cryptoauth PROPERTY C_STANDARD 99) +if(NOT MSVC) +target_compile_options(cryptoauth PRIVATE -Wpedantic) +endif() +endif() + +if(NOT MSVC AND ATCA_HAL_KIT_HID) +set_source_files_properties(${HID_SRC} PROPERTIES COMPILE_FLAGS "-w") +endif() + if(DEFAULT_LIB_PATH) if(${CMAKE_VERSION} VERSION_GREATER "3.12.0") install(TARGETS ${PROJECT_NAME} @@ -406,5 +454,6 @@ if (ATCA_PKCS11) install(FILES ${PKCS11_INC} DESTINATION ${DEFAULT_INC_PATH}/pkcs11 COMPONENT Development) endif() install(FILES ${TNG_INC} DESTINATION ${DEFAULT_INC_PATH}/app/tng COMPONENT Development) +install(FILES ${WPC_INC} DESTINATION ${DEFAULT_INC_PATH}/app/wpc COMPONENT Development) install(FILES ${SHA206_API_INC} DESTINATION ${DEFAULT_INC_PATH}/app/api_206a COMPONENT Development) endif(DEFAULT_INC_PATH) diff --git a/lib/atca_basic.c b/lib/atca_basic.c index b533d6dc2..530ddb8a2 100644 --- a/lib/atca_basic.c +++ b/lib/atca_basic.c @@ -81,6 +81,7 @@ ATCA_STATUS atcab_init_ext(ATCADevice* device, ATCAIfaceCfg *cfg) } #ifdef ATCA_NO_HEAP + memset(&g_atcab_device, 0, sizeof(g_atcab_device)); g_atcab_device.mIface = g_atcab_iface; status = initATCADevice(cfg, &g_atcab_device); if (status != ATCA_SUCCESS) @@ -89,36 +90,39 @@ ATCA_STATUS atcab_init_ext(ATCADevice* device, ATCAIfaceCfg *cfg) } *device = &g_atcab_device; #else - *device = newATCADevice(cfg); - if (*device == NULL) + if (NULL != (*device = newATCADevice(cfg))) { - return ATCA_GEN_FAIL; + status = ATCA_SUCCESS; } #endif -#ifdef ATCA_ATECC608_SUPPORT - if (cfg->devtype == ATECC608) +#if defined(ATCA_ATECC608_SUPPORT) || defined(ATCA_ECC204_SUPPORT) + if (ATCA_SUCCESS == status) { - if ((status = calib_read_bytes_zone(*device, ATCA_ZONE_CONFIG, 0, ATCA_CHIPMODE_OFFSET, &(*device)->clock_divider, 1)) != ATCA_SUCCESS) + #ifdef ATCA_ATECC608_SUPPORT + if (ATECC608 == cfg->devtype) { - return status; + if ((status = calib_read_bytes_zone(*device, ATCA_ZONE_CONFIG, 0, ATCA_CHIPMODE_OFFSET, &(*device)->clock_divider, 1)) != ATCA_SUCCESS) + { + return status; + } + (*device)->clock_divider &= ATCA_CHIPMODE_CLOCK_DIV_MASK; } - (*device)->clock_divider &= ATCA_CHIPMODE_CLOCK_DIV_MASK; - } -#endif + #endif -#ifdef ATCA_ECC204_SUPPORT - /* To compatible with kitprotocol firmware on otherside */ - /* On kitprotocol firmware, during discovery time itself ECC204 would have woke up */ - if ((ECC204 == cfg->devtype) && (atca_iface_is_kit(atGetIFace(*device)))) - { - (*device)->device_state = ATCA_DEVICE_STATE_ACTIVE; + #ifdef ATCA_ECC204_SUPPORT + /* To compatible with kitprotocol firmware on otherside */ + /* On kitprotocol firmware, during discovery time itself ECC204 would have woke up */ + if ((ECC204 == cfg->devtype) && (ATCA_HID_IFACE == cfg->iface_type || ATCA_UART_IFACE == cfg->iface_type)) + { + (*device)->device_state = ATCA_DEVICE_STATE_ACTIVE; + } + #endif } #endif - } - return ATCA_SUCCESS; + return status; } /** \brief Creates a global ATCADevice object used by Basic API. @@ -233,9 +237,9 @@ uint8_t atcab_get_device_address(ATCADevice device) { case ATCA_I2C_IFACE: #ifdef ATCA_ENABLE_DEPRECATED - return device->mIface.mIfaceCFG->atcai2c.slave_address; + return ATCA_IFACECFG_VALUE(device->mIface.mIfaceCFG, atcai2c.slave_address); #else - return device->mIface.mIfaceCFG->atcai2c.address; + return ATCA_IFACECFG_VALUE(device->mIface.mIfaceCFG, atcai2c.address); #endif default: break; @@ -244,7 +248,6 @@ uint8_t atcab_get_device_address(ATCADevice device) return 0xFF; } - /** \brief Check whether the device is cryptoauth device * \return True if device is cryptoauth device or False. */ @@ -261,7 +264,7 @@ bool atcab_is_ta_device(ATCADeviceType dev_type) return (dev_type == TA100) ? true : false; } -#if (ATCA_CA_SUPPORT && ATCA_TA_SUPPORT) || defined(ATCA_USE_ATCAB_FUNCTIONS) || defined(ATCA_ECC204_SUPPORT) +#ifdef ATCA_USE_ATCAB_FUNCTIONS /** \brief wakeup the CryptoAuth device * \return ATCA_SUCCESS on success, otherwise an error code. @@ -377,7 +380,9 @@ ATCA_STATUS atcab_get_zone_size(uint8_t zone, uint16_t slot, size_t* size) } return status; } +#endif +#if ATCAB_AES_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /* AES commands */ /** \brief Compute the AES-128 encrypt, decrypt, or GFM calculation. * \param[in] mode The mode for the AES command. @@ -513,7 +518,9 @@ ATCA_STATUS atcab_aes_decrypt(uint16_t key_id, uint8_t key_block, const uint8_t* { return atcab_aes_decrypt_ext(_gDevice, key_id, key_block, ciphertext, plaintext); } +#endif /* ATCAB_AES_EN */ +#if ATCAB_AES_GFM_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Perform a Galois Field Multiply (GFM) operation. * * \param[in] h First input value (16 bytes). @@ -543,7 +550,9 @@ ATCA_STATUS atcab_aes_gfm(const uint8_t* h, const uint8_t* input, uint8_t* outpu } return status; } +#endif +#if ATCAB_AES_GCM_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Initialize context for AES GCM operation with an existing IV, which * is common when starting a decrypt operation. * @@ -784,6 +793,7 @@ ATCA_STATUS atcab_aes_gcm_decrypt_finish(atca_aes_gcm_ctx_t* ctx, const uint8_t* } return status; } +#endif /* ATCAB_AES_GCM */ /* CheckMAC command */ @@ -797,6 +807,7 @@ ATCA_STATUS atcab_aes_gcm_decrypt_finish(atca_aes_gcm_ctx_t* ctx, const uint8_t* * \param[in] other_data OtherData parameter (13 bytes) * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_CHECKMAC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_checkmac(uint8_t mode, uint16_t key_id, const uint8_t* challenge, const uint8_t* response, const uint8_t* other_data) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -818,6 +829,7 @@ ATCA_STATUS atcab_checkmac(uint8_t mode, uint16_t key_id, const uint8_t* challen } return status; } +#endif /* ATCAB_CHECKMAC */ /* Counter command */ @@ -827,6 +839,7 @@ ATCA_STATUS atcab_checkmac(uint8_t mode, uint16_t key_id, const uint8_t* challen * \param[out] counter_value pointer to the counter value returned from device * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_COUNTER_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_counter(uint8_t mode, uint16_t counter_id, uint32_t* counter_value) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -909,6 +922,7 @@ ATCA_STATUS atcab_counter_read(uint16_t counter_id, uint32_t* counter_value) } return status; } +#endif /* ATCAB_COUNTER_EN */ /* DeriveKey command */ @@ -922,6 +936,7 @@ ATCA_STATUS atcab_counter_read(uint16_t counter_id, uint32_t* counter_value) * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_DERIVEKEY_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_derivekey(uint8_t mode, uint16_t key_id, const uint8_t* mac) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -943,9 +958,11 @@ ATCA_STATUS atcab_derivekey(uint8_t mode, uint16_t key_id, const uint8_t* mac) } return status; } +#endif /* ATCAB_DERIVEKEY */ /* ECDH command */ +#if ATCAB_ECDH_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Base function for generating premaster secret key using ECDH. * \param[in] mode Mode to be used for ECDH computation * \param[in] key_id Slot of key for ECDH computation @@ -1015,7 +1032,9 @@ ATCA_STATUS atcab_ecdh(uint16_t key_id, const uint8_t* public_key, uint8_t* pms) } return status; } +#endif /* ATCAB_ECDH */ +#if ATCAB_ECDH_ENC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief ECDH command with a private key in a slot and the premaster secret * is read from the next slot. * @@ -1097,7 +1116,9 @@ ATCA_STATUS atcab_ecdh_ioenc(uint16_t key_id, const uint8_t* public_key, uint8_t } return status; } +#endif /* ATCAB_ECDH_ENC_EN */ +#if CALIB_ECDH_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief ECDH command with a private key in TempKey and the premaster secret * is returned in the clear. * @@ -1130,7 +1151,9 @@ ATCA_STATUS atcab_ecdh_tempkey(const uint8_t* public_key, uint8_t* pms) } return status; } +#endif /* CALIB_ECDH */ +#if ATCAB_ECDH_ENC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief ECDH command with a private key in TempKey and the premaster secret * is returned encrypted using the IO protection key. * @@ -1164,9 +1187,11 @@ ATCA_STATUS atcab_ecdh_tempkey_ioenc(const uint8_t* public_key, uint8_t* pms, co } return status; } +#endif /* ATCAB_ECDH_ENC_EN */ /* GenDig command */ +#if ATCAB_GENDIG_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Issues a GenDig command, which performs a SHA256 hash on the source data indicated by zone with the * contents of TempKey. See the CryptoAuth datasheet for your chip to see what the values of zone * correspond to. @@ -1198,6 +1223,7 @@ ATCA_STATUS atcab_gendig(uint8_t zone, uint16_t key_id, const uint8_t* other_dat } return status; } +#endif /* ATCAB_GENDIG */ /* GenKey command */ @@ -1217,6 +1243,7 @@ ATCA_STATUS atcab_gendig(uint8_t zone, uint16_t key_id, const uint8_t* other_dat * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_GENKEY_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_genkey_base(uint8_t mode, uint16_t key_id, const uint8_t* other_data, uint8_t* public_key) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -1326,9 +1353,9 @@ ATCA_STATUS atcab_get_pubkey(uint16_t key_id, uint8_t* public_key) { return atcab_get_pubkey_ext(_gDevice, key_id, public_key); } +#endif /* CALIB_GENKEY_EN */ -// HMAC command functions - +#if ATCAB_HMAC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Issues a HMAC command, which computes an HMAC/SHA-256 digest of a * key stored in the device, a challenge, and other information on the * device. @@ -1349,8 +1376,12 @@ ATCA_STATUS atcab_hmac(uint8_t mode, uint16_t key_id, uint8_t* digest) if (atcab_is_ca_device(dev_type)) { -#if defined(ATCA_ATSHA204A_SUPPORT) || defined(ATCA_ATECC508A_SUPPORT) +#if defined(ATCA_ATSHA204A_SUPPORT) || defined(ATCA_ATECC108A_SUPPORT) || defined(ATCA_ATECC508A_SUPPORT) status = calib_hmac(_gDevice, mode, key_id, digest); +#else + ((void)mode); + ((void)key_id); + ((void)digest); #endif } else if (atcab_is_ta_device(dev_type)) @@ -1363,9 +1394,9 @@ ATCA_STATUS atcab_hmac(uint8_t mode, uint16_t key_id, uint8_t* digest) } return status; } +#endif /* ATCAB_HMAC */ -// Info command functions - +#ifdef ATCA_USE_ATCAB_FUNCTIONS /** \brief Issues an Info command, which return internal device information and * can control GPIO and the persistent latch. * @@ -1424,7 +1455,9 @@ ATCA_STATUS atcab_info(uint8_t* revision) } return status; } +#endif +#if ATCAB_INFO_LATCH_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Use the Info command to set the persistent latch state for an * ATECC608 device. * @@ -1482,9 +1515,9 @@ ATCA_STATUS atcab_info_get_latch(bool* state) } return status; } +#endif /* ATCAB_INFO_LATCH_EN */ -// KDF command functions - +#if ATCAB_KDF_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the KDF command, which derives a new key in PRF, AES, or * HKDF modes. * @@ -1531,9 +1564,9 @@ ATCA_STATUS atcab_kdf(uint8_t mode, uint16_t key_id, const uint32_t details, con } return status; } +#endif /* ATCAB_KDF */ -/* Lock commands */ - +#if ATCAB_LOCK_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief The Lock command prevents future modifications of the Configuration * and/or Data and OTP zones. If the device is so configured, then * this command can be used to lock individual data slots. This @@ -1566,7 +1599,9 @@ ATCA_STATUS atcab_lock(uint8_t mode, uint16_t summary_crc) } return status; } +#endif +#if ATCAB_LOCK_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Unconditionally (no CRC required) lock the config zone. * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -1579,16 +1614,7 @@ ATCA_STATUS atcab_lock_config_zone(void) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_lock_config_zone(_gDevice); -#endif - } - else - { - status = calib_lock_config_zone(_gDevice); - } + status = calib_lock_config_zone(_gDevice); #endif } else if (atcab_is_ta_device(dev_type)) @@ -1622,16 +1648,7 @@ ATCA_STATUS atcab_lock_config_zone_crc(uint16_t summary_crc) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = ATCA_UNIMPLEMENTED; -#endif - } - else - { - status = calib_lock_config_zone_crc(_gDevice, summary_crc); - } + status = calib_lock_config_zone_crc(_gDevice, summary_crc); #endif } else if (atcab_is_ta_device(dev_type)) @@ -1662,16 +1679,7 @@ ATCA_STATUS atcab_lock_data_zone(void) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_lock_data_zone(_gDevice); -#endif - } - else - { - status = calib_lock_data_zone(_gDevice); - } + status = calib_lock_data_zone(_gDevice); #endif } else if (atcab_is_ta_device(dev_type)) @@ -1705,16 +1713,7 @@ ATCA_STATUS atcab_lock_data_zone_crc(uint16_t summary_crc) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = ATCA_UNIMPLEMENTED; -#endif - } - else - { - status = calib_lock_data_zone_crc(_gDevice, summary_crc); - } + status = calib_lock_data_zone_crc(_gDevice, summary_crc); #endif } else if (atcab_is_ta_device(dev_type)) @@ -1746,16 +1745,7 @@ ATCA_STATUS atcab_lock_data_slot(uint16_t slot) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_lock_data_slot(_gDevice, slot); -#endif - } - else - { - status = calib_lock_data_slot(_gDevice, slot); - } + status = calib_lock_data_slot(_gDevice, slot); #endif } else if (atcab_is_ta_device(dev_type)) @@ -1770,6 +1760,7 @@ ATCA_STATUS atcab_lock_data_slot(uint16_t slot) } return status; } +#endif /* ATCAB_LOCK_EN */ // MAC command functions @@ -1786,6 +1777,7 @@ ATCA_STATUS atcab_lock_data_slot(uint16_t slot) * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_MAC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_mac(uint8_t mode, uint16_t key_id, const uint8_t* challenge, uint8_t* digest) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -1807,6 +1799,7 @@ ATCA_STATUS atcab_mac(uint8_t mode, uint16_t key_id, const uint8_t* challenge, u } return status; } +#endif /* ATCAB_MAC_EN */ // Nonce command functions @@ -1828,6 +1821,7 @@ ATCA_STATUS atcab_mac(uint8_t mode, uint16_t key_id, const uint8_t* challenge, u * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_NONCE_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_nonce_base(uint8_t mode, uint16_t zero, const uint8_t* num_in, uint8_t* rand_out) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -2012,9 +2006,11 @@ ATCA_STATUS atcab_challenge_seed_update(const uint8_t* num_in, uint8_t* rand_out } return status; } +#endif /* ATCAB_NONCE_EN */ // PrivWrite command functions +#if ATCAB_PRIVWRITE_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes PrivWrite command, to write externally generated ECC * private keys into the device. * @@ -2058,6 +2054,7 @@ ATCA_STATUS atcab_priv_write(uint16_t key_id, const uint8_t priv_key[36], uint16 } return status; } +#endif /* ATCAB_PRIVWRITE_EN */ // Random command functions @@ -2069,6 +2066,7 @@ ATCA_STATUS atcab_priv_write(uint16_t key_id, const uint8_t priv_key[36], uint16 * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_RANDOM_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_random_ext(ATCADevice device, uint8_t* rand_out) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -2093,7 +2091,6 @@ ATCA_STATUS atcab_random_ext(ATCADevice device, uint8_t* rand_out) return status; } - /** \brief Executes Random command, which generates a 32 byte random number * from the device. * @@ -2105,6 +2102,7 @@ ATCA_STATUS atcab_random(uint8_t* rand_out) { return atcab_random_ext(_gDevice, rand_out); } +#endif /* ATCAB_RANDOM_EN */ // Read command functions @@ -2125,6 +2123,7 @@ ATCA_STATUS atcab_random(uint8_t* rand_out) * * returns ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_READ_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_read_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint8_t* data, uint8_t len) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -2133,16 +2132,7 @@ ATCA_STATUS atcab_read_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_read_zone(_gDevice, zone, slot, block, offset, data, len); -#endif - } - else - { - status = calib_read_zone(_gDevice, zone, slot, block, offset, data, len); - } + status = calib_read_zone_ext(_gDevice, zone, slot, block, offset, data, len); #endif } else if (atcab_is_ta_device(dev_type)) @@ -2155,7 +2145,9 @@ ATCA_STATUS atcab_read_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t } return status; } +#endif /* ATCAB_READ_EN */ +#ifdef ATCA_USE_ATCAB_FUNCTIONS /** \brief Executes Read command, which reads the configuration zone to see if * the specified zone is locked. * @@ -2172,16 +2164,7 @@ ATCA_STATUS atcab_is_locked(uint8_t zone, bool* is_locked) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_is_locked(_gDevice, zone, is_locked); -#endif - } - else - { - status = calib_is_locked(_gDevice, zone, is_locked); - } + status = calib_is_locked_ext(_gDevice, zone, is_locked); #endif } else if (atcab_is_ta_device(dev_type)) @@ -2221,16 +2204,7 @@ ATCA_STATUS atcab_is_config_locked(bool* is_locked) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_is_locked(_gDevice, ATCA_ZONE_CONFIG, is_locked); -#endif - } - else - { - status = calib_is_locked(_gDevice, LOCK_ZONE_CONFIG, is_locked); - } + status = calib_is_locked_ext(_gDevice, LOCK_ZONE_CONFIG, is_locked); #endif } else if (atcab_is_ta_device(dev_type)) @@ -2245,7 +2219,9 @@ ATCA_STATUS atcab_is_config_locked(bool* is_locked) } return status; } +#endif +#if ATCAB_READ_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief This function check whether data/setup zone is locked or not * * \param[out] is_locked Lock state returned here. True if locked. @@ -2259,16 +2235,7 @@ ATCA_STATUS atcab_is_data_locked(bool* is_locked) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_is_locked(_gDevice, ATCA_ZONE_DATA, is_locked); -#endif - } - else - { - status = calib_is_locked(_gDevice, LOCK_ZONE_DATA, is_locked); - } + status = calib_is_locked_ext(_gDevice, LOCK_ZONE_DATA, is_locked); #endif } else if (atcab_is_ta_device(dev_type)) @@ -2354,47 +2321,25 @@ ATCA_STATUS atcab_is_private(uint16_t slot, bool* is_private) { return atcab_is_private_ext(_gDevice, slot, is_private); } +#endif -/** \brief Used to read an arbitrary number of bytes from any zone configured - * for clear reads. - * - * This function will issue the Read command as many times as is required to - * read the requested data. - * - * \param[in] zone Zone to read data from. Option are ATCA_ZONE_CONFIG(0), - * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). - * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). - * Ignored for all other zones. - * \param[in] offset Byte offset within the zone to read from. - * \param[out] data Read data is returned here. - * \param[in] length Number of bytes to read starting from the offset. - * - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, uint8_t* data, size_t length) + +#if ATCAB_READ_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) +ATCA_STATUS atcab_read_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t* data, size_t length) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; - ATCADeviceType dev_type = atcab_get_device_type(); + ATCADeviceType dev_type = atcab_get_device_type_ext(device); if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_read_bytes_zone(_gDevice, zone, slot, offset, data, length); -#endif - } - else - { - status = calib_read_bytes_zone(_gDevice, zone, slot, offset, data, length); - } + status = calib_read_bytes_zone_ext(device, zone, slot, offset, data, length); #endif } else if (atcab_is_ta_device(dev_type)) { #if ATCA_TA_SUPPORT - status = talib_read_bytes_zone(_gDevice, zone, slot, offset, data, length); + status = talib_read_bytes_zone(device, zone, slot, offset, data, length); #endif } else @@ -2404,6 +2349,27 @@ ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, ui return status; } +/** \brief Used to read an arbitrary number of bytes from any zone configured + * for clear reads. + * + * This function will issue the Read command as many times as is required to + * read the requested data. + * + * \param[in] zone Zone to read data from. Option are ATCA_ZONE_CONFIG(0), + * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). + * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). + * Ignored for all other zones. + * \param[in] offset Byte offset within the zone to read from. + * \param[out] data Read data is returned here. + * \param[in] length Number of bytes to read starting from the offset. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, uint8_t* data, size_t length) +{ + return atcab_read_bytes_zone_ext(_gDevice, zone, slot, offset, data, length); +} + /** \brief This function returns serial number of the device. * * \param[out] serial_number 9 byte serial number is returned here. @@ -2418,16 +2384,7 @@ ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_read_serial_number(_gDevice, serial_number); -#endif - } - else - { - status = calib_read_serial_number(_gDevice, serial_number); - } + status = calib_read_serial_number_ext(_gDevice, serial_number); #endif } else if (atcab_is_ta_device(dev_type)) @@ -2442,7 +2399,9 @@ ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number) } return status; } +#endif +#if ATCAB_READ_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes Read command to read an ECC P256 public key from a slot * configured for clear reads. * @@ -2534,7 +2493,9 @@ ATCA_STATUS atcab_read_sig(uint16_t slot, uint8_t* sig) } return status; } +#endif +#if ATCAB_READ_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes Read command to read the complete device configuration * zone. * @@ -2552,16 +2513,7 @@ ATCA_STATUS atcab_read_config_zone(uint8_t* config_data) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_read_config_zone(_gDevice, config_data); -#endif - } - else - { - status = calib_read_config_zone(_gDevice, config_data); - } + status = calib_read_config_zone(_gDevice, config_data); #endif } else if (atcab_is_ta_device(dev_type)) @@ -2599,16 +2551,7 @@ ATCA_STATUS atcab_cmp_config_zone(uint8_t* config_data, bool* same_config) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_cmp_config_zone(_gDevice, config_data, same_config); -#endif - } - else - { - status = calib_cmp_config_zone(_gDevice, config_data, same_config); - } + status = calib_cmp_config_zone(_gDevice, config_data, same_config); #endif } else if (atcab_is_ta_device(dev_type)) @@ -2623,7 +2566,9 @@ ATCA_STATUS atcab_cmp_config_zone(uint8_t* config_data, bool* same_config) } return status; } +#endif /* ATCAB_READ_EN */ +#if ATCAB_READ_ENC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes Read command on a slot configured for encrypted reads and * decrypts the data to return it as plaintext. * @@ -2669,6 +2614,7 @@ ATCA_STATUS atcab_read_enc(uint16_t key_id, uint8_t block, uint8_t* data, const } return status; } +#endif /* ATCAB_READ_ENC_EN */ // SecureBoot command functions @@ -2686,6 +2632,7 @@ ATCA_STATUS atcab_read_enc(uint16_t key_id, uint8_t block, uint8_t* data, const * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_SECUREBOOT_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_secureboot(uint8_t mode, uint16_t param2, const uint8_t* digest, const uint8_t* signature, uint8_t* mac) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -2707,7 +2654,9 @@ ATCA_STATUS atcab_secureboot(uint8_t mode, uint16_t param2, const uint8_t* diges } return status; } +#endif /* ATCAB_SECUREBOOT_EN */ +#if ATCAB_SECUREBOOT_MAC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes Secure Boot command with encrypted digest and validated * MAC response using the IO protection key. * @@ -2744,9 +2693,9 @@ ATCA_STATUS atcab_secureboot_mac(uint8_t mode, const uint8_t* digest, const uint } return status; } +#endif /* ATCAB_SECUREBOOT_MAC_EN */ -/* SelfTest Command */ - +#if ATCAB_SELFTEST_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the SelfTest command, which performs a test of one or more * of the cryptographic engines within the ATECC608 chip. * @@ -2781,9 +2730,9 @@ ATCA_STATUS atcab_selftest(uint8_t mode, uint16_t param2, uint8_t* result) } return status; } +#endif /* ATCAB_SELFTEST_EN */ -/* SHA Command */ - +#if ATCAB_SHA_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes SHA command, which computes a SHA-256 or HMAC/SHA-256 * digest for general purpose use by the host system. * @@ -2923,7 +2872,9 @@ ATCA_STATUS atcab_sha_end(uint8_t* digest, uint16_t length, const uint8_t* messa } return status; } +#endif /* ATCAB_SHA_EN */ +#if ATCAB_SHA_CONTEXT_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes SHA command to read the SHA-256 context back. Only for * ATECC608 with SHA-256 contexts. HMAC not supported. * @@ -2989,7 +2940,9 @@ ATCA_STATUS atcab_sha_write_context(const uint8_t* context, uint16_t context_siz } return status; } +#endif /* ATCAB_SHA_CONTEXT_EN */ +#if ATCAB_SHA_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Use the SHA command to compute a SHA-256 digest. * * \param[in] length Size of message parameter in bytes. @@ -3143,7 +3096,9 @@ ATCA_STATUS atcab_hw_sha2_256_finish(atca_sha256_ctx_t* ctx, uint8_t* digest) } return status; } +#endif /* ATCAB_SHA_EN */ +#if ATCAB_SHA_HMAC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes SHA command to start an HMAC/SHA-256 operation * * \param[in] ctx HMAC/SHA-256 context @@ -3238,8 +3193,6 @@ ATCA_STATUS atcab_sha_hmac_finish(atca_hmac_sha256_ctx_t* ctx, uint8_t* digest, return status; } - - /** \brief Use the SHA command to compute an HMAC/SHA-256 operation. * * \param[in] device Device context pointer @@ -3297,10 +3250,9 @@ ATCA_STATUS atcab_sha_hmac(const uint8_t* data, size_t data_size, uint16_t key_s { return atcab_sha_hmac_ext(_gDevice, data, data_size, key_slot, digest, target); } +#endif /* ATCAB_SHA_HMAC_EN */ - -/* Sign command */ - +#if ATCAB_SIGN_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Sign command, which generates a signature using the * ECDSA algorithm. * @@ -3358,17 +3310,8 @@ ATCA_STATUS atcab_sign_ext(ATCADevice device, uint16_t key_id, const uint8_t* ms if (atcab_is_ca_device(dev_type)) { -#ifdef ATCA_ECC_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_sign(device, key_id, msg, signature); -#endif - } - else - { - status = calib_sign(device, key_id, msg, signature); - } +#if ATCA_ECC_SUPPORT + status = calib_sign_ext(device, key_id, msg, signature); #endif } else if (atcab_is_ta_device(dev_type)) @@ -3403,7 +3346,9 @@ ATCA_STATUS atcab_sign(uint16_t key_id, const uint8_t* msg, uint8_t* signature) { return atcab_sign_ext(_gDevice, key_id, msg, signature); } +#endif +#if ATCAB_SIGN_INTERNAL_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes Sign command to sign an internally generated message. * * \param[in] key_id Slot of the private key to be used to sign the @@ -3440,6 +3385,7 @@ ATCA_STATUS atcab_sign_internal(uint16_t key_id, bool is_invalidate, bool is_ful } return status; } +#endif /* ATCAB_SIGN_INTERNAL_EN */ /* UpdateExtra command */ @@ -3455,6 +3401,7 @@ ATCA_STATUS atcab_sign_internal(uint16_t key_id, bool is_invalidate, bool is_ful * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_UPDATEEXTRA_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_updateextra(uint8_t mode, uint16_t new_value) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -3476,9 +3423,9 @@ ATCA_STATUS atcab_updateextra(uint8_t mode, uint16_t new_value) } return status; } +#endif /* ATCAB_UPDATEEXTRA_EN */ -/* Verify command */ - +#if ATCAB_VERIFY_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Verify command, which takes an ECDSA [R,S] signature * and verifies that it is correctly generated from a given message and * public key. In all cases, the signature is an input to the command. @@ -3530,7 +3477,9 @@ ATCA_STATUS atcab_verify(uint8_t mode, uint16_t key_id, const uint8_t* signature } return status; } +#endif /* ATCAB_VERIFY */ +#if ATCAB_VERIFY_EXTERN_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Verify command, which verifies a signature (ECDSA * verify operation) with all components (message, signature, and * public key) supplied. The message to be signed will be loaded into @@ -3598,7 +3547,9 @@ ATCA_STATUS atcab_verify_extern(const uint8_t* message, const uint8_t* signature { return atcab_verify_extern_ext(_gDevice, message, signature, public_key, is_verified); } +#endif /* ATCAB_VERIFY_EXTERN */ +#if ATCAB_VERIFY_EXTERN_STORED_MAC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Verify command with verification MAC, which verifies a * signature (ECDSA verify operation) with all components (message, * signature, and public key) supplied. This function is only available @@ -3641,7 +3592,9 @@ ATCA_STATUS atcab_verify_extern_mac(const uint8_t* message, const uint8_t* signa } return status; } +#endif /* ATCAB_VERIFY_EXTERN_STORED_MAC_EN */ +#if ATCAB_VERIFY_STORED_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Verify command, which verifies a signature (ECDSA * verify operation) with a public key stored in the device. The * message to be signed will be loaded into the Message Digest Buffer @@ -3706,6 +3659,45 @@ ATCA_STATUS atcab_verify_stored(const uint8_t* message, const uint8_t* signature return atcab_verify_stored_ext(_gDevice, message, signature, key_id, is_verified); } +/** \brief Executes the Verify command, which verifies a signature (ECDSA + * verify operation) with a public key stored in the device. + * keyConfig.reqrandom bit should be set and the message to be signed + * should be already loaded into TempKey for all devices. + * + * Please refer to TEST(atca_cmd_basic_test, verify_stored_on_reqrandom_set) in + * atca_tests_verify.c for proper use of this api + * + * \param[in] device Device context pointer + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] key_id Slot containing the public key to be used in the + * verification. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS atcab_verify_stored_with_tempkey(const uint8_t* signature, uint16_t key_id, bool* is_verified) +{ + ATCA_STATUS status = ATCA_UNIMPLEMENTED; + ATCADeviceType dev_type = atcab_get_device_type(); + + if (atcab_is_ca_device(dev_type)) + { +#ifdef ATCA_ECC_SUPPORT + status = calib_verify_stored_with_tempkey(_gDevice, signature, key_id, is_verified); +#endif + } + else + { + status = ATCA_NOT_INITIALIZED; + } + return status; +} +#endif /* ATCAB_VERIFY_STORED_EN */ + +#if ATCAB_VERIFY_EXTERN_STORED_MAC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Verify command with verification MAC, which verifies a * signature (ECDSA verify operation) with a public key stored in the * device. This function is only available on the ATECC608. @@ -3746,7 +3738,9 @@ ATCA_STATUS atcab_verify_stored_mac(const uint8_t* message, const uint8_t* signa } return status; } +#endif /* ATCAB_VERIFY_EXTERN_STORED_MAC_EN */ +#if ATCAB_VERIFY_VALIDATE_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Verify command in Validate mode to validate a public * key stored in a slot. * @@ -3785,7 +3779,9 @@ ATCA_STATUS atcab_verify_validate(uint16_t key_id, const uint8_t* signature, con } return status; } +#endif /*ATCAB_VERIFY_VALIDATE */ +#if ATCAB_VERIFY_VALIDATE_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Verify command in Invalidate mode which invalidates a * previously validated public key stored in a slot. * @@ -3824,9 +3820,9 @@ ATCA_STATUS atcab_verify_invalidate(uint16_t key_id, const uint8_t* signature, c } return status; } +#endif /* ATCAB_VERIFY_INVALIDATE */ -/* Write command functions */ - +#if ATCAB_WRITE_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** * \brief Executes the Write command, which writes either one four byte word or * a 32-byte block to one of the EEPROM zones on the device. Depending @@ -3853,16 +3849,7 @@ ATCA_STATUS atcab_write(uint8_t zone, uint16_t address, const uint8_t* value, co if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_write(_gDevice, zone, address, value, mac); -#endif - } - else - { - status = calib_write(_gDevice, zone, address, value, mac); - } + status = calib_write_ext(_gDevice, zone, address, value, mac); #endif } else if (atcab_is_ta_device(dev_type)) @@ -3898,16 +3885,7 @@ ATCA_STATUS atcab_write_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_write_zone(_gDevice, zone, slot, block, offset, data, len); -#endif - } - else - { - status = calib_write_zone(_gDevice, zone, slot, block, offset, data, len); - } + status = calib_write_zone_ext(_gDevice, zone, slot, block, offset, data, len); #endif } else if (atcab_is_ta_device(dev_type)) @@ -3923,6 +3901,30 @@ ATCA_STATUS atcab_write_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t return status; } +ATCA_STATUS atcab_write_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t* data, size_t length) +{ + ATCA_STATUS status = ATCA_UNIMPLEMENTED; + ATCADeviceType dev_type = atcab_get_device_type_ext(device); + + if (atcab_is_ca_device(dev_type)) + { +#if ATCA_CA_SUPPORT + status = calib_write_bytes_zone_ext(device, zone, slot, offset_bytes, data, length); +#endif + } + else if (atcab_is_ta_device(dev_type)) + { +#if ATCA_TA_SUPPORT + status = talib_write_bytes_zone(device, zone, slot, offset_bytes, data, length); +#endif + } + else + { + status = ATCA_NOT_INITIALIZED; + } + return status; +} + /** \brief Executes the Write command, which writes data into the * configuration, otp, or data zones with a given byte offset and * length. Offset and length must be multiples of a word (4 bytes). @@ -3945,35 +3947,7 @@ ATCA_STATUS atcab_write_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t */ ATCA_STATUS atcab_write_bytes_zone(uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t* data, size_t length) { - ATCA_STATUS status = ATCA_UNIMPLEMENTED; - ATCADeviceType dev_type = atcab_get_device_type(); - - if (atcab_is_ca_device(dev_type)) - { -#if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_write_bytes_zone(_gDevice, zone, slot, offset_bytes, data, length); -#endif - } - else - { - status = calib_write_bytes_zone(_gDevice, zone, slot, offset_bytes, data, length); - } -#endif - } - else if (atcab_is_ta_device(dev_type)) - { -#if ATCA_TA_SUPPORT - status = talib_write_bytes_zone(_gDevice, zone, slot, offset_bytes, data, length); -#endif - } - else - { - status = ATCA_NOT_INITIALIZED; - } - return status; + return atcab_write_bytes_zone_ext(_gDevice, zone, slot, offset_bytes, data, length); } /** \brief Uses the write command to write a public key to a slot in the @@ -4034,16 +4008,7 @@ ATCA_STATUS atcab_write_config_zone(const uint8_t* config_data) if (atcab_is_ca_device(dev_type)) { #if ATCA_CA_SUPPORT - if (ECC204 == dev_type) - { -#if defined(ATCA_ECC204_SUPPORT) - status = calib_ecc204_write_config_zone(_gDevice, config_data); -#endif - } - else - { - status = calib_write_config_zone(_gDevice, config_data); - } + status = calib_write_config_zone_ext(_gDevice, config_data); #endif } else if (atcab_is_ta_device(dev_type)) @@ -4058,7 +4023,9 @@ ATCA_STATUS atcab_write_config_zone(const uint8_t* config_data) } return status; } +#endif /* ATCAB_WRITE_EN*/ +#if ATCAB_WRITE_ENC_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) /** \brief Executes the Write command, which performs an encrypted write of * a 32 byte block into given slot. * @@ -4104,6 +4071,7 @@ ATCA_STATUS atcab_write_enc(uint16_t key_id, uint8_t block, const uint8_t* data, } return status; } +#endif /* ATCAB_WRITE_ENC */ /** \brief Initialize one of the monotonic counters in device with a specific * value. @@ -4117,6 +4085,7 @@ ATCA_STATUS atcab_write_enc(uint16_t key_id, uint8_t block, const uint8_t* data, * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAB_WRITE_EN && defined(ATCA_USE_ATCAB_FUNCTIONS) ATCA_STATUS atcab_write_config_counter(uint16_t counter_id, uint32_t counter_value) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; @@ -4138,5 +4107,4 @@ ATCA_STATUS atcab_write_config_counter(uint16_t counter_id, uint32_t counter_val } return status; } - -#endif +#endif /* ATCAB_WRITE_CONFIG_BYTES_ZONE */ diff --git a/lib/atca_basic.h b/lib/atca_basic.h index 88911d610..9472434f0 100644 --- a/lib/atca_basic.h +++ b/lib/atca_basic.h @@ -66,382 +66,14 @@ bool atcab_is_ta_device(ATCADeviceType dev_type); #define atca_execute_command(...) calib_execute_command(__VA_ARGS__) -// AES Mode functions +/* Extra AES Block Mode Support */ #include "crypto/atca_crypto_hw_aes.h" -ATCA_STATUS atcab_aes_cbc_init_ext(ATCADevice device, atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv); -ATCA_STATUS atcab_aes_cbc_init(atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv); -ATCA_STATUS atcab_aes_cbc_encrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext); -ATCA_STATUS atcab_aes_cbc_decrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext); - -ATCA_STATUS atcab_aes_cbcmac_init_ext(ATCADevice device, atca_aes_cbcmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); -ATCA_STATUS atcab_aes_cbcmac_init(atca_aes_cbcmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); -ATCA_STATUS atcab_aes_cbcmac_update(atca_aes_cbcmac_ctx_t* ctx, const uint8_t* data, uint32_t data_size); -ATCA_STATUS atcab_aes_cbcmac_finish(atca_aes_cbcmac_ctx_t* ctx, uint8_t* mac, uint32_t mac_size); - -ATCA_STATUS atcab_aes_cmac_init_ext(ATCADevice device, atca_aes_cmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); -ATCA_STATUS atcab_aes_cmac_init(atca_aes_cmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); -ATCA_STATUS atcab_aes_cmac_update(atca_aes_cmac_ctx_t* ctx, const uint8_t* data, uint32_t data_size); -ATCA_STATUS atcab_aes_cmac_finish(atca_aes_cmac_ctx_t* ctx, uint8_t* cmac, uint32_t cmac_size); - -ATCA_STATUS atcab_aes_ctr_init_ext(ATCADevice device, atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, const uint8_t* iv); -ATCA_STATUS atcab_aes_ctr_init(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, const uint8_t* iv); -ATCA_STATUS atcab_aes_ctr_init_rand_ext(ATCADevice device, atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, uint8_t* iv); -ATCA_STATUS atcab_aes_ctr_init_rand(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, uint8_t* iv); -ATCA_STATUS atcab_aes_ctr_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* input, uint8_t* output); -ATCA_STATUS atcab_aes_ctr_encrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext); -ATCA_STATUS atcab_aes_ctr_decrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext); -ATCA_STATUS atcab_aes_ctr_increment(atca_aes_ctr_ctx_t* ctx); - -ATCA_STATUS atcab_aes_ccm_init_ext(ATCADevice device, atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); -ATCA_STATUS atcab_aes_ccm_init(atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); -ATCA_STATUS atcab_aes_ccm_init_rand_ext(ATCADevice device, atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); -ATCA_STATUS atcab_aes_ccm_init_rand(atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); -ATCA_STATUS atcab_aes_ccm_aad_update(atca_aes_ccm_ctx_t* ctx, const uint8_t* aad, size_t aad_size); -ATCA_STATUS atcab_aes_ccm_aad_finish(atca_aes_ccm_ctx_t* ctx); -ATCA_STATUS atcab_aes_ccm_encrypt_update(atca_aes_ccm_ctx_t* ctx, const uint8_t* plaintext, uint32_t plaintext_size, uint8_t* ciphertext); -ATCA_STATUS atcab_aes_ccm_decrypt_update(atca_aes_ccm_ctx_t* ctx, const uint8_t* ciphertext, uint32_t ciphertext_size, uint8_t* plaintext); -ATCA_STATUS atcab_aes_ccm_encrypt_finish(atca_aes_ccm_ctx_t* ctx, uint8_t* tag, uint8_t* tag_size); -ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* tag, bool* is_verified); // Hardware Accelerated algorithms ATCA_STATUS atcab_pbkdf2_sha256_ext(ATCADevice device, const uint32_t iter, const uint16_t slot, const uint8_t* salt, const size_t salt_len, uint8_t* result, size_t result_len); ATCA_STATUS atcab_pbkdf2_sha256(const uint32_t iter, const uint16_t slot, const uint8_t* salt, const size_t salt_len, uint8_t* result, size_t result_len); - -#if ATCA_CA_SUPPORT && !ATCA_TA_SUPPORT && !defined(ATCA_USE_ATCAB_FUNCTIONS) && !defined(ATCA_ECC204_SUPPORT) - -#define atcab_wakeup() calib_wakeup(_gDevice) -#define atcab_idle() calib_idle(_gDevice) -#define atcab_sleep() calib_sleep(_gDevice) -#define _atcab_exit(...) _calib_exit(_gDevice, __VA_ARGS__) -#define atcab_get_zone_size(...) calib_get_zone_size(_gDevice, __VA_ARGS__) - - -// AES command functions -#define atcab_aes(...) calib_aes(_gDevice, __VA_ARGS__) -#define atcab_aes_encrypt(...) calib_aes_encrypt(_gDevice, __VA_ARGS__) -#define atcab_aes_encrypt_ext calib_aes_encrypt -#define atcab_aes_decrypt(...) calib_aes_decrypt(_gDevice, __VA_ARGS__) -#define atcab_aes_decrypt_ext calib_aes_decrypt -#define atcab_aes_gfm(...) calib_aes_gfm(_gDevice, __VA_ARGS__) - -#define atcab_aes_gcm_init(...) calib_aes_gcm_init(_gDevice, __VA_ARGS__) -#define atcab_aes_gcm_init_rand(...) calib_aes_gcm_init_rand(_gDevice, __VA_ARGS__) -#define atcab_aes_gcm_aad_update(...) calib_aes_gcm_aad_update(_gDevice, __VA_ARGS__) -#define atcab_aes_gcm_encrypt_update(...) calib_aes_gcm_encrypt_update(_gDevice, __VA_ARGS__) -#define atcab_aes_gcm_encrypt_finish(...) calib_aes_gcm_encrypt_finish(_gDevice, __VA_ARGS__) -#define atcab_aes_gcm_decrypt_update(...) calib_aes_gcm_decrypt_update(_gDevice, __VA_ARGS__) -#define atcab_aes_gcm_decrypt_finish(...) calib_aes_gcm_decrypt_finish(_gDevice, __VA_ARGS__) - -// CheckMAC command functions -#define atcab_checkmac(...) calib_checkmac(_gDevice, __VA_ARGS__) - -// Counter command functions -#define atcab_counter(...) calib_counter(_gDevice, __VA_ARGS__) -#define atcab_counter_increment(...) calib_counter_increment(_gDevice, __VA_ARGS__) -#define atcab_counter_read(...) calib_counter_read(_gDevice, __VA_ARGS__) - -// DeriveKey command functions -#define atcab_derivekey(...) calib_derivekey(_gDevice, __VA_ARGS__) - -// ECDH command functions -#define atcab_ecdh_base(...) calib_ecdh_base(_gDevice, __VA_ARGS__) -#define atcab_ecdh(...) calib_ecdh(_gDevice, __VA_ARGS__) -#define atcab_ecdh_enc(...) calib_ecdh_enc(_gDevice, __VA_ARGS__) -#define atcab_ecdh_ioenc(...) calib_ecdh_ioenc(_gDevice, __VA_ARGS__) -#define atcab_ecdh_tempkey(...) calib_ecdh_tempkey(_gDevice, __VA_ARGS__) -#define atcab_ecdh_tempkey_ioenc(...) calib_ecdh_tempkey_ioenc(_gDevice, __VA_ARGS__) - -// GenDig command functions -#define atcab_gendig(...) calib_gendig(_gDevice, __VA_ARGS__) - -// GenKey command functions -#define atcab_genkey_base(...) calib_genkey_base(_gDevice, __VA_ARGS__) -#define atcab_genkey(...) calib_genkey(_gDevice, __VA_ARGS__) -#define atcab_get_pubkey(...) calib_get_pubkey(_gDevice, __VA_ARGS__) -#define atcab_get_pubkey_ext calib_get_pubkey - -// HMAC command functions -#define atcab_hmac(...) calib_hmac(_gDevice, __VA_ARGS__) - -// Info command functions -#define atcab_info_base(...) calib_info_base(_gDevice, __VA_ARGS__) -#define atcab_info(...) calib_info(_gDevice, __VA_ARGS__) -#define atcab_info_get_latch(...) calib_info_get_latch(_gDevice, __VA_ARGS__) -#define atcab_info_set_latch(...) calib_info_set_latch(_gDevice, __VA_ARGS__) - -// KDF command functions -#define atcab_kdf(...) calib_kdf(_gDevice, __VA_ARGS__) - -// Lock command functions -#define atcab_lock(...) calib_lock(_gDevice, __VA_ARGS__) -#define atcab_lock_config_zone() calib_lock_config_zone(_gDevice) -#define atcab_lock_config_zone_crc(...) calib_lock_config_zone_crc(_gDevice, __VA_ARGS__) -#define atcab_lock_data_zone() calib_lock_data_zone(_gDevice) -#define atcab_lock_data_zone_crc(...) calib_lock_data_zone_crc(_gDevice, __VA_ARGS__) -#define atcab_lock_data_slot(...) calib_lock_data_slot(_gDevice, __VA_ARGS__) - -// MAC command functions -#define atcab_mac(...) calib_mac(_gDevice, __VA_ARGS__) - -// Nonce command functions -#define atcab_nonce_base(...) calib_nonce_base(_gDevice, __VA_ARGS__) -#define atcab_nonce(...) calib_nonce(_gDevice, __VA_ARGS__) -#define atcab_nonce_load(...) calib_nonce_load(_gDevice, __VA_ARGS__) -#define atcab_nonce_rand(...) calib_nonce_rand(_gDevice, __VA_ARGS__) -#define atcab_challenge(...) calib_challenge(_gDevice, __VA_ARGS__) -#define atcab_challenge_seed_update(...) calib_challenge_seed_update(_gDevice, __VA_ARGS__) - -// PrivWrite command functions -#define atcab_priv_write(...) calib_priv_write(_gDevice, __VA_ARGS__) - - -// Random command functions -#define atcab_random(...) calib_random(_gDevice, __VA_ARGS__) -#define atcab_random_ext calib_random - -// Read command functions -#define atcab_read_zone(...) calib_read_zone(_gDevice, __VA_ARGS__) -#define atcab_is_locked(...) calib_is_locked(_gDevice, __VA_ARGS__) -#define atcab_is_config_locked(...) calib_is_locked(_gDevice, LOCK_ZONE_CONFIG, __VA_ARGS__) -#define atcab_is_data_locked(...) calib_is_locked(_gDevice, LOCK_ZONE_DATA, __VA_ARGS__) -#define atcab_is_slot_locked(...) calib_is_slot_locked(_gDevice, __VA_ARGS__) -#define atcab_is_private(...) calib_is_private(_gDevice, __VA_ARGS__) -#define atcab_is_private_ext calib_is_private -#define atcab_read_bytes_zone(...) calib_read_bytes_zone(_gDevice, __VA_ARGS__) -#define atcab_read_serial_number(...) calib_read_serial_number(_gDevice, __VA_ARGS__) -#define atcab_read_pubkey(...) calib_read_pubkey(_gDevice, __VA_ARGS__) -#define atcab_read_pubkey_ext calib_read_pubkey -#define atcab_read_sig(...) calib_read_sig(_gDevice, __VA_ARGS__) -#define atcab_read_config_zone(...) calib_read_config_zone(_gDevice, __VA_ARGS__) -#define atcab_cmp_config_zone(...) calib_cmp_config_zone(_gDevice, __VA_ARGS__) -#define atcab_read_enc(...) calib_read_enc(_gDevice, __VA_ARGS__) - - -// SecureBoot command functions -#define atcab_secureboot(...) calib_secureboot(_gDevice, __VA_ARGS__) -#define atcab_secureboot_mac(...) calib_secureboot_mac(_gDevice, __VA_ARGS__) - -// SelfTest command functions -#define atcab_selftest(...) calib_selftest(_gDevice, __VA_ARGS__) - -// SHA command functions -#define atcab_sha_base(...) calib_sha_base(_gDevice, __VA_ARGS__) -#define atcab_sha_start() calib_sha_start(_gDevice) -#define atcab_sha_update(...) calib_sha_update(_gDevice, __VA_ARGS__) -#define atcab_sha_end(...) calib_sha_end(_gDevice, __VA_ARGS__) -#define atcab_sha_read_context(...) calib_sha_read_context(_gDevice, __VA_ARGS__) -#define atcab_sha_write_context(...) calib_sha_write_context(_gDevice, __VA_ARGS__) -#define atcab_sha(...) calib_sha(_gDevice, __VA_ARGS__) -#define atcab_hw_sha2_256(...) calib_hw_sha2_256(_gDevice, __VA_ARGS__) -#define atcab_hw_sha2_256_init(...) calib_hw_sha2_256_init(_gDevice, __VA_ARGS__) -#define atcab_hw_sha2_256_update(...) calib_hw_sha2_256_update(_gDevice, __VA_ARGS__) -#define atcab_hw_sha2_256_finish(...) calib_hw_sha2_256_finish(_gDevice, __VA_ARGS__) -#define atcab_sha_hmac_init(...) calib_sha_hmac_init(_gDevice, __VA_ARGS__) -#define atcab_sha_hmac_update(...) calib_sha_hmac_update(_gDevice, __VA_ARGS__) -#define atcab_sha_hmac_finish(...) calib_sha_hmac_finish(_gDevice, __VA_ARGS__) -#define atcab_sha_hmac(...) calib_sha_hmac(_gDevice, __VA_ARGS__) -#define atcab_sha_hmac_ext calib_sha_hmac -#define SHA_CONTEXT_MAX_SIZE (99) - -// Sign command functions -#define atcab_sign_base(...) calib_sign_base(_gDevice, __VA_ARGS__) -#define atcab_sign(...) calib_sign(_gDevice, __VA_ARGS__) -#define atcab_sign_ext calib_sign -#define atcab_sign_internal(...) calib_sign_internal(_gDevice, __VA_ARGS__) - -// UpdateExtra command functions -#define atcab_updateextra(...) calib_updateextra(_gDevice, __VA_ARGS__) - -// Verify command functions -#define atcab_verify(...) calib_verify(_gDevice, __VA_ARGS__) -#define atcab_verify_extern(...) calib_verify_extern(_gDevice, __VA_ARGS__) -#define atcab_verify_extern_ext calib_verify_extern -#define atcab_verify_extern_mac(...) calib_verify_extern_mac(_gDevice, __VA_ARGS__) -#define atcab_verify_stored(...) calib_verify_stored(_gDevice, __VA_ARGS__) -#define atcab_verify_stored_ext calib_verify_stored -#define atcab_verify_stored_mac(...) calib_verify_stored_mac(_gDevice, __VA_ARGS__) -#define atcab_verify_validate(...) calib_verify_validate(_gDevice, __VA_ARGS__) -#define atcab_verify_invalidate(...) calib_verify_invalidate(_gDevice, __VA_ARGS__) - -// Write command functions -#define atcab_write(...) calib_write(_gDevice, __VA_ARGS__) -#define atcab_write_zone(...) calib_write_zone(_gDevice, __VA_ARGS__) -#define atcab_write_bytes_zone(...) calib_write_bytes_zone(_gDevice, __VA_ARGS__) -#define atcab_write_pubkey(...) calib_write_pubkey(_gDevice, __VA_ARGS__) -#define atcab_write_config_zone(...) calib_write_config_zone(_gDevice, __VA_ARGS__) -#define atcab_write_enc(...) calib_write_enc(_gDevice, __VA_ARGS__) -#define atcab_write_config_counter(...) calib_write_config_counter(_gDevice, __VA_ARGS__) - -#elif ATCA_TA_SUPPORT && !ATCA_CA_SUPPORT && !defined(ATCA_USE_ATCAB_FUNCTIONS) - -#define atcab_wakeup(...) (0) -#define atcab_idle(...) (0) -#define atcab_sleep(...) (0) -#define _atcab_exit(...) (1) -#define atcab_get_zone_size(...) talib_get_zone_size(_gDevice, __VA_ARGS__) -//#define atcab_get_addr(...) (1) - -// AES command functions -#define atcab_aes(...) (1) -#define atcab_aes_encrypt(...) talib_aes_encrypt(_gDevice, __VA_ARGS__) -#define atcab_aes_encrypt_ext talib_aes_encrypt -#define atcab_aes_decrypt(...) talib_aes_decrypt(_gDevice, __VA_ARGS__) -#define atcab_aes_decrypt_ext talib_aes_decrypt -#define atcab_aes_gfm(...) (1) - -#define atcab_aes_gcm_init(...) (1) -#define atcab_aes_gcm_init_rand(...) (1) -#define atcab_aes_gcm_aad_update(...) (1) -#define atcab_aes_gcm_encrypt_update(...) (1) -#define atcab_aes_gcm_encrypt_finish(...) (1) -#define atcab_aes_gcm_decrypt_update(...) (1) -#define atcab_aes_gcm_decrypt_finish(...) (1) - -// CheckMAC command functions -#define atcab_checkmac(...) (1) - -// Counter command functions -#define atcab_counter(...) talib_counter(_gDevice, __VA_ARGS__) -#define atcab_counter_increment(...) talib_counter_increment(_gDevice, __VA_ARGS__) -#define atcab_counter_read(...) talib_counter_read(_gDevice, __VA_ARGS__) - -// DeriveKey command functions -#define atcab_derivekey(...) (1) - -// ECDH command functions -#define atcab_ecdh_base(...) (1) -#define atcab_ecdh(...) talib_ecdh_compat(_gDevice, __VA_ARGS__) -#define atcab_ecdh_enc(...) (ATCA_UNIMPLEMENTED) -#define atcab_ecdh_ioenc(...) (ATCA_UNIMPLEMENTED) -#define atcab_ecdh_tempkey(...) (1) -#define atcab_ecdh_tempkey_ioenc(...) (ATCA_UNIMPLEMENTED) - -// GenDig command functions -#define atcab_gendig(...) (1) - -// GenKey command functions -#define atcab_genkey_base(...) (ATCA_UNIMPLEMENTED) -#define atcab_genkey(...) talib_genkey_compat(_gDevice, __VA_ARGS__) -#define atcab_get_pubkey(...) talib_get_pubkey_compat(_gDevice, __VA_ARGS__) -#define atcab_get_pubkey_ext talib_get_pubkey_compat - -// HMAC command functions -#define atcab_hmac(...) (ATCA_UNIMPLEMENTED) - -// Info command functions -#define atcab_info_base(...) talib_info_base(_gDevice, __VA_ARGS__) -#define atcab_info(...) talib_info_compat(_gDevice, __VA_ARGS__) -#define atcab_info_get_latch(...) (1) -#define atcab_info_set_latch(...) (1) -//#define atcab_info_get_latch(...) talib_info_get_latch(_gDevice, __VA_ARGS__) -//#define atcab_info_set_latch(...) talib_info_set_latch(_gDevice, __VA_ARGS__) - -// KDF command functions -#define atcab_kdf(...) (1) - -// Lock command functions -#define atcab_lock(...) (1) -#define atcab_lock_config_zone() talib_lock_config(_gDevice) -#define atcab_lock_config_zone_crc(...) talib_lock_config_with_crc(_gDevice, __VA_ARGS__) -#define atcab_lock_data_zone() talib_lock_setup(_gDevice) -#define atcab_lock_data_zone_crc(...) (1) -#define atcab_lock_data_slot(...) talib_lock_handle(_gDevice, __VA_ARGS__) - -// MAC command functions -#define atcab_mac(...) (ATCA_UNIMPLEMENTED) - -// Nonce command functions -#define atcab_nonce_base(...) (1) -#define atcab_nonce(...) (1) -#define atcab_nonce_load(...) (1) -#define atcab_nonce_rand(...) (1) -#define atcab_challenge(...) (1) -#define atcab_challenge_seed_update(...) (1) - -// PrivWrite command functionsoc -#define atcab_priv_write(...) (1) - -// Random command functions -#define atcab_random(...) talib_random_compat(_gDevice, __VA_ARGS__) -#define atcab_random_ext talib_random_compat - -// Read command functions -#define atcab_read_zone(...) (ATCA_UNIMPLEMENTED) -#define atcab_is_locked(...) talib_is_locked_compat(_gDevice, __VA_ARGS__) -#define atcab_is_config_locked(...) talib_is_config_locked(_gDevice, __VA_ARGS__) -#define atcab_is_data_locked(...) talib_is_setup_locked(_gDevice, __VA_ARGS__) -#define atcab_is_slot_locked(...) talib_is_handle_locked(_gDevice, __VA_ARGS__) -#define atcab_is_private(...) talib_is_private(_gDevice, __VA_ARGS__) -#define atcab_is_private_ext talib_is_private -#define atcab_read_bytes_zone(...) talib_read_bytes_zone(_gDevice, __VA_ARGS__) -#define atcab_read_serial_number(...) talib_info_serial_number_compat(_gDevice, __VA_ARGS__) -#define atcab_read_pubkey(...) talib_read_pubkey_compat(_gDevice, __VA_ARGS__) -#define atcab_read_pubkey_ext talib_read_pubkey_compat -#define atcab_read_sig(...) talib_read_sig_compat(_gDevice, __VA_ARGS__) -#define atcab_read_config_zone(...) talib_read_config_zone(_gDevice, __VA_ARGS__) -#define atcab_cmp_config_zone(...) talib_cmp_config_zone(_gDevice, __VA_ARGS__) -#define atcab_read_enc(...) (ATCA_UNIMPLEMENTED) - - -// SecureBoot command functions -#define atcab_secureboot(...) (ATCA_UNIMPLEMENTED) -#define atcab_secureboot_mac(...) (ATCA_UNIMPLEMENTED) - -// SelfTest command functions -#define atcab_selftest(...) (1) - -// SHA command functions -#define atcab_sha_base(...) talib_sha_base_compat(_gDevice, __VA_ARGS__) -#define atcab_sha_start() talib_sha_start(_gDevice) -#define atcab_sha_update(...) talib_sha_update_compat(_gDevice, __VA_ARGS__) -#define atcab_sha_end(...) talib_sha_end_compat(_gDevice, __VA_ARGS__) -#define atcab_sha_read_context(...) talib_sha_read_context(_gDevice, __VA_ARGS__) -#define atcab_sha_write_context(...) talib_sha_write_context(_gDevice, __VA_ARGS__) -#define atcab_sha(...) talib_sha(_gDevice, __VA_ARGS__) -#define atcab_hw_sha2_256(...) (1) -#define atcab_hw_sha2_256_init(...) (1) -#define atcab_hw_sha2_256_update(...) (1) -#define atcab_hw_sha2_256_finish(...) (1) -#define atcab_sha_hmac_init(...) (ATCA_UNIMPLEMENTED) -#define atcab_sha_hmac_update(...) (ATCA_UNIMPLEMENTED) -#define atcab_sha_hmac_finish(...) (ATCA_UNIMPLEMENTED) -#define atcab_sha_hmac(...) talib_hmac_compat(_gDevice, __VA_ARGS__) -#define atcab_sha_hmac_ext talib_hmac_compat -#define SHA_CONTEXT_MAX_SIZE (109) - -// Sign command functions -#define atcab_sign_base(...) (1) -#define atcab_sign(...) talib_sign_compat(_gDevice, __VA_ARGS__) -#define atcab_sign_ext talib_sign_compat -#define atcab_sign_internal(...) (1) - -// UpdateExtra command functions -#define atcab_updateextra(...) (1) - -// Verify command functions -#define atcab_verify(...) (1) -#define atcab_verify_extern(...) talib_verify_extern_compat(_gDevice, __VA_ARGS__) -#define atcab_verify_extern_ext talib_verify_extern_compat -#define atcab_verify_extern_mac(...) (ATCA_UNIMPLEMENTED) -#define atcab_verify_stored(...) talib_verify_stored_compat(_gDevice, __VA_ARGS__) -#define atcab_verify_stored_ext talib_verify_stored_compat -#define atcab_verify_stored_mac(...) (ATCA_UNIMPLEMENTED) -#define atcab_verify_validate(...) (ATCA_UNIMPLEMENTED) -#define atcab_verify_invalidate(...) (ATCA_UNIMPLEMENTED) - -// Write command functions -#define atcab_write(...) (ATCA_UNIMPLEMENTED) -#define atcab_write_zone(...) talib_write_zone(_gDevice, __VA_ARGS__) -#define atcab_write_bytes_zone(...) talib_write_bytes_zone(_gDevice, __VA_ARGS__) -#define atcab_write_pubkey(...) talib_write_pubkey_compat(_gDevice, __VA_ARGS__) -#define atcab_write_config_zone(...) talib_write_config_zone(_gDevice, __VA_ARGS__) -#define atcab_write_enc(...) (ATCA_UNIMPLEMENTED) -#define atcab_write_config_counter(...) (ATCA_UNIMPLEMENTED) - -#endif - -#if (ATCA_TA_SUPPORT && ATCA_CA_SUPPORT) || defined(ATCA_USE_ATCAB_FUNCTIONS) || defined(ATCA_ECC204_SUPPORT) +#ifdef ATCA_USE_ATCAB_FUNCTIONS /* Basic global methods */ ATCA_STATUS _atcab_exit(void); @@ -553,6 +185,7 @@ ATCA_STATUS atcab_is_data_locked(bool* is_locked); ATCA_STATUS atcab_is_slot_locked(uint16_t slot, bool* is_locked); ATCA_STATUS atcab_is_private_ext(ATCADevice device, uint16_t slot, bool* is_private); ATCA_STATUS atcab_is_private(uint16_t slot, bool* is_private); +ATCA_STATUS atcab_read_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t* data, size_t length); ATCA_STATUS atcab_read_bytes_zone(uint8_t zone, uint16_t slot, size_t offset, uint8_t* data, size_t length); ATCA_STATUS atcab_read_serial_number(uint8_t* serial_number); ATCA_STATUS atcab_read_pubkey(uint16_t slot, uint8_t* public_key); @@ -611,6 +244,7 @@ ATCA_STATUS atcab_verify_extern_ext(ATCADevice device, const uint8_t* message, c ATCA_STATUS atcab_verify_extern_mac(const uint8_t* message, const uint8_t* signature, const uint8_t* public_key, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); ATCA_STATUS atcab_verify_stored(const uint8_t* message, const uint8_t* signature, uint16_t key_id, bool* is_verified); ATCA_STATUS atcab_verify_stored_ext(ATCADevice device, const uint8_t* message, const uint8_t* signature, uint16_t key_id, bool* is_verified); +ATCA_STATUS atcab_verify_stored_with_tempkey(const uint8_t* signature, uint16_t key_id, bool* is_verified); ATCA_STATUS atcab_verify_stored_mac(const uint8_t* message, const uint8_t* signature, uint16_t key_id, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); ATCA_STATUS atcab_verify_validate(uint16_t key_id, const uint8_t* signature, const uint8_t* other_data, bool* is_verified); @@ -619,6 +253,7 @@ ATCA_STATUS atcab_verify_invalidate(uint16_t key_id, const uint8_t* signature, c /* Write command functions */ ATCA_STATUS atcab_write(uint8_t zone, uint16_t address, const uint8_t* value, const uint8_t* mac); ATCA_STATUS atcab_write_zone(uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, const uint8_t* data, uint8_t len); +ATCA_STATUS atcab_write_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t* data, size_t length); ATCA_STATUS atcab_write_bytes_zone(uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t* data, size_t length); ATCA_STATUS atcab_write_pubkey(uint16_t slot, const uint8_t* public_key); ATCA_STATUS atcab_write_config_zone(const uint8_t* config_data); @@ -631,7 +266,6 @@ ATCA_STATUS atcab_write_enc(uint16_t key_id, uint8_t block, const uint8_t* data, ATCA_STATUS atcab_write_config_counter(uint16_t counter_id, uint32_t counter_value); - #endif /* ATCA_TA_SUPPORT && ATCA_CA_SUPPORT */ #ifdef __cplusplus diff --git a/lib/atca_cfgs.c b/lib/atca_cfgs.c index f04f1be7c..a3b92cfb1 100644 --- a/lib/atca_cfgs.c +++ b/lib/atca_cfgs.c @@ -162,12 +162,15 @@ ATCAIfaceCfg cfg_atsha20xa_kituart_default = { ATCAIfaceCfg cfg_atsha20xa_kithid_default = { .iface_type = ATCA_HID_IFACE, .devtype = ATSHA204A, + { .atcahid.dev_interface = ATCA_KIT_AUTO_IFACE, .atcahid.dev_identity = 0, .atcahid.idx = 0, .atcahid.vid = 0x03EB, .atcahid.pid = 0x2312, .atcahid.packetsize = 64, + }, + .rx_retries = 1 }; #endif diff --git a/lib/atca_config.h.in b/lib/atca_config.h.in index 49e14451b..4bf75bc3e 100644 --- a/lib/atca_config.h.in +++ b/lib/atca_config.h.in @@ -83,6 +83,9 @@ /** Define to enable older API forms that have been replaced */ #cmakedefine ATCA_ENABLE_DEPRECATED +/** Enable Strict ISO/C99 compliance */ +#cmakedefine ATCA_STRICT_C99 + /** TA100 Specific - Enable auth sessions that require AES (CMAC/GCM) from an external library */ #cmakedefine ATCA_TA100_AES_AUTH_SUPPORT @@ -95,9 +98,11 @@ /** Define if the library is not to use malloc/free */ #cmakedefine ATCA_NO_HEAP -/** Define platform malloc/free */ -#cmakedefine ATCA_PLATFORM_MALLOC @ATCA_PLATFORM_MALLOC@ -#cmakedefine ATCA_PLATFORM_FREE @ATCA_PLATFORM_FREE@ +/** Define platform provided functions */ +#cmakedefine ATCA_PLATFORM_MALLOC @ATCA_PLATFORM_MALLOC@ +#cmakedefine ATCA_PLATFORM_FREE @ATCA_PLATFORM_FREE@ +#cmakedefine ATCA_PLATFORM_STRCASESTR @ATCA_PLATFORM_STRCASESTR@ +#cmakedefine ATCA_PLATFORM_MEMSET_S @ATCA_PLATFORM_MEMSET_S@ #define atca_delay_ms hal_delay_ms #define atca_delay_us hal_delay_us diff --git a/lib/atca_config_check.h b/lib/atca_config_check.h new file mode 100644 index 000000000..58a1dc9ff --- /dev/null +++ b/lib/atca_config_check.h @@ -0,0 +1,730 @@ +/** + * \file + * \brief Consistency checks for configuration options + * + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_CONFIG_CHECK_H +#define ATCA_CONFIG_CHECK_H + +#define FEATURE_ENABLED (1) +#define FEATURE_DISABLED (0) + +#define DEFAULT_ENABLED FEATURE_ENABLED +#define DEFAULT_DISABLED FEATURE_DISABLED + +/** Library Configuration File - All build attributes should be included in + atca_config.h */ +#include "atca_config.h" + +/* Configuration Macros to detect device classes */ +#if defined(ATCA_ATSHA204A_SUPPORT) || defined(ATCA_ATSHA206A_SUPPORT) +#define ATCA_SHA_SUPPORT 1 +#endif + +/* Make sure all configuration options work */ +#if defined(ATCA_ATECC608A_SUPPORT) && !defined(ATCA_ATECC608_SUPPORT) +#define ATCA_ATECC608_SUPPORT +#endif + +/* Support for fully featured ECC devices */ +#if defined(ATCA_ATECC108A_SUPPORT) || defined(ATCA_ATECC508A_SUPPORT) \ + || defined(ATCA_ATECC608_SUPPORT) +#define ATCA_ECC_SUPPORT DEFAULT_ENABLED +#endif + +/* Classic Cryptoauth Devices */ +#if defined(ATCA_SHA_SUPPORT) || defined(ATCA_ECC_SUPPORT) || defined(ATCA_ECC204_SUPPORT) +#define ATCA_CA_SUPPORT DEFAULT_ENABLED +#else +#define ATCA_CA_SUPPORT DEFAULT_DISABLED +#endif + +/* New Trust Anchor Devices */ +#if defined(ATCA_TA100_SUPPORT) +#define ATCA_TA_SUPPORT DEFAULT_ENABLED +#else +#define ATCA_TA_SUPPORT DEFAULT_DISABLED +#endif + +/* Check for external crypto libraries for host side operations */ +#ifndef ATCA_HOSTLIB_EN +#if defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) +#define ATCA_HOSTLIB_EN DEFAULT_ENABLED +#else +#define ATCA_HOSTLIB_EN DEFAULT_DISABLED +#endif +#endif + +/** Does the atcab_ API layer need to be instantiated (adds a layer of abstraction) */ +#ifndef ATCA_USE_ATCAB_FUNCTIONS +#if (ATCA_TA_SUPPORT && ATCA_CA_SUPPORT) +#define ATCA_USE_ATCAB_FUNCTIONS +#endif +#endif + +#ifndef ATCA_CHECK_PARAMS_EN +#define ATCA_CHECK_PARAMS_EN DEFAULT_ENABLED +#endif + + +#if ATCA_CHECK_PARAMS_EN +/** Emits message and returns the status code when the condition is true */ +#define ATCA_CHECK_INVALID_MSG(c, s, m) if (c) return ATCA_TRACE(s, m) +/* Continues when the condition is true - emits message if the condition is false */ +#define ATCA_CHECK_VALID_MSG(c, m) if (!ATCA_TRACE(!(c), m)) +#else +#define ATCA_CHECK_INVALID_MSG(c, s, m) +#define ATCA_CHECK_VALID_MSG(c, m) if (1) +#endif + +#define ATCA_CHECK_INVALID(c, s) ATCA_CHECK_INVALID_MSG(c, s, "") +#define ATCA_CHECK_VALID(c) ATCA_CHECK_VALID_MSG(c, "") + + + +/**** AES command ****/ + +/** \def ATCAB_AES + * + * Enable ATCAB_AES to compute the AES-128 encrypt, decrypt + * + * Supported API's: atcab_aes + **/ +#ifndef ATCAB_AES_EN +#if defined(ATCA_ATECC608_SUPPORT) || defined(ATCA_TA_SUPPORT) +#define ATCAB_AES_EN (DEFAULT_ENABLED) +#else +#define ATCAB_AES_EN (DEFAULT_DISABLED) +#endif +#endif + +/** \def ATCAB_AES_GFM_EN + * + * Enable ATCAB_AES_GFM_EN to enabled Galois Field Multiply + * + * Supported API's: atcab_aes + **/ +#if !defined(ATCAB_AES_GFM_EN) && ATCAB_AES_EN && defined(ATCA_ATECC608_SUPPORT) +#define ATCAB_AES_GFM_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_AES_GCM + * + * Requires: ATCAB_AES_GCM + * + * Supported API's: atcab_aes_gcm_init + * atcab_aes_gcm_init_rand + * atcab_aes_gcm_aad_update + * atcab_aes_gcm_encrypt_update + * atcab_aes_gcm_encrypt_finish + * atcab_aes_gcm_decrypt_update + * atcab_aes_gcm_decrypt_finish + **/ +#ifndef ATCAB_AES_GCM_EN +#define ATCAB_AES_GCM_EN (DEFAULT_ENABLED) +#endif + +#if ATCAB_AES_GCM_EN && !ATCAB_AES_GFM_EN && !ATCA_TA_SUPPORT && ATCA_ECC_SUPPORT +#error "AES128-GCM with ECC parts required the GFM (ATCAB_AES_GFM_EN) to be enabled as well" +#endif + +/**** CHECKMAC command ****/ + +/** \def ATCAB_CHECKMAC + * + * Requires: ATCAB_CHECKMAC + * CALIB_CHECKMAC + * + * Enable ATCAB_CHECKMAC to compare a MAC response with input values + * + * Supported API's: atcab_checkmac + **/ +#ifndef ATCAB_CHECKMAC_EN +#define ATCAB_CHECKMAC_EN (DEFAULT_ENABLED) +#endif + +/***** COUNTER command *****/ + +/** \def ATCAB_COUNTER + * + * Requires: ATCAB_COUNTER + * CALIB_COUNTER + * + * Enable ATCAB_COUNTER to compute the counter functions + * + * Supported API's: atcab_counter + **/ +#ifndef ATCAB_COUNTER_EN +#define ATCAB_COUNTER_EN (DEFAULT_ENABLED) +#endif + +/***** DERIVEKEY command ******/ + +/** \def ATCAB_DERIVEKEY + * + * Requires: ATCAB_DERIVEKEY + * CALIB_DERIVEKEY + * + * Enable ATCAB_DERIVEKEY for deriving a new key from a nonce (TempKey) and an existing key + * + * Supported API's: atcab_derivekey + **/ +#ifndef ATCAB_DERIVEKEY_EN +#define ATCAB_DERIVEKEY_EN (DEFAULT_ENABLED) +#endif + +/******* ECDH command *******/ + +/** \def ATCAB_ECDH + * + * Requires: ATCAB_ECDH + * CALIB_ECDH + * + * Supported API's: atcab_ecdh_base + * atcab_ecdh + * atcab_ecdh_tempkey + * + * Enable ATCAB_ECDH for generating premaster secret key using ECDH + * ECDH command with a private key in a slot/tempkey and the premaster secret is returned in the clear + **/ +#ifndef ATCAB_ECDH_EN +#define ATCAB_ECDH_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_ECDH_ENC + * + * Requires: ATCAB_ECDH_ENC + * CALIB_ECDH_ENC + * + * Supported API's: atcab_ecdh_enc + * atcab_ecdh_ioenc + * atcab_ecdh_tempkey_ioenc + * + * ECDH command with a private key in a slot and the premaster secret is read from the next slot + * ECDH command with a private key in a slot/tempkey and the premaster secret is returned encrypted + * using the IO protection key + **/ +#ifndef ATCAB_ECDH_ENC_EN +#define ATCAB_ECDH_ENC_EN (DEFAULT_ENABLED) +#endif + +/****** GENDIG command ******/ + +/** \def ATCAB_GENDIG + * + * Requires: ATCAB_GENDIG + * CALIB_GENDIG + * + * Enable ATCAB_GENDIG to perform a SHA256 hash on the source data indicated by zone with the + * contents of TempKey + * + * Supported API's: atcab_gendig + **/ +#ifndef ATCAB_GENDIG_EN +#define ATCAB_GENDIG_EN (DEFAULT_ENABLED) +#endif + +/****** GENKEY COMMAND ******/ + +/** \def ATCAB_GENKEY_BASE + * + * Requires: ATCAB_GENKEY_BASE + * CALIB_GENKEY_BASE + * + * Enable ATCAB_GENKEY_BASE which can generate a private key, compute a public key, nd/or compute a + * digest of a public key + * + * Supported API's: atcab_genkey_base + **/ +#ifndef ATCAB_GENKEY_EN +#define ATCAB_GENKEY_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_GENKEY_MAC_EN + * + * Requires: ATCAB_GENKEY_EN + * + * Enable ATCAB_GENKEY_MAC_EN which provides for a mac with the genkey command + * + * Supported API's: atcab_genkey_base + **/ +#ifndef ATCAB_GENKEY_MAC_EN +#define ATCAB_GENKEY_MAC_EN ATCAB_GENKEY_EN +#endif + +/******* HMAC COMMAND *******/ + +/** \def ATCAB_HMAC + * + * Requires: ATCAB_HMAC + * ATCAB_HMAC + * + * Enable ATCAB_HMAC which computes an HMAC/SHA-256 digest of a key stored in the device, a + * challenge, and other information on the device + * + * Supported API's: atcab_hmac + **/ +#ifndef ATCAB_HMAC_EN +#define ATCAB_HMAC_EN (DEFAULT_ENABLED) +#endif + +/******* INFO COMMAND ********/ + +/** \def ATCAB_INFO_LATCH_EN + * + * Enable ATCAB_INFO_LATCH_EN which enables control of GPIOs and the + * persistent latch + * + * Supported API's: atcab_info_base + **/ +#ifndef ATCAB_INFO_LATCH_EN +#define ATCAB_INFO_LATCH_EN (DEFAULT_ENABLED) +#endif + +/****** KDF COMMAND ******/ + +/** \def ATCAB_KDF + * + * Requires: ATCAB_KDF + * CALIB_KDF + * + * Enable ATCAB_KDF to derive a new key in PRF, AES, or HKDF modes + * + * Supported API's: atcab_kdf + **/ +#ifndef ATCAB_KDF_EN +#define ATCAB_KDF_EN (DEFAULT_ENABLED) +#endif + +/****** LOCK COMMAND ******/ + +/** \def ATCAB_LOCK + * + * Requires: ATCAB_LOCK + * CALIB_LOCK + * + * Enable ATCAB_LOCK which prevents future modifications of the Configuration and/or Data and OTP zones + * + * Supported API's: atcab_lock + **/ +#ifndef ATCAB_LOCK_EN +#define ATCAB_LOCK_EN (DEFAULT_ENABLED) +#endif + +/****** MAC command ******/ + +/** \def ATCAB_MAC + * + * Enable ATCAB_MAC to computes a SHA-256 digest of a key stored in the device, a challenge, and + * other information on the device + * + * Supported API's: atcab_mac + **/ +#ifndef ATCAB_MAC_EN +#define ATCAB_MAC_EN (DEFAULT_ENABLED) +#endif + +/****** NONCE command ******/ + +/** \def ATCAB_NONCE_BASE + * + * Enable ATCAB_NONCE_BASE which loads a random or fixed nonce/data into the device for use by subsequent + * commands + * + * Requires: ATCAB_NONCE_BASE + * CALIB_NONCE_BASE + * + * Supported API's: atcab_nonce_base + **/ +#ifndef ATCAB_NONCE_EN +#define ATCAB_NONCE_EN (DEFAULT_ENABLED) +#endif + +/**** PRIVWRITE COMMAND ****/ + +/** \def ATCAB_PRIVWRITE + * + * Enable ATCAB_PRIVWRITE to write externally generated ECC private keys into the device + * + * Requires: ATCAB_PRIVWRITE + * CALIB_PRIVWRITE + * + * Supported API's: atcab_priv_write + **/ +#ifndef ATCAB_PRIVWRITE_EN +#define ATCAB_PRIVWRITE_EN (DEFAULT_ENABLED) +#endif + +/***** RANDOM COMMAND *****/ + +/** \def ATCAB_RANDOM + * + * Requires: ATCAB_RANDOM + * CALIB_RANDOM + * + * Enable ATCAB_RANDOM which generates a 32 byte random number from the CryptoAuth device + * + * Supported API's: atcab_random + * atcab_random_ext + **/ +#ifndef ATCAB_RANDOM_EN +#define ATCAB_RANDOM_EN (DEFAULT_ENABLED) +#endif + +/***** READ command *****/ + +/** \def ATCAB_READ_ZONE + * + * Requires: ATCAB_READ_ZONE + * CALIB_READ_ZONE + * + * Enable ATCAB_READ_ZONE which reads either 4 or 32 bytes of data from a given slot, + * configuration zone, or the OTP zone + * + * Supported API's: atcab_read_zone + **/ +#ifndef ATCAB_READ_EN +#define ATCAB_READ_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_READ_ENC + * + * Requires: ATCAB_READ_ENC + * CALIB_READ_ENC + * + * Performs Read command on a slot configured for encrypted reads and decrypts the data to return + * it as plaintext + * + * Supported API's: atcab_read_enc + **/ +#ifndef ATCAB_READ_ENC_EN +#define ATCAB_READ_ENC_EN ATCAB_READ_EN +#endif + +/***** SECUREBOOT command ****/ + +/** \def ATCAB_SECUREBOOT + * + * Enable ATCAB_SECUREBOOT which provides support for secureboot of an external MCU or MPU + * + * Requires: ATCAB_SECUREBOOT + * + * Supported API's: atcab_secureboot + **/ +#ifndef ATCAB_SECUREBOOT_EN +#define ATCAB_SECUREBOOT_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_SECUREBOOT_MAC + * + * Requires: ATCAB_SECUREBOOT_MAC + * CALIB_SECUREBOOT_MAC + * + * Performs secureboot command with encrypted digest and validated MAC response using the + * IO protection key + * + * Supported API's: ATCAB_secureboot_mac + **/ +#ifndef ATCAB_SECUREBOOT_MAC_EN +#define ATCAB_SECUREBOOT_MAC_EN ATCAB_SECUREBOOT_EN +#endif + +/**** SELFTEST command ****/ + +/** \def ATCAB_SELFTEST + * + * Enable ATCAB_SELFTEST which performs a test of one or more of the cryptographic engines within + * the ATECC608 chip + * + * Supported API's: atcab_selftest + **/ +#ifndef ATCAB_SELFTEST_EN +#define ATCAB_SELFTEST_EN (DEFAULT_ENABLED) +#endif + +/****** SHA command ******/ + +/** \def ATCAB_SHA_BASE + * + * Requires: ATCAB_SHA_BASE + * CALIB_SHA_BASE + * + * Enable ATCAB_SHA_BASE to compute a SHA-256 or HMAC/SHA-256 digest for general purpose use by + * the host system + * + * Supported API's: atcab_sha_base + **/ +#ifndef ATCAB_SHA_EN +#define ATCAB_SHA_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_SHA_HMAC + * + * Requires: ATCAB_SHA_HMAC + * + * Use the SHA command to compute an HMAC/SHA-256 operation + * + * Supported API's: atcab_sha_hmac, atcab_sha_hmac_init, atcab_sha_hmac_update, + * atcab_sha_hmac_finish, atcab_sha_hmac_ext + **/ +#ifndef ATCAB_SHA_HMAC_EN +#define ATCAB_SHA_HMAC_EN ATCAB_SHA_EN +#endif + +/** \def ATCAB_SHA_READ_CONTEXT_EN + * + * Requires: ATCAB_SHA_EN + * + * Use the SHA command to compute an HMAC/SHA-256 operation + * + * Supported API's: atcab_sha_read_context, atcab_sha_write_context + **/ +#ifndef ATCAB_SHA_CONTEXT_EN +#define ATCAB_SHA_CONTEXT_EN ATCAB_SHA_EN +#endif + +/****** SIGN command ******/ + +/** \def ATCAB_SIGN_BASE + * + * Requires: ATCAB_SIGN_BASE + * CALIB_SIGN_BASE + * + * Enable ATCAB_SIGN_BASE to generate a signature using the ECDSA algorithm + * + * Supported API's: atcab_sign_base + **/ +#ifndef ATCAB_SIGN_EN +#define ATCAB_SIGN_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_SIGN_MODE_ENCODING + * + * Requires: ATCAB_SIGN + * + * Use ATCAB_SIGN_INTERNAL to sign a internally generated message + * + * Supported API's: atcab_sign_internal + **/ +#ifndef ATCAB_SIGN_INTERNAL_EN +#define ATCAB_SIGN_INTERNAL_EN ATCAB_SIGN_EN +#endif + +/***** UPDATEEXTRA command ****/ + +/** \def ATCAB_UPDATEEXTRA + * + * Requires: ATCAB_UPDATEEXTRA + * + * Enable ATCAB_UPDATEEXTRA to update the values of the two extra bytes within the configuration + * zone (bytes 84 and 85) + * + * Supported API's: atcab_updateextra + **/ +#ifndef ATCAB_UPDATEEXTRA_EN +#define ATCAB_UPDATEEXTRA_EN (DEFAULT_ENABLED) +#endif + +/******** VERIFY command ********/ + +/** \def ATCAB_VERIFY + * + * Requires: ATCAB_VERIFY + * CALIB_VERIFY + * + * Enable ATCAB_VERIFY which takes an ECDSA [R,S] signature and verifies that it is correctly + * generated from a given message and public key. In all cases, the signature is an input to the command + * + * Supported API's: atcab_verify + **/ +#ifndef ATCAB_VERIFY_EN +#define ATCAB_VERIFY_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_VERIFY_EXTERN + * + * Requires: ATCAB_VERIFY + * + * Verifies a signature (ECDSA verify operation) with all components (message, signature, and + * public key) supplied + * + * Supported API's: atcab_verify_extern_ext + * atcab_verify_extern + **/ +#ifndef ATCAB_VERIFY_EXTERN_EN +#define ATCAB_VERIFY_EXTERN_EN ATCAB_VERIFY_EN +#endif + +/** \def ATCAB_VERIFY_MAC_EN + * + * Requires: ATCAB_VERIFY + * + * Executes verification command with verification MAC for the External or Stored Verify modes + * + * Supported API's: atcab_verify_extern_mac, atcab_verify_stored_mac + **/ +#ifndef ATCAB_VERIFY_MAC_EN +#define ATCAB_VERIFY_MAC_EN ATCAB_VERIFY_EN +#endif + +/** \def ATCAB_VERIFY_STORED + * + * Requires: ATCAB_VERIFY + * + * Verifies a signature (ECDSA verify operation) with a public key stored in the device + * + * Supported API's: atcab_verify_stored_ext + * atcab_verify_stored + **/ +#ifndef ATCAB_VERIFY_STORED_EN +#define ATCAB_VERIFY_STORED_EN ATCAB_VERIFY_EN +#endif + +/** \def ATCAB_VERIFY_VALIDATE + * + * Requires: ATCAB_VERIFY_VALIDATE + * + * Executes verification command in Validate mode to validate a public key stored in a slot + * + * Supported API's: atcab_verify_validate + **/ +#ifndef ATCAB_VERIFY_VALIDATE_EN +#define ATCAB_VERIFY_VALIDATE_EN ATCAB_VERIFY_EN +#endif + +/****** WRITE command ******/ + +/** \def ATCAB_WRITE + * + * Requires: ATCAB_WRITE + * CALIB_WRITE + * + * Enable ATCAB_WRITE which writes either one four byte word or a 32-byte block to one of the + * EEPROM zones on the device + * + * Supported API's: atcab_write + **/ +#ifndef ATCAB_WRITE_EN +#define ATCAB_WRITE_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAB_WRITE_ENC + * + * Requires: ATCAB_WRITE_ENC + * + * Performs an encrypted write of a 32 byte block into given slot + * + * Supported API's: atcab_write_enc + **/ +#ifndef ATCAB_WRITE_ENC_EN +#define ATCAB_WRITE_ENC_EN ATCAB_WRITE_EN +#endif + +/* Host side Cryptographic functionality required by the library */ + +/** \def ATCAC_SHA1_EN + * + * Enable ATCAC_SHA1_EN to enable sha1 host side api + * + * Supported API's: atcab_write + **/ +#ifndef ATCAC_SHA1_EN +#define ATCAC_SHA1_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAC_SHA256_EN + * + * Enable ATCAC_SHA256_EN to enable sha256 host side api + * + * Supported API's: atcab_write + **/ +#ifndef ATCAC_SHA256_EN +#define ATCAC_SHA256_EN (DEFAULT_ENABLED) +#endif + +/** \def ATCAC_SHA256_HMAC + * + * Requires: ATCAC_SHA256_HMAC + * ATCAC_SW_SHA2_256 + * + * Enable ATCAC_SHA256_HMAC to initialize context for performing HMAC (sha256) in software + * + * Supported API's: atcac_sha256_hmac_init, atcac_sha256_hmac_update, atcac_sha256_hmac_finish + **/ +#ifndef ATCAC_SHA256_HMAC_EN +#define ATCAC_SHA256_HMAC_EN ATCAC_SHA256_EN +#endif + +/** \def ATCAC_SHA256_HMAC_COUNTER + * + * Requires: ATCAC_SHA256_HMAC_COUNTER + * ATCAC_SHA256_HMAC + * ATCAC_SW_SHA2_256 + * + * Enable ATCAC_SHA256_HMAC_COUNTER to implement SHA256 HMAC-Counter per NIST SP 800-108 used for + * KDF like operations + * + * Supported API's: atcac_sha256_hmac_counter + **/ +#ifndef ATCAC_SHA256_HMAC_CTR_EN +#define ATCAC_SHA256_HMAC_CTR_EN ATCAC_SHA256_HMAC_EN +#endif + +/** \def ATCAC_RANDOM_EN + * + * Requires: ATCA_HOSTLIB_EN + * + * Enable ATCAC_RANDOM_EN get random numbers from the host's + * implementation - generally assumed to come from the host's + * cryptographic library or peripheral driver + * + */ +#ifndef ATCAC_RANDOM_EN +#define ATCAC_RANDOM_EN ATCA_HOSTLIB_EN +#endif + +/** \def ATCAC_VERIFY_EN + * + * Requires: ATCA_HOSTLIB_EN + * + * Enable ATCAC_VERIFY_EN to use the host's verify functions. Generally assumed + * to come from the host's cryptographic library or peripheral driver. + */ +#ifndef ATCAC_VERIFY_EN +#define ATCAC_VERIFY_EN ATCA_HOSTLIB_EN +#endif + +/** \def ATCAC_SIGN_EN + * + * Requires: ATCA_HOSTLIB_EN + * + * Enable ATCAC_SIGN_EN to use the host's sign functions. Generally assumed + * to come from the host's cryptographic library or peripheral driver. + */ +#ifndef ATCAC_SIGN_EN +#define ATCAC_SIGN_EN ATCA_HOSTLIB_EN +#endif + +#endif /* ATCA_CONFIG_CHECK_H */ diff --git a/lib/atca_debug.c b/lib/atca_debug.c index f1cf6d9da..8dcbd8379 100644 --- a/lib/atca_debug.c +++ b/lib/atca_debug.c @@ -44,6 +44,7 @@ ATCA_STATUS atca_trace_msg(ATCA_STATUS status, const char * msg) if (ATCA_SUCCESS != status) { fprintf(g_trace_fp ? g_trace_fp : stderr, msg, status); + fflush(g_trace_fp); } return status; } diff --git a/lib/atca_devtypes.h b/lib/atca_devtypes.h index ba8f82d46..9dd490c6f 100644 --- a/lib/atca_devtypes.h +++ b/lib/atca_devtypes.h @@ -48,6 +48,7 @@ typedef enum ATECC608 = 3, ATSHA206A = 4, ECC204 = 5, + TA010 = 7, TA100 = 0x10, ATCA_DEV_UNKNOWN = 0x20 } ATCADeviceType; diff --git a/lib/atca_helpers.c b/lib/atca_helpers.c index 6086f341d..0d62b6ce3 100644 --- a/lib/atca_helpers.c +++ b/lib/atca_helpers.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "cryptoauthlib.h" #include "atca_helpers.h" @@ -853,6 +854,7 @@ ATCA_STATUS atcab_base64decode(const char* encoded, size_t encoded_len, uint8_t* return atcab_base64decode_(encoded, encoded_len, byte_array, array_len, atcab_b64rules_default); } +#if !defined(ATCA_PLATFORM_MEMSET_S) && !defined(memset_s) /** * \brief Guaranteed to perform memory writes regardless of optimization level. Matches memset_s signature */ @@ -879,3 +881,52 @@ int atcab_memset_s(void* dest, size_t destsz, int ch, size_t count) return 0; } +#endif + +#if !defined(ATCA_PLATFORM_STRCASESTR) && !defined(strcasecstr) +/** + * \brief Search for a substring in a case insenstive format + */ +char * lib_strcasestr(const char *haystack, const char *needle) +{ + const char * h = haystack; + const char * n = needle; + const char * m = NULL; + + if (!h || !n) + { + return (char*)h; + } + + while(*h && *n) + { + if (*h != *n && *h != toupper(*n)) + { + if(m) + { + /* Restart Matching */ + m = NULL; + n = needle; + } + else + { + /* Continue stepping through the haystack */ + h++; + } + } + else + { + if (!m) + { + /* Save the start of the match */ + m = h; + } + n++; + h++; + } + } + + /* if we reached the end of the needle then it was found */ + return (char*)((!*n) ? m : NULL); +} +#endif diff --git a/lib/atca_iface.c b/lib/atca_iface.c index ab8aeacc1..00aac2aaa 100644 --- a/lib/atca_iface.c +++ b/lib/atca_iface.c @@ -27,6 +27,7 @@ */ #include "cryptoauthlib.h" +#include /** \defgroup interface ATCAIface (atca_) * \brief Abstract interface to all CryptoAuth device types. This interface @@ -154,9 +155,9 @@ ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t address, uint8_t *txdata, int txl if (ATCA_I2C_IFACE == ca_iface->mIfaceCFG->iface_type && 0xFF == address) { #ifdef ATCA_ENABLE_DEPRECATED - address = ca_iface->mIfaceCFG->atcai2c.slave_address; + address = ATCA_IFACECFG_VALUE(ca_iface->mIfaceCFG, atcai2c.slave_address); #else - address = ca_iface->mIfaceCFG->atcai2c.address; + address = ATCA_IFACECFG_VALUE(ca_iface->mIfaceCFG, atcai2c.address); #endif } #endif @@ -330,6 +331,21 @@ void* atgetifacehaldat(ATCAIface ca_iface) return ca_iface ? ca_iface->hal_data : NULL; } +/** \brief Check if the given interface is a "kit protocol" one + * \return true if the interface type is considered a kit + */ +bool ifacetype_is_kit(ATCAIfaceType iface_type) +{ + bool ret = false; + + if (ATCA_HID_IFACE == iface_type || ATCA_KIT_IFACE == iface_type + || ATCA_UART_IFACE == iface_type) + { + ret = true; + } + return ret; +} + /** \brief Check if the given interface is configured as a "kit protocol" one where * transactions are atomic * \return true if the interface is considered a kit @@ -392,6 +408,131 @@ uint16_t atca_iface_get_wake_delay(ATCAIface ca_iface) } } +/** \brief Retrieves the device address given an interface configuration */ +uint8_t ifacecfg_get_address(ATCAIfaceCfg * cfg) +{ + uint8_t addr = 0xFF; + if (cfg) + { + switch(cfg->iface_type) + { +#ifdef ATCA_HAL_I2C + case ATCA_I2C_IFACE: +#ifdef ATCA_ENABLE_DEPRECATED + addr = ATCA_IFACECFG_VALUE(cfg, atcai2c.slave_address); +#else + addr = ATCA_IFACECFG_VALUE(cfg, atcai2c.address); +#endif + break; +#endif +#ifdef ATCA_HAL_SWI_UART + case ATCA_SWI_IFACE: +#ifdef __linux__ + addr = ATCA_IFACECFG_VALUE(cfg, atcauart.dev_identity); +#else + addr = ATCA_IFACECFG_VALUE(cfg, atcaswi.address); +#endif + break; +#endif +#ifdef ATCA_HAL_KIT_UART + case ATCA_UART_IFACE: + addr = ATCA_IFACECFG_VALUE(cfg, atcauart.dev_identity); + break; +#endif +#ifdef ATCA_HAL_KIT_HID + case ATCA_HID_IFACE: + addr = ATCA_IFACECFG_VALUE(cfg, atcahid.dev_identity); + break; +#endif +#ifdef ATCA_HAL_KIT_BRIDGE + case ATCA_KIT_IFACE: + addr = ATCA_IFACECFG_VALUE(cfg, atcakit.dev_identity); + break; +#endif +#if defined(ATCA_HAL_SWI_GPIO) || defined(ATCA_HAL_SWI_BB) + case ATCA_SWI_GPIO_IFACE: + addr = ATCA_IFACECFG_VALUE(cfg, atcaswi.address); + break; +#endif + default: + break; + } + } + return addr; +} + +/** \brief Change the address of the selected device */ +ATCA_STATUS ifacecfg_set_address( + ATCAIfaceCfg * cfg, /**< [in] Interface configuration structure to update */ + uint8_t addr, /**< [in] Desired address */ + ATCAKitType kitiface /**< [in] Optional parameter to set the kit iface type */ +) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + if (cfg) + { + status = ATCA_SUCCESS; + switch(cfg->iface_type) + { +#ifdef ATCA_HAL_I2C + case ATCA_I2C_IFACE: +#ifdef ATCA_ENABLE_DEPRECATED + ATCA_IFACECFG_VALUE(cfg, atcai2c.slave_address) = addr; +#else + ATCA_IFACECFG_VALUE(cfg, atcai2c.address) = addr; +#endif + break; +#endif +#ifdef ATCA_HAL_SWI_UART + case ATCA_SWI_IFACE: +#ifdef __linux__ + ATCA_IFACECFG_VALUE(cfg, atcauart.dev_interface) = ATCA_KIT_AUTO_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcauart.dev_identity) = addr; +#else + ATCA_IFACECFG_VALUE(cfg, atcaswi.address) = addr; +#endif + break; +#endif +#ifdef ATCA_HAL_KIT_UART + case ATCA_UART_IFACE: + if(ATCA_KIT_UNKNOWN_IFACE != kitiface) + { + ATCA_IFACECFG_VALUE(cfg, atcauart.dev_interface) = kitiface; + } + ATCA_IFACECFG_VALUE(cfg, atcauart.dev_identity) = addr; + break; +#endif +#ifdef ATCA_HAL_KIT_HID + case ATCA_HID_IFACE: + if(ATCA_KIT_UNKNOWN_IFACE != kitiface) + { + ATCA_IFACECFG_VALUE(cfg, atcahid.dev_interface) = kitiface; + } + ATCA_IFACECFG_VALUE(cfg, atcahid.dev_identity) = addr; + break; +#endif +#ifdef ATCA_HAL_KIT_BRIDGE + case ATCA_KIT_IFACE: + if(ATCA_KIT_UNKNOWN_IFACE != kitiface) + { + ATCA_IFACECFG_VALUE(cfg, atcakit.dev_interface) = kitiface; + } + ATCA_IFACECFG_VALUE(cfg, atcakit.dev_identity) = addr; + break; +#endif +#if defined(ATCA_HAL_SWI_GPIO) || defined(ATCA_HAL_SWI_BB) + case ATCA_SWI_GPIO_IFACE: + ATCA_IFACECFG_VALUE(cfg, atcaswi.address) = addr; + break; +#endif + default: + status = ATCA_BAD_PARAM; + break; + } + } + return status; +} + /** \brief Instruct the HAL driver to release any resources associated with * this interface. @@ -435,4 +576,56 @@ void deleteATCAIface(ATCAIface *ca_iface) } #endif +typedef struct { + ATCADeviceType devtype; + const char * name; +} devtype_names_t; + +static const devtype_names_t devtype_names[] = { +#ifdef ATCA_ATSHA204A_SUPPORT + { ATSHA204A, "sha204" }, +#endif +#ifdef ATCA_ATECC108A_SUPPORT + { ATECC108A, "ecc108" }, +#endif +#ifdef ATCA_ATECC508A_SUPPORT + { ATECC508A, "ecc508" }, +#endif +#ifdef ATCA_ATECC608_SUPPORT + { ATECC608, "ecc608" }, +#endif +#ifdef ATCA_ATSHA206A_SUPPORT + { ATSHA206A, "sha206" }, +#endif +#ifdef ATCA_ECC204_SUPPORT + { ECC204, "ecc204" }, +#endif +#ifdef ATCA_TA100_SUPPORT + { TA100, "ta100" }, +#endif + { ATCA_DEV_UNKNOWN, "unknown"} +}; + +/** \brief Get the ATCADeviceType for a string that looks like a part number */ +ATCADeviceType iface_get_device_type_by_name(const char * name) +{ + ATCADeviceType devtype = ATCA_DEV_UNKNOWN; + if (name) + { + const devtype_names_t * entry; + + for( entry=devtype_names; entry->devtype != ATCA_DEV_UNKNOWN; entry++) + { + if (lib_strcasestr(name, entry->name)) + { + devtype = entry->devtype; + break; + } + } + } + + return devtype; +} + + /** @} */ diff --git a/lib/atca_iface.h b/lib/atca_iface.h index 1cb80eab6..9dfc42225 100644 --- a/lib/atca_iface.h +++ b/lib/atca_iface.h @@ -47,6 +47,13 @@ extern "C" { #include "atca_devtypes.h" #include "atca_status.h" +#ifdef ATCA_STRICT_C99 +#define ATCA_IFACECFG_NAME(x) x +#define ATCA_IFACECFG_VALUE(c, v) c->cfg.v +#else +#define ATCA_IFACECFG_NAME(x) +#define ATCA_IFACECFG_VALUE(c, v) c->v +#endif typedef enum { @@ -89,7 +96,7 @@ typedef struct struct { #ifdef ATCA_ENABLE_DEPRECATED - uint8_t slave_address; // 8-bit slave address + uint8_t slave_address; // 8-bit device address #else uint8_t address; /**< Device address - the upper 7 bits are the I2c address bits */ #endif @@ -149,8 +156,7 @@ typedef struct ATCA_STATUS (*halsleep)(void *iface); ATCA_STATUS (*halrelease)(void* hal_data); } atcacustom; - - }; + } ATCA_IFACECFG_NAME(cfg); uint16_t wake_delay; // microseconds of tWHI + tWLO which varies based on chip type int rx_retries; // the number of retries to attempt for receiving bytes @@ -200,12 +206,18 @@ ATCA_STATUS atsleep(ATCAIface ca_iface); // accessors ATCAIfaceCfg * atgetifacecfg(ATCAIface ca_iface); void* atgetifacehaldat(ATCAIface ca_iface); +ATCA_STATUS ifacecfg_set_address(ATCAIfaceCfg * cfg, uint8_t address, ATCAKitType kitiface); +uint8_t ifacecfg_get_address(ATCAIfaceCfg * cfg); /* Utilities */ +bool ifacetype_is_kit(ATCAIfaceType iface_type); + bool atca_iface_is_kit(ATCAIface ca_iface); bool atca_iface_is_swi(ATCAIface ca_iface); int atca_iface_get_retries(ATCAIface ca_iface); uint16_t atca_iface_get_wake_delay(ATCAIface ca_iface); +ATCADeviceType iface_get_device_type_by_name(const char * name); + #ifdef __cplusplus } diff --git a/lib/atca_platform.h b/lib/atca_platform.h new file mode 100644 index 000000000..ccd2588a8 --- /dev/null +++ b/lib/atca_platform.h @@ -0,0 +1,62 @@ +/** + * \file + * \brief Configure the platform interfaces for cryptoauthlib + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#ifndef ATCA_PLATFORM_H +#define ATCA_PLATFORM_H + +#include + +#if defined(ATCA_TESTS_ENABLED) || !defined(ATCA_PLATFORM_MALLOC) +void* hal_malloc(size_t size); +void hal_free(void* ptr); +#else +#define hal_malloc ATCA_PLATFORM_MALLOC +#define hal_free ATCA_PLATFORM_FREE +#endif +#endif + +#ifdef ATCA_PLATFORM_MEMSET_S +#define hal_memset_s ATCA_PLATFORM_MEMSET_S +#else +#include +#ifndef memset_s +#define hal_memset_s atcab_memset_s +#else +#define hal_memset_s memset_s +#endif + +#ifdef ATCA_PLATFORM_STRCASESTR +#define lib_strcasestr ATCA_PLATFORM_STRCASESTR +#else +#include +#ifndef strcasestr +char *lib_strcasestr(const char *haystack, const char *needle); +#else +#define lib_strcasestr strcasestr +#endif +#endif /* ATCA_PLATFORM_STRCASESTR */ + +#endif /* ATCA_PLATFORM_H */ diff --git a/lib/atca_utils_sizes.c b/lib/atca_utils_sizes.c index 0b1002b1b..db9abac25 100644 --- a/lib/atca_utils_sizes.c +++ b/lib/atca_utils_sizes.c @@ -49,10 +49,16 @@ SIZE_OF_API_T(atcacert_def_t) SIZE_OF_API_T(atcacert_build_state_t) #endif -/* atcab.h */ +/* atca_crypto_hw_aes.h */ +#ifdef atca_aes_cbc_ctx_t SIZE_OF_API_T(atca_aes_cbc_ctx_t) +#endif +#ifdef atca_aes_cmac_ctx_t SIZE_OF_API_T(atca_aes_cmac_ctx_t) +#endif +#ifdef atca_aes_ctr_ctx_t SIZE_OF_API_T(atca_aes_ctr_ctx_t) +#endif #if ATCA_CA_SUPPORT #include "host/atca_host.h" diff --git a/lib/atca_version.h b/lib/atca_version.h index 0a8d8bc4f..6aa3010ef 100644 --- a/lib/atca_version.h +++ b/lib/atca_version.h @@ -30,9 +30,9 @@ #define _ATCA_VERSION_H // Version format yyyymmdd -#define ATCA_LIBRARY_VERSION_DATE "20211006" +#define ATCA_LIBRARY_VERSION_DATE "20221027" #define ATCA_LIBRARY_VERSION_MAJOR 3 -#define ATCA_LIBRARY_VERSION_MINOR 3 -#define ATCA_LIBRARY_VERSION_BUILD 3 +#define ATCA_LIBRARY_VERSION_MINOR 4 +#define ATCA_LIBRARY_VERSION_BUILD 0 #endif /* _ATCA_VERSION_H */ diff --git a/lib/atcacert/atcacert.h b/lib/atcacert/atcacert.h index fb765f260..7e5284fc0 100644 --- a/lib/atcacert/atcacert.h +++ b/lib/atcacert/atcacert.h @@ -33,6 +33,8 @@ #include #include +#include "atcacert_check_config.h" + /** \defgroup atcacert_ Certificate manipulation methods (atcacert_) * * \brief diff --git a/lib/atcacert/atcacert_check_config.h b/lib/atcacert/atcacert_check_config.h new file mode 100644 index 000000000..0c5f55be8 --- /dev/null +++ b/lib/atcacert/atcacert_check_config.h @@ -0,0 +1,58 @@ +/** + * \file + * \brief Configuration check and defaults for the atcacert module + * + * \copyright (c) 2015-2022 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ +#ifndef ATCACERT_CHECK_CONFIG_H +#define ATCACERT_CHECK_CONFIG_H + +/* The atcacert_ module is only set up to work with classic cryptoauth devices */ +#include "calib/calib_config_check.h" + + +#ifndef ATCACERT_HW_CHALLENGE_EN +#define ATCACERT_HW_CHALLENGE_EN CALIB_RANDOM_EN +#endif + +#ifndef ATCACERT_HW_VERIFY_EN +#define ATCACERT_HW_VERIFY_EN CALIB_VERIFY_EXTERN_EN +#endif + +#ifndef ATCACERT_DATEFMT_ISO_EN +#define ATCACERT_DATEFMT_ISO_EN DEFAULT_ENABLED +#endif + +#ifndef ATCACERT_DATEFMT_UTC_EN +#define ATCACERT_DATEFMT_UTC_EN DEFAULT_ENABLED +#endif + +#ifndef ATCACERT_DATEFMT_POSIX_EN +#define ATCACERT_DATEFMT_POSIX_EN DEFAULT_ENABLED +#endif + +#ifndef ATCACERT_DATEFMT_GEN_EN +#define ATCACERT_DATEFMT_GEN_EN DEFAULT_ENABLED +#endif + +#endif /* ATCACERT_CHECK_CONFIG_H */ diff --git a/lib/atcacert/atcacert_client.c b/lib/atcacert/atcacert_client.c index c8a03dfc5..6b02a2d72 100644 --- a/lib/atcacert/atcacert_client.c +++ b/lib/atcacert/atcacert_client.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" #include "calib/calib_basic.h" +#if ATCAB_WRITE_EN // Perform floor integer division (-1 / 2 == -1) instead of truncate towards zero (-1 / 2 == 0) static int floor_div(int a, int b) { @@ -43,6 +44,7 @@ static int floor_div(int a, int b) return r ? (d - ((a < 0) ^ (b < 0))) : d; } +#endif int atcacert_get_response(uint8_t device_private_key_slot, const uint8_t challenge[32], @@ -172,6 +174,7 @@ int atcacert_read_cert(const atcacert_def_t* cert_def, return ATCACERT_E_SUCCESS; } +#if ATCAB_WRITE_EN int atcacert_write_cert(const atcacert_def_t* cert_def, const uint8_t* cert, size_t cert_size) @@ -239,6 +242,7 @@ int atcacert_write_cert(const atcacert_def_t* cert_def, return ATCACERT_E_SUCCESS; } +#endif int atcacert_create_csr_pem(const atcacert_def_t* csr_def, char* csr, size_t* csr_size) { @@ -424,7 +428,10 @@ int atcacert_read_cert_size(const atcacert_def_t* cert_def, if (ATCACERT_E_SUCCESS == ret) { - ret = atcab_read_sig(cert_def->comp_cert_dev_loc.slot, &buffer[8]); + ret = atcab_read_bytes_zone(cert_def->comp_cert_dev_loc.zone, + cert_def->comp_cert_dev_loc.slot, + cert_def->comp_cert_dev_loc.offset, + &buffer[8], ATCA_ECCP256_SIG_SIZE); } if (ATCACERT_E_SUCCESS == ret) diff --git a/lib/atcacert/atcacert_date.c b/lib/atcacert/atcacert_date.c index 66ae26ee8..a6f5698f2 100644 --- a/lib/atcacert/atcacert_date.c +++ b/lib/atcacert/atcacert_date.c @@ -60,11 +60,19 @@ int atcacert_date_enc(atcacert_date_format_t format, } switch (format) { +#if ATCACERT_DATEFMT_ISO_EN case DATEFMT_ISO8601_SEP: return atcacert_date_enc_iso8601_sep(timestamp, formatted_date); +#endif +#if ATCACERT_DATEFMT_UTC_EN case DATEFMT_RFC5280_UTC: return atcacert_date_enc_rfc5280_utc(timestamp, formatted_date); +#endif +#if ATCACERT_DATEFMT_POSIX_EN case DATEFMT_POSIX_UINT32_BE: return atcacert_date_enc_posix_uint32_be(timestamp, formatted_date); case DATEFMT_POSIX_UINT32_LE: return atcacert_date_enc_posix_uint32_le(timestamp, formatted_date); +#endif +#if ATCACERT_DATEFMT_GEN_EN case DATEFMT_RFC5280_GEN: return atcacert_date_enc_rfc5280_gen(timestamp, formatted_date); +#endif default: break; } @@ -88,11 +96,19 @@ int atcacert_date_dec(atcacert_date_format_t format, } switch (format) { +#if ATCACERT_DATEFMT_ISO_EN case DATEFMT_ISO8601_SEP: return atcacert_date_dec_iso8601_sep(formatted_date, timestamp); +#endif +#if ATCACERT_DATEFMT_UTC_EN case DATEFMT_RFC5280_UTC: return atcacert_date_dec_rfc5280_utc(formatted_date, timestamp); +#endif +#if ATCACERT_DATEFMT_POSIX_EN case DATEFMT_POSIX_UINT32_BE: return atcacert_date_dec_posix_uint32_be(formatted_date, timestamp); case DATEFMT_POSIX_UINT32_LE: return atcacert_date_dec_posix_uint32_le(formatted_date, timestamp); +#endif +#if ATCACERT_DATEFMT_GEN_EN case DATEFMT_RFC5280_GEN: return atcacert_date_dec_rfc5280_gen(formatted_date, timestamp); +#endif default: break; } @@ -109,6 +125,7 @@ int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* switch (format) { +#if ATCACERT_DATEFMT_ISO_EN case DATEFMT_ISO8601_SEP: timestamp->tm_year = 9999 - 1900; timestamp->tm_mon = 12 - 1; @@ -117,7 +134,8 @@ int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* timestamp->tm_min = 59; timestamp->tm_sec = 59; break; - +#endif +#if ATCACERT_DATEFMT_UTC_EN case DATEFMT_RFC5280_UTC: timestamp->tm_year = 2049 - 1900; timestamp->tm_mon = 12 - 1; @@ -126,7 +144,8 @@ int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* timestamp->tm_min = 59; timestamp->tm_sec = 59; break; - +#endif +#if ATCACERT_DATEFMT_POSIX_EN case DATEFMT_POSIX_UINT32_BE: timestamp->tm_year = 2106 - 1900; timestamp->tm_mon = 2 - 1; @@ -144,7 +163,8 @@ int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* timestamp->tm_min = 28; timestamp->tm_sec = 15; break; - +#endif +#if ATCACERT_DATEFMT_GEN_EN case DATEFMT_RFC5280_GEN: timestamp->tm_year = 9999 - 1900; timestamp->tm_mon = 12 - 1; @@ -153,7 +173,7 @@ int atcacert_date_get_max_date(atcacert_date_format_t format, atcacert_tm_utc_t* timestamp->tm_min = 59; timestamp->tm_sec = 59; break; - +#endif default: return ATCACERT_E_BAD_PARAMS; } @@ -245,6 +265,7 @@ static const uint8_t* str_to_int(const uint8_t* str, int width, int* num) return ret; } +#if ATCACERT_DATEFMT_ISO_EN int atcacert_date_enc_iso8601_sep(const atcacert_tm_utc_t* timestamp, uint8_t formatted_date[DATEFMT_ISO8601_SEP_SIZE]) { @@ -398,7 +419,9 @@ int atcacert_date_dec_iso8601_sep(const uint8_t formatted_date[DATEFMT_ISO8 } return ATCACERT_E_SUCCESS; } +#endif +#if ATCACERT_DATEFMT_UTC_EN int atcacert_date_enc_rfc5280_utc(const atcacert_tm_utc_t* timestamp, uint8_t formatted_date[DATEFMT_RFC5280_UTC_SIZE]) { @@ -533,7 +556,9 @@ int atcacert_date_dec_rfc5280_utc(const uint8_t formatted_date[DATEFMT_RFC5 } return ATCACERT_E_SUCCESS; } +#endif +#if ATCACERT_DATEFMT_GEN_EN int atcacert_date_enc_rfc5280_gen(const atcacert_tm_utc_t* timestamp, uint8_t formatted_date[DATEFMT_RFC5280_GEN_SIZE]) { @@ -652,7 +677,9 @@ int atcacert_date_dec_rfc5280_gen(const uint8_t formatted_date[DATEFMT_RFC5 } return ATCACERT_E_SUCCESS; } +#endif +#if ATCACERT_DATEFMT_POSIX_EN static int is_leap_year(int year) { return (year % 400 == 0) || ((year % 4 == 0) && (year % 100 != 0)); @@ -987,6 +1014,7 @@ int atcacert_date_dec_posix_uint32_le(const uint8_t formatted_date[DATEFMT_ return atcacert_date_dec_posix_uint32(posix_uint32, timestamp); } +#endif int atcacert_date_enc_compcert(const atcacert_tm_utc_t* issue_date, uint8_t expire_years, diff --git a/lib/atcacert/atcacert_def.c b/lib/atcacert/atcacert_def.c index 5da56ec3f..54e841f52 100644 --- a/lib/atcacert/atcacert_def.c +++ b/lib/atcacert/atcacert_def.c @@ -722,19 +722,16 @@ int atcacert_set_signature(const atcacert_def_t* cert_def, const uint8_t signature[64]) { int ret = 0; - int16_t sig_offset; + size_t sig_offset; size_t cur_der_sig_size; size_t new_der_sig_size; size_t old_cert_der_length_size; uint32_t new_cert_length; - if (cert_def == NULL || cert == NULL || cert_size == NULL || signature == NULL) - { - return ATCACERT_E_BAD_PARAMS; - } + ATCA_CHECK_INVALID((!cert_def || !cert || !cert_size || !signature), ATCACERT_E_BAD_PARAMS); - sig_offset = (int16_t)cert_def->std_cert_elements[STDCERT_SIGNATURE].offset; - sig_offset += get_effective_offset(cert_def, cert, (uint16_t)sig_offset); + sig_offset = (size_t)cert_def->std_cert_elements[STDCERT_SIGNATURE].offset; + sig_offset += get_effective_offset(cert_def, cert, sig_offset); // Non X.509 signatures are treated like normal certificate elements if (cert_def->type != CERTTYPE_X509) @@ -748,10 +745,10 @@ int atcacert_set_signature(const atcacert_def_t* cert_def, } // Current size of the signature is from its offset to the end of the cert - cur_der_sig_size = *cert_size - (uint16_t)sig_offset; + cur_der_sig_size = *cert_size - sig_offset; // Find the size of buffer available for the new DER signature - new_der_sig_size = max_cert_size - (uint16_t)sig_offset; + new_der_sig_size = max_cert_size - sig_offset; // Set the new signature ret = atcacert_der_enc_ecdsa_sig_value(signature, &cert[sig_offset], &new_der_sig_size); @@ -791,7 +788,7 @@ int atcacert_get_signature(const atcacert_def_t* cert_def, size_t cert_size, uint8_t signature[64]) { - int16_t sig_offset; + size_t sig_offset; size_t der_sig_size = 0; if (cert_def == NULL || cert == NULL || signature == NULL) @@ -799,8 +796,8 @@ int atcacert_get_signature(const atcacert_def_t* cert_def, return ATCACERT_E_BAD_PARAMS; } - sig_offset = (int16_t)cert_def->std_cert_elements[STDCERT_SIGNATURE].offset; - sig_offset += get_effective_offset(cert_def, cert, (uint16_t)sig_offset); + sig_offset = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset; + sig_offset += get_effective_offset(cert_def, cert, sig_offset); // Non X.509 signatures are treated like normal certificate elements if (cert_def->type != CERTTYPE_X509) @@ -813,7 +810,7 @@ int atcacert_get_signature(const atcacert_def_t* cert_def, return ATCACERT_E_ELEM_OUT_OF_BOUNDS; // Signature element is shown as past the end of the certificate } - der_sig_size = cert_size - (uint16_t)sig_offset; + der_sig_size = cert_size - sig_offset; return atcacert_der_dec_ecdsa_sig_value(&cert[sig_offset], &der_sig_size, signature); } diff --git a/lib/atcacert/atcacert_der.c b/lib/atcacert/atcacert_der.c index 40f2466c2..53c359226 100644 --- a/lib/atcacert/atcacert_der.c +++ b/lib/atcacert/atcacert_der.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ - +#include "cryptoauthlib.h" #include "atcacert_der.h" #include @@ -193,10 +193,7 @@ int atcacert_der_enc_integer(const uint8_t* int_data, size_t pad = 0; int ret; - if (int_data == NULL || der_int_size == NULL || int_data_size <= 0) - { - return ATCACERT_E_BAD_PARAMS; - } + ATCA_CHECK_INVALID((int_data == NULL || der_int_size == NULL || int_data_size <= 0), ATCACERT_E_BAD_PARAMS); if (!(is_unsigned && (int_data[0] & 0x80))) { @@ -318,10 +315,7 @@ int atcacert_der_enc_ecdsa_sig_value(const uint8_t raw_sig[64], size_t s_size = 0; size_t der_sig_size_calc = 0; - if (raw_sig == NULL || der_sig_size == NULL) - { - return ATCACERT_E_BAD_PARAMS; - } + ATCA_CHECK_INVALID((!raw_sig || !der_sig_size), ATCACERT_E_BAD_PARAMS); // Find size of the DER encoded R integer ret = atcacert_der_enc_integer(&raw_sig[0], 32, TRUE, NULL, &r_size); diff --git a/lib/atcacert/atcacert_host_hw.c b/lib/atcacert/atcacert_host_hw.c index 7388aad5e..273283db3 100644 --- a/lib/atcacert/atcacert_host_hw.c +++ b/lib/atcacert/atcacert_host_hw.c @@ -30,9 +30,7 @@ #include "crypto/atca_crypto_sw_sha2.h" - - - +#if ATCACERT_HW_VERIFY_EN int atcacert_verify_cert_hw(const atcacert_def_t* cert_def, const uint8_t* cert, size_t cert_size, @@ -68,10 +66,9 @@ int atcacert_verify_cert_hw(const atcacert_def_t* cert_def, return is_verified ? ATCACERT_E_SUCCESS : ATCACERT_E_VERIFY_FAILED; } +#endif - - - +#if ATCACERT_HW_CHALLENGE_EN int atcacert_gen_challenge_hw(uint8_t challenge[32]) { if (challenge == NULL) @@ -81,8 +78,9 @@ int atcacert_gen_challenge_hw(uint8_t challenge[32]) return atcab_random(challenge); } +#endif - +#if ATCACERT_HW_VERIFY_EN int atcacert_verify_response_hw(const uint8_t device_public_key[64], const uint8_t challenge[32], const uint8_t response[64]) @@ -103,3 +101,4 @@ int atcacert_verify_response_hw(const uint8_t device_public_key[64], return is_verified ? ATCACERT_E_SUCCESS : ATCACERT_E_VERIFY_FAILED; } +#endif diff --git a/lib/atcacert/atcacert_host_sw.c b/lib/atcacert/atcacert_host_sw.c index e3069c616..a141b997b 100644 --- a/lib/atcacert/atcacert_host_sw.c +++ b/lib/atcacert/atcacert_host_sw.c @@ -26,15 +26,9 @@ */ #include "atcacert_host_sw.h" -#include "crypto/atca_crypto_sw_sha2.h" -#include "crypto/atca_crypto_sw_ecdsa.h" -#include "crypto/atca_crypto_sw_rand.h" - - - - - +#include "crypto/atca_crypto_sw.h" +#if ATCAC_VERIFY_EN int atcacert_verify_cert_sw(const atcacert_def_t* cert_def, const uint8_t* cert, size_t cert_size, @@ -43,6 +37,7 @@ int atcacert_verify_cert_sw(const atcacert_def_t* cert_def, int ret = 0; uint8_t tbs_digest[32]; uint8_t signature[64]; + atcac_pk_ctx pkey_ctx; if (cert_def == NULL || ca_public_key == NULL || cert == NULL) { @@ -61,17 +56,24 @@ int atcacert_verify_cert_sw(const atcacert_def_t* cert_def, return ret; } - ret = atcac_sw_ecdsa_verify_p256(tbs_digest, signature, ca_public_key); + /* Initialize the key using the provided X,Y cordinantes */ + ret = atcac_pk_init(&pkey_ctx, ca_public_key, 64, 0, true); if (ret != ATCACERT_E_SUCCESS) { return ret; } - return ATCACERT_E_SUCCESS; -} + /* Perform the verification */ + ret = atcac_pk_verify(&pkey_ctx, tbs_digest, sizeof(tbs_digest), signature, sizeof(signature)); + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + return ret; +} +#endif /* ATCAC_VERIFY_EN */ +#if ATCAC_RANDOM_EN int atcacert_gen_challenge_sw(uint8_t challenge[32]) { if (challenge == NULL) @@ -81,17 +83,34 @@ int atcacert_gen_challenge_sw(uint8_t challenge[32]) return atcac_sw_random(challenge, 32); } +#endif /* ATCAC_RANDOM_EN */ - - +#if ATCAC_VERIFY_EN int atcacert_verify_response_sw(const uint8_t device_public_key[64], const uint8_t challenge[32], const uint8_t response[64]) { + atcac_pk_ctx pkey_ctx; + int ret = ATCACERT_E_BAD_PARAMS; + if (device_public_key == NULL || challenge == NULL || response == NULL) { - return ATCACERT_E_BAD_PARAMS; + return ret; } - return atcac_sw_ecdsa_verify_p256(challenge, response, device_public_key); + /* Initialize the key using the provided X,Y cordinantes */ + ret = atcac_pk_init(&pkey_ctx, device_public_key, 64, 0, true); + if (ret != ATCACERT_E_SUCCESS) + { + return ret; + } + + /* Perform the verification */ + ret = atcac_pk_verify(&pkey_ctx, challenge, 32, response, 32); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + return ret; } +#endif /* ATCAC_VERIFY_EN */ diff --git a/lib/calib/calib_aes.c b/lib/calib/calib_aes.c index 2979ac92c..e0767bffe 100644 --- a/lib/calib/calib_aes.c +++ b/lib/calib/calib_aes.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_AES_EN /** \brief Compute the AES-128 encrypt, decrypt, or GFM calculation. * * \param[in] device Device context pointer @@ -134,7 +135,9 @@ ATCA_STATUS calib_aes_decrypt(ATCADevice device, uint16_t key_id, uint8_t key_bl mode = AES_MODE_DECRYPT | (AES_MODE_KEY_BLOCK_MASK & (key_block << AES_MODE_KEY_BLOCK_POS)); return calib_aes(device, mode, key_id, ciphertext, plaintext); } +#endif +#if CALIB_AES_EN && CALIB_AES_GCM_EN /** \brief Perform a Galois Field Multiply (GFM) operation. * * \param[in] device Device context pointer @@ -153,3 +156,4 @@ ATCA_STATUS calib_aes_gfm(ATCADevice device, const uint8_t* h, const uint8_t* in // KeyID is ignored for GFM mode return calib_aes(device, AES_MODE_GFM, 0x0000, aes_in, output); } +#endif /* CALIB_AES_MODE_ENCODING */ diff --git a/lib/calib/calib_aes_gcm.c b/lib/calib/calib_aes_gcm.c index d7ee27494..eafaf15be 100644 --- a/lib/calib/calib_aes_gcm.c +++ b/lib/calib/calib_aes_gcm.c @@ -34,8 +34,12 @@ */ #include "cryptoauthlib.h" + +#if CALIB_AES_GCM_EN + #include "calib_aes_gcm.h" + /** \ingroup calib_ * @{ */ @@ -593,5 +597,5 @@ ATCA_STATUS calib_aes_gcm_decrypt_finish(ATCADevice device, atca_aes_gcm_ctx_t* return ATCA_SUCCESS; } - +#endif /* CALIB_AES_GCM */ /** @} */ diff --git a/lib/calib/calib_aes_gcm.h b/lib/calib/calib_aes_gcm.h index c242f59c7..a2d51e30c 100644 --- a/lib/calib/calib_aes_gcm.h +++ b/lib/calib/calib_aes_gcm.h @@ -35,6 +35,10 @@ extern "C" { #endif +#include "calib_config_check.h" + +#if CALIB_AES_GCM_EN + #define ATCA_AES_GCM_IV_STD_LENGTH 12 extern const char* atca_basic_aes_gcm_version; @@ -67,6 +71,8 @@ ATCA_STATUS calib_aes_gcm_encrypt_finish(ATCADevice device, atca_aes_gcm_ctx_t* ATCA_STATUS calib_aes_gcm_decrypt_update(ATCADevice device, atca_aes_gcm_ctx_t* ctx, const uint8_t* ciphertext, uint32_t ciphertext_size, uint8_t* plaintext); ATCA_STATUS calib_aes_gcm_decrypt_finish(ATCADevice device, atca_aes_gcm_ctx_t* ctx, const uint8_t* tag, size_t tag_size, bool* is_verified); +#endif + #ifdef __cplusplus } #endif diff --git a/lib/calib/calib_basic.c b/lib/calib/calib_basic.c index cf37063d6..693e03181 100644 --- a/lib/calib/calib_basic.c +++ b/lib/calib/calib_basic.c @@ -50,7 +50,7 @@ ATCA_STATUS calib_wakeup_i2c(ATCADevice device) do { - if (100000UL < iface->mIfaceCFG->atcai2c.baud) + if (100000UL < ATCA_IFACECFG_VALUE(iface->mIfaceCFG, atcai2c.baud)) { temp = 100000UL; status = atcontrol(iface, ATCA_HAL_CHANGE_BAUD, &temp, sizeof(temp)); @@ -86,9 +86,9 @@ ATCA_STATUS calib_wakeup_i2c(ATCADevice device) status = atreceive(iface, address, (uint8_t*)&wake, &rxlen); } - if ((ATCA_SUCCESS == status) && (100000UL < iface->mIfaceCFG->atcai2c.baud)) + if ((ATCA_SUCCESS == status) && (100000UL < ATCA_IFACECFG_VALUE(iface->mIfaceCFG, atcai2c.baud))) { - temp = iface->mIfaceCFG->atcai2c.baud; + temp = ATCA_IFACECFG_VALUE(iface->mIfaceCFG, atcai2c.baud); status = atcontrol(iface, ATCA_HAL_CHANGE_BAUD, &temp, sizeof(temp)); } @@ -244,6 +244,7 @@ ATCA_STATUS calib_get_addr(uint8_t zone, uint16_t slot, uint8_t block, uint8_t o return status; } +#ifdef ATCA_ECC204_SUPPORT /** \brief Compute the address given the zone, slot, block, and offset for ECC204 device * \param[in] zone Zone to get address from. Config(1) or * Data(0) which requires a slot. @@ -273,6 +274,7 @@ ATCA_STATUS calib_ecc204_get_addr(uint8_t zone, uint16_t slot, uint8_t block, ui return status; } +#endif /** \brief Gets the size of the specified zone in bytes. * @@ -295,6 +297,7 @@ ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, if (device->mIface.mIfaceCFG->devtype == ATSHA204A) { +#ifdef ATCA_ATSHA204A_SUPPORT switch (zone) { case ATCA_ZONE_CONFIG: *size = 88; break; @@ -302,7 +305,9 @@ ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, case ATCA_ZONE_DATA: *size = 32; break; default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } +#endif } +#ifdef ATCA_ATSHA206A_SUPPORT else if (device->mIface.mIfaceCFG->devtype == ATSHA206A) { switch (zone) @@ -313,6 +318,7 @@ ATCA_STATUS calib_get_zone_size(ATCADevice device, uint8_t zone, uint16_t slot, default: status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); break; } } +#endif #ifdef ATCA_ECC204_SUPPORT else if (ECC204 == device->mIface.mIfaceCFG->devtype) { diff --git a/lib/calib/calib_basic.h b/lib/calib/calib_basic.h index f5d3c3577..db6070428 100644 --- a/lib/calib/calib_basic.h +++ b/lib/calib/calib_basic.h @@ -1,6 +1,9 @@ #ifndef _CALIB_H #define _CALIB_H +/* Library Configuration */ +#include "calib_config_check.h" + #include "calib_command.h" #include "calib_execution.h" @@ -25,83 +28,119 @@ ATCA_STATUS calib_ecc204_get_addr(uint8_t zone, uint16_t slot, uint8_t block, ui /* Helper Functions */ ATCA_STATUS calib_is_locked(ATCADevice device, uint8_t zone, bool* is_locked); +ATCA_STATUS calib_is_locked_ext(ATCADevice device, uint8_t zone, bool* is_locked); ATCA_STATUS calib_is_slot_locked(ATCADevice device, uint16_t slot, bool* is_locked); ATCA_STATUS calib_is_private(ATCADevice device, uint16_t slot, bool* is_private); ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_locked); ATCA_STATUS calib_ecc204_is_data_locked(ATCADevice device, bool* is_locked); ATCA_STATUS calib_ecc204_is_config_locked(ATCADevice device, bool* is_locked); +ATCADeviceType calib_get_devicetype(uint8_t revision[4]); //AES command functions +#if CALIB_AES_EN ATCA_STATUS calib_aes(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* aes_in, uint8_t* aes_out); ATCA_STATUS calib_aes_encrypt(ATCADevice device, uint16_t key_id, uint8_t key_block, const uint8_t* plaintext, uint8_t* ciphertext); ATCA_STATUS calib_aes_decrypt(ATCADevice device, uint16_t key_id, uint8_t key_block, const uint8_t* ciphertext, uint8_t* plaintext); +#endif +#if CALIB_AES_GCM_EN ATCA_STATUS calib_aes_gfm(ATCADevice device, const uint8_t* h, const uint8_t* input, uint8_t* output); +#endif //CheckMAC command functions +#if CALIB_CHECKMAC_EN ATCA_STATUS calib_checkmac(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t *challenge, const uint8_t *response, const uint8_t *other_data); +#endif // Counter command functions +#if CALIB_COUNTER_EN ATCA_STATUS calib_counter(ATCADevice device, uint8_t mode, uint16_t counter_id, uint32_t* counter_value); ATCA_STATUS calib_counter_increment(ATCADevice device, uint16_t counter_id, uint32_t* counter_value); ATCA_STATUS calib_counter_read(ATCADevice device, uint16_t counter_id, uint32_t* counter_value); +#endif // DeriveKey command functions +#if CALIB_DERIVEKEY_EN ATCA_STATUS calib_derivekey(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* mac); +#endif // ECDH command functions +#if CALIB_ECDH_EN ATCA_STATUS calib_ecdh_base(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* public_key, uint8_t* pms, uint8_t* out_nonce); ATCA_STATUS calib_ecdh(ATCADevice device, uint16_t key_id, const uint8_t* public_key, uint8_t* pms); +ATCA_STATUS calib_ecdh_tempkey(ATCADevice device, const uint8_t* public_key, uint8_t* pms); +#endif +#if CALIB_ECDH_ENC_EN #if defined(ATCA_USE_CONSTANT_HOST_NONCE) ATCA_STATUS calib_ecdh_enc(ATCADevice device, uint16_t key_id, const uint8_t* public_key, uint8_t* pms, const uint8_t* read_key, uint16_t read_key_id); #else ATCA_STATUS calib_ecdh_enc(ATCADevice device, uint16_t key_id, const uint8_t* public_key, uint8_t* pms, const uint8_t* read_key, uint16_t read_key_id, const uint8_t num_in[NONCE_NUMIN_SIZE]); -#endif - +#endif /* ATCA_USE_CONSTANT_HOST_NONCE */ ATCA_STATUS calib_ecdh_ioenc(ATCADevice device, uint16_t key_id, const uint8_t* public_key, uint8_t* pms, const uint8_t* io_key); -ATCA_STATUS calib_ecdh_tempkey(ATCADevice device, const uint8_t* public_key, uint8_t* pms); ATCA_STATUS calib_ecdh_tempkey_ioenc(ATCADevice device, const uint8_t* public_key, uint8_t* pms, const uint8_t* io_key); +#endif /* CALIB_ECDH_ENC_EN */ // GenDig command functions +#if CALIB_GENDIG_EN ATCA_STATUS calib_gendig(ATCADevice device, uint8_t zone, uint16_t key_id, const uint8_t *other_data, uint8_t other_data_size); +#endif // GenKey command functions +#if CALIB_GENKEY_EN ATCA_STATUS calib_genkey_base(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* other_data, uint8_t* public_key); ATCA_STATUS calib_genkey(ATCADevice device, uint16_t key_id, uint8_t* public_key); ATCA_STATUS calib_get_pubkey(ATCADevice device, uint16_t key_id, uint8_t* public_key); +#endif +#if CALIB_GENKEY_MAC_EN ATCA_STATUS calib_genkey_mac(ATCADevice device, uint8_t* public_key, uint8_t* mac); +#endif // HMAC command functions +#if CALIB_HMAC_EN ATCA_STATUS calib_hmac(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t* digest); +#endif // Info command functions ATCA_STATUS calib_info_base(ATCADevice device, uint8_t mode, uint16_t param2, uint8_t* out_data); ATCA_STATUS calib_info(ATCADevice device, uint8_t* revision); -ATCA_STATUS calib_info_set_latch(ATCADevice device, bool state); -ATCA_STATUS calib_info_get_latch(ATCADevice device, bool* state); ATCA_STATUS calib_info_privkey_valid(ATCADevice device, uint16_t key_id, uint8_t* is_valid); ATCA_STATUS calib_info_lock_status(ATCADevice device, uint16_t param2, uint8_t* is_locked); +#if CALIB_INFO_LATCH_EN +ATCA_STATUS calib_info_set_latch(ATCADevice device, bool state); +ATCA_STATUS calib_info_get_latch(ATCADevice device, bool* state); +#endif // KDF command functions +#if CALIB_KDF_EN ATCA_STATUS calib_kdf(ATCADevice device, uint8_t mode, uint16_t key_id, const uint32_t details, const uint8_t* message, uint8_t* out_data, uint8_t* out_nonce); +#endif // Lock command functions +#if CALIB_LOCK_EN || CALIB_LOCK_ECC204_EN ATCA_STATUS calib_lock(ATCADevice device, uint8_t mode, uint16_t summary_crc); +#endif +#if CALIB_LOCK_EN ATCA_STATUS calib_lock_config_zone(ATCADevice device); ATCA_STATUS calib_lock_config_zone_crc(ATCADevice device, uint16_t summary_crc); ATCA_STATUS calib_lock_data_zone(ATCADevice device); ATCA_STATUS calib_lock_data_zone_crc(ATCADevice device, uint16_t summary_crc); ATCA_STATUS calib_lock_data_slot(ATCADevice device, uint16_t slot); +#endif // Lock ECC204 command functions +#if CALIB_LOCK_ECC204_EN ATCA_STATUS calib_ecc204_lock_config_slot(ATCADevice device, uint16_t slot, uint16_t summary_crc); ATCA_STATUS calib_ecc204_lock_config_zone(ATCADevice device); ATCA_STATUS calib_ecc204_lock_data_slot(ATCADevice device, uint16_t slot); ATCA_STATUS calib_ecc204_lock_data_zone(ATCADevice device); +#endif // MAC command functions +#if CALIB_MAC_EN ATCA_STATUS calib_mac(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* challenge, uint8_t* digest); +#endif // Nonce command functions +#if CALIB_NONCE_EN ATCA_STATUS calib_nonce_base(ATCADevice device, uint8_t mode, uint16_t zero, const uint8_t *num_in, uint8_t* rand_out); ATCA_STATUS calib_nonce(ATCADevice device, const uint8_t *num_in); ATCA_STATUS calib_nonce_load(ATCADevice device, uint8_t target, const uint8_t *num_in, uint16_t num_in_size); @@ -110,46 +149,72 @@ ATCA_STATUS calib_challenge(ATCADevice device, const uint8_t *num_in); ATCA_STATUS calib_challenge_seed_update(ATCADevice device, const uint8_t *num_in, uint8_t* rand_out); ATCA_STATUS calib_nonce_gen_session_key(ATCADevice device, uint16_t param2, uint8_t* num_in, uint8_t* rand_out); +#endif // PrivWrite command functions - +#if CALIB_PRIVWRITE_EN #if defined(ATCA_USE_CONSTANT_HOST_NONCE) ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t priv_key[36], uint16_t write_key_id, const uint8_t write_key[32]); #else ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t priv_key[36], uint16_t write_key_id, const uint8_t write_key[32], const uint8_t num_in[NONCE_NUMIN_SIZE]); #endif +#endif /* CALIB_PRIVWRITE_EN */ + // Random command functions +#if CALIB_RANDOM_EN ATCA_STATUS calib_random(ATCADevice device, uint8_t* rand_out); +#endif // Read command functions +#if CALIB_READ_EN ATCA_STATUS calib_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint8_t *data, uint8_t len); ATCA_STATUS calib_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length); +ATCA_STATUS calib_read_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length); ATCA_STATUS calib_read_serial_number(ATCADevice device, uint8_t* serial_number); -ATCA_STATUS calib_read_pubkey(ATCADevice device, uint16_t slot, uint8_t *public_key); -ATCA_STATUS calib_read_sig(ATCADevice device, uint16_t slot, uint8_t *sig); -ATCA_STATUS calib_read_config_zone(ATCADevice device, uint8_t* config_data); -ATCA_STATUS calib_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config); +ATCA_STATUS calib_read_serial_number_ext(ATCADevice device, uint8_t* serial_number); +bool calib_sha_compare_config(uint8_t* expected, uint8_t* other); +bool calib_ecc_compare_config(uint8_t* expected, uint8_t* other); +bool calib_ecc608_compare_config(uint8_t* expected, uint8_t* other); +#endif // ECC204 Read command functions +#if CALIB_READ_ECC204_EN ATCA_STATUS calib_ecc204_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, size_t offset, uint8_t* data, uint8_t len); -ATCA_STATUS calib_ecc204_read_config_zone(ATCADevice device, uint8_t* config_data); -ATCA_STATUS calib_ecc204_read_serial_number(ATCADevice device, uint8_t* serial_number); ATCA_STATUS calib_ecc204_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t block, uint8_t* data, size_t length); -ATCA_STATUS calib_ecc204_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config); +ATCA_STATUS calib_ecc204_read_serial_number(ATCADevice device, uint8_t* serial_number); +ATCA_STATUS calib_ecc204_read_config_zone(ATCADevice device, uint8_t* config_data); +bool calib_ecc204_compare_config(uint8_t* expected, uint8_t* other); +#endif +#if CALIB_READ_EN || CALIB_READ_ECC204_EN +ATCA_STATUS calib_read_config_zone(ATCADevice device, uint8_t* config_data); +ATCA_STATUS calib_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config); +ATCA_STATUS calib_read_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, uint8_t *data, uint8_t len); +ATCA_STATUS calib_read_pubkey(ATCADevice device, uint16_t slot, uint8_t *public_key); +ATCA_STATUS calib_read_sig(ATCADevice device, uint16_t slot, uint8_t *sig); +#endif + +#if CALIB_READ_ENC_EN #if defined(ATCA_USE_CONSTANT_HOST_NONCE) ATCA_STATUS calib_read_enc(ATCADevice device, uint16_t key_id, uint8_t block, uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id); #else ATCA_STATUS calib_read_enc(ATCADevice device, uint16_t key_id, uint8_t block, uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id, const uint8_t num_in[NONCE_NUMIN_SIZE]); #endif +#endif /* CALIB_READ_ENC_EN */ // SecureBoot command functions +#if CALIB_SECUREBOOT_EN ATCA_STATUS calib_secureboot(ATCADevice device, uint8_t mode, uint16_t param2, const uint8_t* digest, const uint8_t* signature, uint8_t* mac); +#endif +#if CALIB_SECUREBOOT_MAC_EN ATCA_STATUS calib_secureboot_mac(ATCADevice device, uint8_t mode, const uint8_t* digest, const uint8_t* signature, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); +#endif // SelfTest command functions +#if CALIB_SELFTEST_EN ATCA_STATUS calib_selftest(ATCADevice device, uint8_t mode, uint16_t param2, uint8_t* result); +#endif // SHA command functions typedef struct atca_sha256_ctx @@ -161,6 +226,7 @@ typedef struct atca_sha256_ctx typedef atca_sha256_ctx_t atca_hmac_sha256_ctx_t; +#if CALIB_SHA_EN ATCA_STATUS calib_sha_base(ATCADevice device, uint8_t mode, uint16_t length, const uint8_t* data_in, uint8_t* data_out, uint16_t* data_out_size); ATCA_STATUS calib_sha_start(ATCADevice device); ATCA_STATUS calib_sha_update(ATCADevice device, const uint8_t* message); @@ -172,37 +238,84 @@ ATCA_STATUS calib_hw_sha2_256(ATCADevice device, const uint8_t * data, size_t da ATCA_STATUS calib_hw_sha2_256_init(ATCADevice device, atca_sha256_ctx_t* ctx); ATCA_STATUS calib_hw_sha2_256_update(ATCADevice device, atca_sha256_ctx_t* ctx, const uint8_t* data, size_t data_size); ATCA_STATUS calib_hw_sha2_256_finish(ATCADevice device, atca_sha256_ctx_t* ctx, uint8_t* digest); +#endif +#if CALIB_SHA_HMAC_EN ATCA_STATUS calib_sha_hmac_init(ATCADevice device, atca_hmac_sha256_ctx_t* ctx, uint16_t key_slot); ATCA_STATUS calib_sha_hmac_update(ATCADevice device, atca_hmac_sha256_ctx_t* ctx, const uint8_t* data, size_t data_size); ATCA_STATUS calib_sha_hmac_finish(ATCADevice device, atca_hmac_sha256_ctx_t* ctx, uint8_t* digest, uint8_t target); ATCA_STATUS calib_sha_hmac(ATCADevice device, const uint8_t * data, size_t data_size, uint16_t key_slot, uint8_t* digest, uint8_t target); +#endif // Sign command functions +#if CALIB_SIGN_EN ATCA_STATUS calib_sign_base(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t *signature); ATCA_STATUS calib_sign(ATCADevice device, uint16_t key_id, const uint8_t *msg, uint8_t *signature); +ATCA_STATUS calib_sign_ext(ATCADevice device, uint16_t key_id, const uint8_t *msg, uint8_t *signature); +#endif +#if CALIB_SIGN_INTERNAL_EN ATCA_STATUS calib_sign_internal(ATCADevice device, uint16_t key_id, bool is_invalidate, bool is_full_sn, uint8_t *signature); +#endif // ECC204 Sign command functions +#if CALIB_SIGN_ECC204_EN ATCA_STATUS calib_ecc204_sign(ATCADevice device, uint16_t key_id, const uint8_t* msg, uint8_t* signature); +#endif // UpdateExtra command functions +#if CALIB_UPDATEEXTRA_EN ATCA_STATUS calib_updateextra(ATCADevice device, uint8_t mode, uint16_t new_value); +#endif // Verify command functions +#if CALIB_VERIFY_EXTERN_EN || CALIB_VERIFY_STORED_EN ATCA_STATUS calib_verify(ATCADevice device, uint8_t mode, uint16_t key_id, const uint8_t* signature, const uint8_t* public_key, const uint8_t* other_data, uint8_t* mac); +#endif + +#if CALIB_VERIFY_EXTERN_EN ATCA_STATUS calib_verify_extern(ATCADevice device, const uint8_t *message, const uint8_t *signature, const uint8_t *public_key, bool *is_verified); +#if CALIB_VERIFY_MAC_EN ATCA_STATUS calib_verify_extern_mac(ATCADevice device, const uint8_t *message, const uint8_t* signature, const uint8_t* public_key, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); +#endif +#endif + +#if CALIB_VERIFY_STORED_EN ATCA_STATUS calib_verify_stored(ATCADevice device, const uint8_t *message, const uint8_t *signature, uint16_t key_id, bool *is_verified); +ATCA_STATUS calib_verify_stored_with_tempkey(ATCADevice device, const uint8_t* signature, uint16_t key_id, bool* is_verified); +#if CALIB_VERIFY_MAC_EN ATCA_STATUS calib_verify_stored_mac(ATCADevice device, const uint8_t *message, const uint8_t *signature, uint16_t key_id, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified); +#endif +#endif + +#if CALIB_VERIFY_VALIDATE_EN ATCA_STATUS calib_verify_validate(ATCADevice device, uint16_t key_id, const uint8_t *signature, const uint8_t *other_data, bool *is_verified); ATCA_STATUS calib_verify_invalidate(ATCADevice device, uint16_t key_id, const uint8_t *signature, const uint8_t *other_data, bool *is_verified); +#endif // Write command functions +#if CALIB_WRITE_EN ATCA_STATUS calib_write(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac); +ATCA_STATUS calib_write_ext(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac); ATCA_STATUS calib_write_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, const uint8_t *data, uint8_t len); ATCA_STATUS calib_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t *data, size_t length); -ATCA_STATUS calib_write_pubkey(ATCADevice device, uint16_t slot, const uint8_t *public_key); +ATCA_STATUS calib_write_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t *data, size_t length); ATCA_STATUS calib_write_config_zone(ATCADevice device, const uint8_t* config_data); +ATCA_STATUS calib_write_config_zone_ext(ATCADevice device, const uint8_t* config_data); +ATCA_STATUS calib_write_config_counter(ATCADevice device, uint16_t counter_id, uint32_t counter_value); +#endif +#if CALIB_WRITE_EN || CALIB_WRITE_ECC204_EN +ATCA_STATUS calib_write_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, const uint8_t *data, uint8_t len); +ATCA_STATUS calib_write_pubkey(ATCADevice device, uint16_t slot, const uint8_t *public_key); +#endif + +#if CALIB_WRITE_ENC_EN +#if defined(ATCA_USE_CONSTANT_HOST_NONCE) +ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id); +#else +ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id, const uint8_t num_in[NONCE_NUMIN_SIZE]); +#endif +#endif /* CALIB_WRITE_ENC_EN */ + // ECC204 Write command functions +#if CALIB_WRITE_ECC204_EN ATCA_STATUS calib_ecc204_write(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac); ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, @@ -210,22 +323,216 @@ ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t sl ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, const uint8_t* config_data); ATCA_STATUS calib_ecc204_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t block, const uint8_t *data, size_t length); +#endif /* CALIB_WRITE_ECC204_EN */ +#if CALIB_WRITE_ENC_ECC204_EN +ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* data, uint8_t* transport_key, + uint8_t key_id, uint8_t num_in[NONCE_NUMIN_SIZE]); +#endif /* CALIB_WRITE_ENC_ECC204_EN */ -#if defined(ATCA_USE_CONSTANT_HOST_NONCE) -ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id); +/* Map calib functions to atcab names for api compatibility without abstraction overhead */ +#if !ATCA_TA_SUPPORT && !defined(ATCA_USE_ATCAB_FUNCTIONS) + +#define atcab_wakeup() calib_wakeup(_gDevice) +#define atcab_idle() calib_idle(_gDevice) +#define atcab_sleep() calib_sleep(_gDevice) +#define _atcab_exit(...) _calib_exit(_gDevice, __VA_ARGS__) +#define atcab_get_zone_size(...) calib_get_zone_size(_gDevice, __VA_ARGS__) + + +// AES command functions +#define atcab_aes(...) calib_aes(_gDevice, __VA_ARGS__) +#define atcab_aes_encrypt(...) calib_aes_encrypt(_gDevice, __VA_ARGS__) +#define atcab_aes_encrypt_ext calib_aes_encrypt +#define atcab_aes_decrypt(...) calib_aes_decrypt(_gDevice, __VA_ARGS__) +#define atcab_aes_decrypt_ext calib_aes_decrypt +#define atcab_aes_gfm(...) calib_aes_gfm(_gDevice, __VA_ARGS__) + +#define atcab_aes_gcm_init(...) calib_aes_gcm_init(_gDevice, __VA_ARGS__) +#define atcab_aes_gcm_init_rand(...) calib_aes_gcm_init_rand(_gDevice, __VA_ARGS__) +#define atcab_aes_gcm_aad_update(...) calib_aes_gcm_aad_update(_gDevice, __VA_ARGS__) +#define atcab_aes_gcm_encrypt_update(...) calib_aes_gcm_encrypt_update(_gDevice, __VA_ARGS__) +#define atcab_aes_gcm_encrypt_finish(...) calib_aes_gcm_encrypt_finish(_gDevice, __VA_ARGS__) +#define atcab_aes_gcm_decrypt_update(...) calib_aes_gcm_decrypt_update(_gDevice, __VA_ARGS__) +#define atcab_aes_gcm_decrypt_finish(...) calib_aes_gcm_decrypt_finish(_gDevice, __VA_ARGS__) + +// CheckMAC command functions +#define atcab_checkmac(...) calib_checkmac(_gDevice, __VA_ARGS__) + +// Counter command functions +#define atcab_counter(...) calib_counter(_gDevice, __VA_ARGS__) +#define atcab_counter_increment(...) calib_counter_increment(_gDevice, __VA_ARGS__) +#define atcab_counter_read(...) calib_counter_read(_gDevice, __VA_ARGS__) + +// DeriveKey command functions +#define atcab_derivekey(...) calib_derivekey(_gDevice, __VA_ARGS__) + +// ECDH command functions +#define atcab_ecdh_base(...) calib_ecdh_base(_gDevice, __VA_ARGS__) +#define atcab_ecdh(...) calib_ecdh(_gDevice, __VA_ARGS__) +#define atcab_ecdh_enc(...) calib_ecdh_enc(_gDevice, __VA_ARGS__) +#define atcab_ecdh_ioenc(...) calib_ecdh_ioenc(_gDevice, __VA_ARGS__) +#define atcab_ecdh_tempkey(...) calib_ecdh_tempkey(_gDevice, __VA_ARGS__) +#define atcab_ecdh_tempkey_ioenc(...) calib_ecdh_tempkey_ioenc(_gDevice, __VA_ARGS__) + +// GenDig command functions +#define atcab_gendig(...) calib_gendig(_gDevice, __VA_ARGS__) + +// GenKey command functions +#define atcab_genkey_base(...) calib_genkey_base(_gDevice, __VA_ARGS__) +#define atcab_genkey(...) calib_genkey(_gDevice, __VA_ARGS__) +#define atcab_get_pubkey(...) calib_get_pubkey(_gDevice, __VA_ARGS__) +#define atcab_get_pubkey_ext calib_get_pubkey + +// HMAC command functions +#define atcab_hmac(...) calib_hmac(_gDevice, __VA_ARGS__) + +// Info command functions +#define atcab_info_base(...) calib_info_base(_gDevice, __VA_ARGS__) +#define atcab_info(...) calib_info(_gDevice, __VA_ARGS__) +#define atcab_info_get_latch(...) calib_info_get_latch(_gDevice, __VA_ARGS__) +#define atcab_info_set_latch(...) calib_info_set_latch(_gDevice, __VA_ARGS__) + +// KDF command functions +#define atcab_kdf(...) calib_kdf(_gDevice, __VA_ARGS__) + +// Lock command functions +#if CALIB_ECC204_ONLY +#define atcab_lock(...) (ATCA_UNIMPLEMENTED) +#define atcab_lock_config_zone() calib_ecc204_lock_config_zone(_gDevice) +#define atcab_lock_config_zone_crc(...) (ATCA_UNIMPLEMENTED) +#define atcab_lock_data_zone() calib_ecc204_lock_data_zone(_gDevice) +#define atcab_lock_data_zone_crc(...) (ATCA_UNIMPLEMENTED) +#define atcab_lock_data_slot(...) calib_ecc204_lock_data_slot(_gDevice, __VA_ARGS__) #else -ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, const uint8_t *data, const uint8_t* enc_key, const uint16_t enc_key_id, const uint8_t num_in[NONCE_NUMIN_SIZE]); +#define atcab_lock(...) calib_lock(_gDevice, __VA_ARGS__) +#define atcab_lock_config_zone() calib_lock_config_zone(_gDevice) +#define atcab_lock_config_zone_crc(...) calib_lock_config_zone_crc(_gDevice, __VA_ARGS__) +#define atcab_lock_data_zone() calib_lock_data_zone(_gDevice) +#define atcab_lock_data_zone_crc(...) calib_lock_data_zone_crc(_gDevice, __VA_ARGS__) +#define atcab_lock_data_slot(...) calib_lock_data_slot(_gDevice, __VA_ARGS__) #endif -#if defined(ATCA_USE_CONSTANT_HOST_NONCE) -ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* data, uint8_t* transport_key, - uint8_t key_id); +// MAC command functions +#define atcab_mac(...) calib_mac(_gDevice, __VA_ARGS__) + +// Nonce command functions +#define atcab_nonce_base(...) calib_nonce_base(_gDevice, __VA_ARGS__) +#define atcab_nonce(...) calib_nonce(_gDevice, __VA_ARGS__) +#define atcab_nonce_load(...) calib_nonce_load(_gDevice, __VA_ARGS__) +#define atcab_nonce_rand(...) calib_nonce_rand(_gDevice, __VA_ARGS__) +#define atcab_challenge(...) calib_challenge(_gDevice, __VA_ARGS__) +#define atcab_challenge_seed_update(...) calib_challenge_seed_update(_gDevice, __VA_ARGS__) + +// PrivWrite command functions +#define atcab_priv_write(...) calib_priv_write(_gDevice, __VA_ARGS__) + + +// Random command functions +#define atcab_random(...) calib_random(_gDevice, __VA_ARGS__) +#define atcab_random_ext calib_random + +// Read command functions +#define atcab_is_slot_locked(...) calib_is_slot_locked(_gDevice, __VA_ARGS__) +#define atcab_is_private(...) calib_is_private(_gDevice, __VA_ARGS__) +#define atcab_is_private_ext calib_is_private +#if CALIB_ECC204_ONLY +#define atcab_read_zone(...) calib_ecc204_read_zone(_gDevice, __VA_ARGS__) +#define atcab_is_locked(...) calib_ecc204_is_locked(_gDevice, __VA_ARGS__) +#define atcab_is_config_locked(...) calib_ecc204_is_locked(_gDevice, ATCA_ZONE_CONFIG, __VA_ARGS__) +#define atcab_is_data_locked(...) calib_ecc204_is_locked(_gDevice, ATCA_ZONE_DATA, __VA_ARGS__) +#define atcab_read_bytes_zone(...) calib_ecc204_read_bytes_zone(_gDevice, __VA_ARGS__) +#define atcab_read_bytes_zone_ext calib_ecc204_read_bytes_zone +#define atcab_read_serial_number(...) calib_ecc204_read_serial_number(_gDevice, __VA_ARGS__) +#define atcab_read_config_zone(...) calib_ecc204_read_config_zone(_gDevice, __VA_ARGS__) #else -ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* data, uint8_t* transport_key, - uint8_t key_id, uint8_t num_in[NONCE_NUMIN_SIZE]); +#define atcab_read_zone(...) calib_read_zone_ext(_gDevice, __VA_ARGS__) +#define atcab_is_locked(...) calib_is_locked_ext(_gDevice, __VA_ARGS__) +#define atcab_is_config_locked(...) calib_is_locked_ext(_gDevice, LOCK_ZONE_CONFIG, __VA_ARGS__) +#define atcab_is_data_locked(...) calib_is_locked_ext(_gDevice, LOCK_ZONE_DATA, __VA_ARGS__) +#define atcab_read_bytes_zone(...) calib_read_bytes_zone_ext(_gDevice, __VA_ARGS__) +#define atcab_read_bytes_zone_ext calib_read_bytes_zone_ext +#define atcab_read_serial_number(...) calib_read_serial_number_ext(_gDevice, __VA_ARGS__) +#define atcab_read_config_zone(...) calib_read_config_zone(_gDevice, __VA_ARGS__) #endif +#define atcab_cmp_config_zone(...) calib_cmp_config_zone(_gDevice, __VA_ARGS__) +#define atcab_read_pubkey(...) calib_read_pubkey(_gDevice, __VA_ARGS__) +#define atcab_read_pubkey_ext calib_read_pubkey +#define atcab_read_sig(...) calib_read_sig(_gDevice, __VA_ARGS__) +#define atcab_read_enc(...) calib_read_enc(_gDevice, __VA_ARGS__) -ATCA_STATUS calib_write_config_counter(ATCADevice device, uint16_t counter_id, uint32_t counter_value); + +// SecureBoot command functions +#define atcab_secureboot(...) calib_secureboot(_gDevice, __VA_ARGS__) +#define atcab_secureboot_mac(...) calib_secureboot_mac(_gDevice, __VA_ARGS__) + +// SelfTest command functions +#define atcab_selftest(...) calib_selftest(_gDevice, __VA_ARGS__) + +// SHA command functions +#define atcab_sha_base(...) calib_sha_base(_gDevice, __VA_ARGS__) +#define atcab_sha_start() calib_sha_start(_gDevice) +#define atcab_sha_update(...) calib_sha_update(_gDevice, __VA_ARGS__) +#define atcab_sha_end(...) calib_sha_end(_gDevice, __VA_ARGS__) +#define atcab_sha_read_context(...) calib_sha_read_context(_gDevice, __VA_ARGS__) +#define atcab_sha_write_context(...) calib_sha_write_context(_gDevice, __VA_ARGS__) +#define atcab_sha(...) calib_sha(_gDevice, __VA_ARGS__) +#define atcab_hw_sha2_256(...) calib_hw_sha2_256(_gDevice, __VA_ARGS__) +#define atcab_hw_sha2_256_init(...) calib_hw_sha2_256_init(_gDevice, __VA_ARGS__) +#define atcab_hw_sha2_256_update(...) calib_hw_sha2_256_update(_gDevice, __VA_ARGS__) +#define atcab_hw_sha2_256_finish(...) calib_hw_sha2_256_finish(_gDevice, __VA_ARGS__) +#define atcab_sha_hmac_init(...) calib_sha_hmac_init(_gDevice, __VA_ARGS__) +#define atcab_sha_hmac_update(...) calib_sha_hmac_update(_gDevice, __VA_ARGS__) +#define atcab_sha_hmac_finish(...) calib_sha_hmac_finish(_gDevice, __VA_ARGS__) +#define atcab_sha_hmac(...) calib_sha_hmac(_gDevice, __VA_ARGS__) +#define atcab_sha_hmac_ext calib_sha_hmac +#define SHA_CONTEXT_MAX_SIZE (99) + +// Sign command functions +#define atcab_sign_base(...) calib_sign_base(_gDevice, __VA_ARGS__) +#if CALIB_ECC204_ONLY +#define atcab_sign(...) calib_ecc204_sign(_gDevice, __VA_ARGS__) +#define atcab_sign_ext calib_ecc204_sign +#else +#define atcab_sign(...) calib_sign_ext(_gDevice, __VA_ARGS__) +#define atcab_sign_ext calib_sign_ext +#endif + +#define atcab_sign_internal(...) calib_sign_internal(_gDevice, __VA_ARGS__) + +// UpdateExtra command functions +#define atcab_updateextra(...) calib_updateextra(_gDevice, __VA_ARGS__) + +// Verify command functions +#define atcab_verify(...) calib_verify(_gDevice, __VA_ARGS__) +#define atcab_verify_extern(...) calib_verify_extern(_gDevice, __VA_ARGS__) +#define atcab_verify_extern_ext calib_verify_extern +#define atcab_verify_extern_mac(...) calib_verify_extern_mac(_gDevice, __VA_ARGS__) +#define atcab_verify_stored(...) calib_verify_stored(_gDevice, __VA_ARGS__) +#define atcab_verify_stored_ext calib_verify_stored +#define atcab_verify_stored_with_tempkey(...) calib_verify_stored_with_tempkey(_gDevice, __VA_ARGS__) +#define atcab_verify_stored_mac(...) calib_verify_stored_mac(_gDevice, __VA_ARGS__) +#define atcab_verify_validate(...) calib_verify_validate(_gDevice, __VA_ARGS__) +#define atcab_verify_invalidate(...) calib_verify_invalidate(_gDevice, __VA_ARGS__) + +// Write command functions +#if CALIB_ECC204_ONLY +#define atcab_write(...) calib_ecc204_write(_gDevice, __VA_ARGS__) +#define atcab_write_zone(...) calib_ecc204_write_zone(_gDevice, __VA_ARGS__) +#define atcab_write_bytes_zone(...) calib_ecc204_write_bytes_zone(_gDevice, __VA_ARGS__) +#define atcab_write_bytes_zone_ext calib_ecc204_write_bytes_zone +#define atcab_write_config_zone(...) calib_ecc204_write_config_zone(_gDevice, __VA_ARGS__) +#else +#define atcab_write(...) calib_write_ext(_gDevice, __VA_ARGS__) +#define atcab_write_zone(...) calib_write_zone_ext(_gDevice, __VA_ARGS__) +#define atcab_write_bytes_zone(...) calib_write_bytes_zone_ext(_gDevice, __VA_ARGS__) +#define atcab_write_bytes_zone_ext calib_write_bytes_zone_ext +#define atcab_write_config_zone(...) calib_write_config_zone_ext(_gDevice, __VA_ARGS__) +#endif + +#define atcab_write_pubkey(...) calib_write_pubkey(_gDevice, __VA_ARGS__) +#define atcab_write_enc(...) calib_write_enc(_gDevice, __VA_ARGS__) +#define atcab_write_config_counter(...) calib_write_config_counter(_gDevice, __VA_ARGS__) +#endif #ifdef __cplusplus } diff --git a/lib/calib/calib_checkmac.c b/lib/calib/calib_checkmac.c index d0cf73daf..a6178a124 100644 --- a/lib/calib/calib_checkmac.c +++ b/lib/calib/calib_checkmac.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_CHECKMAC_EN /** \brief Compares a MAC response with input values * * \param[in] device Device context pointer @@ -91,3 +92,4 @@ ATCA_STATUS calib_checkmac(ATCADevice device, uint8_t mode, uint16_t key_id, con return status; } +#endif /* CALIB_CHECKMAC */ diff --git a/lib/calib/calib_command.c b/lib/calib/calib_command.c index f8d6fc585..342e3fdbd 100644 --- a/lib/calib/calib_command.c +++ b/lib/calib/calib_command.c @@ -34,6 +34,7 @@ #include "cryptoauthlib.h" +#if CALIB_CHECKMAC_EN /** \brief ATCACommand CheckMAC method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -49,7 +50,9 @@ ATCA_STATUS atCheckMAC(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_COUNTER_EN /** \brief ATCACommand Counter method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -65,7 +68,9 @@ ATCA_STATUS atCounter(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_DERIVEKEY_EN /** \brief ATCACommand DeriveKey method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -92,7 +97,9 @@ ATCA_STATUS atDeriveKey(ATCADeviceType device_type, ATCAPacket *packet, bool has atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_ECDH_EN /** \brief ATCACommand ECDH method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -108,7 +115,9 @@ ATCA_STATUS atECDH(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_GENDIG_EN /** \brief ATCACommand Generate Digest method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -137,7 +146,9 @@ ATCA_STATUS atGenDig(ATCADeviceType device_type, ATCAPacket *packet, bool is_no_ atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_GENKEY_EN /** \brief ATCACommand Generate Key method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -161,7 +172,9 @@ ATCA_STATUS atGenKey(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_HMAC_EN /** \brief ATCACommand HMAC method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -177,6 +190,7 @@ ATCA_STATUS atHMAC(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif /** \brief ATCACommand Info method * \param[in] ca_cmd instance @@ -194,6 +208,7 @@ ATCA_STATUS atInfo(ATCADeviceType device_type, ATCAPacket *packet) return ATCA_SUCCESS; } +#if CALIB_LOCK_EN || CALIB_LOCK_ECC204_EN /** \brief ATCACommand Lock method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -209,7 +224,9 @@ ATCA_STATUS atLock(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_MAC_EN /** \brief ATCACommand MAC method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -233,7 +250,9 @@ ATCA_STATUS atMAC(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_NONCE_EN /** \brief ATCACommand Nonce method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -275,6 +294,7 @@ ATCA_STATUS atNonce(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif /** \brief ATCACommand Pause method * \param[in] ca_cmd instance @@ -292,6 +312,7 @@ ATCA_STATUS atPause(ATCADeviceType device_type, ATCAPacket *packet) return ATCA_SUCCESS; } +#if CALIB_PRIVWRITE_EN /** \brief ATCACommand PrivWrite method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -307,7 +328,9 @@ ATCA_STATUS atPrivWrite(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_RANDOM_EN /** \brief ATCACommand Random method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -323,7 +346,9 @@ ATCA_STATUS atRandom(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_READ_EN || CALIB_READ_ECC204_EN /** \brief ATCACommand Read method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -339,7 +364,9 @@ ATCA_STATUS atRead(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_SECUREBOOT_EN /** \brief ATCACommand SecureBoot method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -371,7 +398,9 @@ ATCA_STATUS atSecureBoot(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_SHA_EN /** \brief ATCACommand SHA method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -416,7 +445,9 @@ ATCA_STATUS atSHA(ATCADeviceType device_type, ATCAPacket *packet, uint16_t write atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_SIGN_EN || CALIB_SIGN_ECC204_EN /** \brief ATCACommand Sign method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -434,7 +465,9 @@ ATCA_STATUS atSign(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_UPDATEEXTRA_EN /** \brief ATCACommand UpdateExtra method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -450,7 +483,9 @@ ATCA_STATUS atUpdateExtra(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_VERIFY_EN /** \brief ATCACommand ECDSA Verify method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -490,7 +525,9 @@ ATCA_STATUS atVerify(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_WRITE_EN || CALIB_WRITE_ECC204_EN /** \brief ATCACommand Write method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -537,7 +574,9 @@ ATCA_STATUS atWrite(ATCADeviceType device_type, ATCAPacket *packet, bool has_mac atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_AES_EN /** \brief ATCACommand AES method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -562,7 +601,9 @@ ATCA_STATUS atAES(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_SELFTEST_EN /** \brief ATCACommand AES method * \param[in] ca_cmd instance * \param[in] packet pointer to the packet containing the command being built @@ -578,7 +619,9 @@ ATCA_STATUS atSelfTest(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } +#endif +#if CALIB_KDF_EN /** \brief ATCACommand KDF method * \param[in] ca_cmd Instance * \param[in] packet Pointer to the packet containing the command being @@ -606,7 +649,7 @@ ATCA_STATUS atKDF(ATCADeviceType device_type, ATCAPacket *packet) atCalcCrc(packet); return ATCA_SUCCESS; } - +#endif /** \brief Calculates CRC over the given raw data and returns the CRC in * little-endian byte order. @@ -688,6 +731,7 @@ bool atIsSHAFamily(ATCADeviceType device_type) switch (device_type) { case ATSHA204A: + /* fallthrough */ case ATSHA206A: return true; break; @@ -707,8 +751,11 @@ bool atIsECCFamily(ATCADeviceType device_type) switch (device_type) { case ATECC108A: + /* fallthrough */ case ATECC508A: + /* fallthrough */ case ATECC608: + /* fallthrough */ case ECC204: return true; break; diff --git a/lib/calib/calib_command.h b/lib/calib/calib_command.h index 949eb675c..92750c4b3 100644 --- a/lib/calib/calib_command.h +++ b/lib/calib/calib_command.h @@ -179,6 +179,7 @@ ATCA_STATUS atCheckCrc(const uint8_t *response); #define ATCA_WRITE ((uint8_t)0x12) //!< Write command op-code #define ATCA_ECDH ((uint8_t)0x43) //!< ECDH command op-code #define ATCA_COUNTER ((uint8_t)0x24) //!< Counter command op-code +#define ATCA_DELETE ((uint8_t)0x13) //!< Delete command op-code #define ATCA_SHA ((uint8_t)0x47) //!< SHA command op-code #define ATCA_AES ((uint8_t)0x51) //!< AES command op-code #define ATCA_KDF ((uint8_t)0x56) //!< KDF command op-code diff --git a/lib/calib/calib_config_check.h b/lib/calib/calib_config_check.h new file mode 100644 index 000000000..25fb698cb --- /dev/null +++ b/lib/calib/calib_config_check.h @@ -0,0 +1,670 @@ +/** + * \file + * \brief Consistency checks for configuration options + * + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef CALIB_CONFIG_CHECK_H +#define CALIB_CONFIG_CHECK_H + +#include "atca_config_check.h" + +/* Device Specific Defaults */ +#ifdef ATCA_ATSHA204A_SUPPORT +#define CALIB_SHA204_EN DEFAULT_ENABLED +#endif + +#ifdef ATCA_ATSHA206A_SUPPORT +#define CALIB_SHA206_EN DEFAULT_ENABLED +#endif + +#ifdef ATCA_ATECC108A_SUPPORT +#define CALIB_ECC108_EN DEFAULT_ENABLED +#endif + +#ifdef ATCA_ATECC508A_SUPPORT +#define CALIB_ECC508_EN DEFAULT_ENABLED +#endif + +#ifdef ATCA_ATECC608_SUPPORT +#define CALIB_ECC608_EN DEFAULT_ENABLED +#endif + +#ifdef ATCA_ECC204_SUPPORT +#define CALIB_ECC204_EN DEFAULT_ENABLED +#endif + +/* Helper macros */ +#define CALIB_FULL_FEATURE (CALIB_SHA204_EN || CALIB_ECC108_EN || CALIB_ECC508_EN || CALIB_ECC608_EN) +#define CALIB_ECC_SUPPORT (CALIB_ECC108_EN || CALIB_ECC508_EN || CALIB_ECC608_EN || CALIB_ECC204_EN) +#define CALIB_ECC204_ONLY (CALIB_ECC204_EN && !(CALIB_FULL_FEATURE || CALIB_SHA206_EN)) +#define CALIB_SHA206_ONLY (CALIB_SHA206_EN && !(CALIB_FULL_FEATURE || CALIB_ECC204_EN)) + + /**** AES command ****/ + +/** \def CALIB_AES + * + * Enable CALIB_AES to compute the AES-128 encrypt, decrypt, or GFM calculation + * + * Supported API's: calib_aes + **/ +#ifndef CALIB_AES_EN +#define CALIB_AES_EN (ATCAB_AES_EN && CALIB_ECC608_EN) +#endif + + /**** AES GCM command ****/ + +/** \def CALIB_AES_GCM + * + * Requires: CALIB_AES_GCM + * CALIB_AES_MODE_ENCODING + * CALIB_AES + * CALIB_RANDOM + * + * Supported API's: calib_aes_ghash + * calib_aes_gcm_increment + * calib_aes_gcm_init + * calib_aes_gcm_init_rand + * calib_aes_gcm_aad_update + * calib_aes_gcm_update + * calib_aes_gcm_encrypt_update + * calib_aes_gcm_calc_auth_tag + * calib_aes_gcm_encrypt_finish + * calib_aes_gcm_decrypt_update + * calib_aes_gcm_decrypt_finish + **/ +#ifndef CALIB_AES_GCM_EN +#define CALIB_AES_GCM_EN (ATCAB_AES_GCM_EN && CALIB_AES_EN && CALIB_ECC608_EN) +#endif + + /**** CHECKMAC command ****/ + +/** \def CALIB_CHECKMAC + * + * Enable CALIB_CHECKMAC to compare a MAC response with input values + * + * Supported API's: calib_checkmac + **/ +#ifndef CALIB_CHECKMAC_EN +#define CALIB_CHECKMAC_EN (ATCAB_CHECKMAC_EN && CALIB_FULL_FEATURE) +#endif + + /***** COUNTER command *****/ + +/** \def CALIB_COUNTER + * + * Enable CALIB_COUNTER to compute the counter functions + * + * Supported API's: calib_counter + **/ +#ifndef CALIB_COUNTER_EN +#define CALIB_COUNTER_EN (ATCAB_COUNTER_EN && CALIB_ECC_SUPPORT) +#endif + + /***** DERIVEKEY command ******/ + +/** \def CALIB_DERIVEKEY + * + * Enable CALIB_DERIVEKEY for deriving a new key from a nonce (TempKey) and an existing key + * + * Supported API's: calib_derivekey + **/ +#ifndef CALIB_DERIVEKEY_EN +#define CALIB_DERIVEKEY_EN (ATCAB_DERIVEKEY_EN && (CALIB_FULL_FEATURE || CALIB_SHA206_EN)) +#endif + + /******* ECDH command *******/ + +/** \def CALIB_ECDH + * + * Requires: CALIB_ECDH + * + * Supported API's: calib_ecdh_base + * calib_ecdh + * calib_ecdh_tempkey + * + * Enable CALIB_ECDH for generating premaster secret key using ECDH + * ECDH command with a private key in a slot/tempkey and the premaster secret is returned in the clear + **/ +#ifndef CALIB_ECDH_EN +#define CALIB_ECDH_EN (ATCAB_ECDH_EN && (CALIB_ECC508_EN || CALIB_ECC608_EN)) +#endif + +/** \def CALIB_ECDH_ENC + * + * Requires: CALIB_ECDH_ENC + * CALIB_ECDH + * CALIB_READ_ZONE + * CALIB_READ_ENC + * ATCAH_IO_DECRYPT + * ATCAC_SW_SHA2_256 + * CALIB_NONCE_BASE + * CALIB_NONCE_MODE_ENCODING + * CALIB_GENDIG + * + * Supported API's: calib_ecdh_enc + * calib_ecdh_ioenc + * calib_ecdh_tempkey_ioenc + * + * ECDH command with a private key in a slot and the premaster secret is read from the next slot + * ECDH command with a private key in a slot/tempkey and the premaster secret is returned encrypted + * using the IO protection key +**/ +#ifndef CALIB_ECDH_ENC_EN +#define CALIB_ECDH_ENC_EN (ATCAB_ECDH_ENC_EN && (CALIB_ECC508_EN || CALIB_ECC608_EN)) +#endif + + /****** GENDIG command ******/ + +/** \def CALIB_GENDIG + * + * Enable CALIB_GENDIG to perform a SHA256 hash on the source data indicated by zone with the + * contents of TempKey + * + * Supported API's: calib_gendig + **/ +#ifndef CALIB_GENDIG_EN +#define CALIB_GENDIG_EN (ATCAB_GENDIG_EN && CALIB_FULL_FEATURE) +#endif + + /****** GENKEY COMMAND ******/ + +/** \def CALIB_GENKEY_BASE + * + * Enable CALIB_GENKEY_BASE which can generate a private key, compute a public key, nd/or compute a + * digest of a public key + * + * Supported API's: calib_genkey_base + **/ +#ifndef CALIB_GENKEY_EN +#define CALIB_GENKEY_EN (ATCAB_GENKEY_EN && CALIB_ECC_SUPPORT) +#endif + +/** \def CALIB_GENKEY_MAC + * + * Requires: CALIB_GENKEY_MAC + * + * Supported API's: calib_genkey_mac + * + * Uses Genkey command to calculate SHA256 digest MAC of combining public key and session key + **/ +#ifndef CALIB_GENKEY_MAC_EN +#define CALIB_GENKEY_MAC_EN (ATCAB_GENKEY_MAC_EN && CALIB_ECC_SUPPORT) +#endif + + /******* HMAC COMMAND *******/ + +/** \def CALIB_HMAC + * + * Enable CALIB_HMAC which computes an HMAC/SHA-256 digest of a key stored in the device, a + * challenge, and other information on the device + * + * Supported API's: calib_hmac + **/ +#ifndef CALIB_HMAC_EN +#define CALIB_HMAC_EN (ATCAB_HMAC_EN && (CALIB_SHA204_EN || CALIB_ECC108_EN || CALIB_ECC508)) +#endif + + /******* INFO COMMAND ********/ + +/** \def CALIB_INFO_LATCH_EN + * + * Supported API's: + * calib_info_get_latch + * calib_info_set_latch + * + * ECC204 specific api: calib_info_lock_status +**/ +#ifndef CALIB_INFO_LATCH_EN +#define CALIB_INFO_LATCH_EN ATCAB_INFO_LATCH_EN +#endif + + /****** KDF COMMAND ******/ + +/** \def CALIB_KDF + * + * Enable CALIB_KDF to derive a new key in PRF, AES, or HKDF modes + * + * Supported API's: calib_kdf + **/ +#ifndef CALIB_KDF_EN +#define CALIB_KDF_EN (ATCAB_KDF_EN && CALIB_ECC608_EN) +#endif + + /****** LOCK COMMAND ******/ + +/** \def CALIB_LOCK_EN + * + * Enable CALIB_LOCK_EN to enable the lock commands for the classic cryptoauth parts + * + * Supported API's: calib_lock + **/ +#ifndef CALIB_LOCK_EN +#define CALIB_LOCK_EN (ATCAB_LOCK_EN && CALIB_FULL_FEATURE) +#endif + +/** \def CALIB_LOCK_ECC204_EN + * + * Enable CALIB_LOCK_ECC204_EN which enables the lock command for the ecc204 device + * + * Supported API's: calib_lock + **/ +#ifndef CALIB_LOCK_ECC204_EN +#define CALIB_LOCK_ECC204_EN (ATCAB_LOCK_EN && CALIB_ECC204_EN) +#endif + + /****** MAC command ******/ + +/** \def CALIB_MAC + * + * Enable CALIB_MAC to computes a SHA-256 digest of a key stored in the device, a challenge, and + * other information on the device + * + * Supported API's: calib_mac + **/ +#ifndef CALIB_MAC_EN +#define CALIB_MAC_EN (ATCAB_MAC_EN && (CALIB_FULL_FEATURE || CALIB_SHA206_EN)) +#endif + + /****** NONCE command ******/ + +/** \def CALIB_NONCE_BASE + * + * Enable CALIB_NONCE_BASE which loads a random or fixed nonce/data into the device for use by subsequent + * commands + * + * Requires: CALIB_NONCE_BASE + * + * Supported API's: calib_nonce_base + **/ +#ifndef CALIB_NONCE_EN +#define CALIB_NONCE_EN (ATCAB_NONCE_EN && (CALIB_FULL_FEATURE || CALIB_ECC204_EN)) +#endif + + /**** PRIVWRITE COMMAND ****/ + +/** \def CALIB_PRIVWRITE + * + * Enable CALIB_PRIVWRITE to write externally generated ECC private keys into the device + * + * Requires: CALIB_PRIVWRITE + * CALIB_READ_ZONE + * CALIB_NONCE_MODE_ENCODING + * CALIB_NONCE_BASE + * CALIB_GENDIG + * ATCAH_GENDIG + * ATCAH_PRIVWRITE_AUTH_MAC + * ATCAH_NONCE + * ATCAC_SW_SHA2_256 + * + * Supported API's: calib_priv_write + **/ +#ifndef CALIB_PRIVWRITE_EN +#define CALIB_PRIVWRITE_EN (ATCAB_PRIVWRITE_EN && (CALIB_ECC108_EN || CALIB_ECC508_EN || CALIB_ECC608_EN)) +#endif + + /***** RANDOM COMMAND *****/ + +/** \def CALIB_RANDOM + * + * Enable CALIB_RANDOM which generates a 32 byte random number from the CryptoAuth device + * + * Supported API's: calib_random + **/ +#ifndef CALIB_RANDOM_EN +#define CALIB_RANDOM_EN (ATCAB_RANDOM_EN && CALIB_FULL_FEATURE) +#endif + + /***** READ command *****/ + +/** \def CALIB_READ_EN + * + * Enable CALIB_READ_EN which enables the read commands + * + * Supported API's: calib_read_zone + * + **/ +#ifndef CALIB_READ_EN +#define CALIB_READ_EN (ATCAB_READ_EN && (CALIB_FULL_FEATURE || CALIB_SHA206_EN)) +#endif + +/** \def CALIB_READ_ZONE + * + * Enable CALIB_READ_ZONE which reads either 4 or 32 bytes of data from a given slot, + * configuration zone, or the OTP zone + * + * Supported API's: calib_read_zone + * + * Supported ECC204 specific API's: calib_ecc204_read_zone + **/ +#ifndef CALIB_READ_ECC204_EN +#define CALIB_READ_ECC204_EN (ATCAB_READ_EN && CALIB_ECC204_EN) +#endif + +/** \def CALIB_READ_ENC + * + * Requires: CALIB_NONCE_BASE + * CALIB_NONCE_MODE_ENCODING + * CALIB_GENDIG + * ATCAH_NONCE + * ATCAH_GENDIG + * ATCAC_SW_SHA2_256 + * CALIB_READ_ZONE + * CALIB_READ_ENC + * + * Performs Read command on a slot configured for encrypted reads and decrypts the data to return + * it as plaintext + * + * Supported API's: calib_read_enc + **/ +#ifndef CALIB_READ_ENC_EN +#define CALIB_READ_ENC_EN (ATCAB_READ_ENC_EN && CALIB_FULL_FEATURE) +#endif + + /***** SECUREBOOT command ****/ + +/** \def CALIB_SECUREBOOT + * + * Enable CALIB_SECUREBOOT which provides support for secureboot of an external MCU or MPU + * + * Requires: CALIB_SECUREBOOT + * + * Supported API's: calib_secureboot + * calib_secureboot_mac +**/ +#ifndef CALIB_SECUREBOOT_EN +#define CALIB_SECUREBOOT_EN (ATCAB_SECUREBOOT_EN && CALIB_ECC608_EN) +#endif + +/** \def CALIB_SECUREBOOT_MAC + * + * Requires: CALIB_NONCE_BASE + * CALIB_READ_CONFIG_BYTES_ZONE + * CALIB_READ_ZONE + * ATCAH_NONCE + * ATCAH_SECUREBOOT_ENC + * ATCAH_SECUREBOOT_MAC + * ATCAC_SW_SHA2_256 + * CALIB_SECUREBOOT + * + * Performs secureboot command with encrypted digest and validated MAC response using the IO protection key + * + * Supported API's: calib_secureboot_mac + **/ +#ifndef CALIB_SECUREBOOT_MAC_EN +#define CALIB_SECUREBOOT_MAC_EN (ATCAB_SECUREBOOT_MAC_EN && CALIB_ECC608_EN) +#endif + + /**** SELFTEST command ****/ + +/** \def CALIB_SELFTEST + * + * Enable CALIB_SELFTEST which performs a test of one or more of the cryptographic engines within + * the ATECC608 chip + * + * Supported API's: calib_selftest + **/ +#ifndef CALIB_SELFTEST_EN +#define CALIB_SELFTEST_EN (ATCAB_SELFTEST_EN && (CALIB_ECC608_EN || CALIB_ECC204_EN)) +#endif + + /****** SHA command ******/ + +/** \def CALIB_SHA_EN + * + * Enable CALIB_SHA_EN to compute a SHA-256 or HMAC/SHA-256 digest for general purpose use by + * the host system + * + * Supported API's: calib_sha_base + **/ +#ifndef CALIB_SHA_EN +#define CALIB_SHA_EN (ATCAB_SHA_EN && (CALIB_FULL_FEATURE || CALIB_ECC204_EN)) +#endif + +/** \def CALIB_SHA_HMAC_EN + * + * Requires: CALIB_SHA_HMAC + * CALIB_SHA_BASE + * + * Use the SHA command to compute an HMAC/SHA-256 operation + * + * Supported API's: calib_sha_hmac,calib_sha_hmac_init, calib_sha_hmac_update, calib_sha_hmac_finish + **/ +#ifndef CALIB_SHA_HMAC_EN +#define CALIB_SHA_HMAC_EN (ATCAB_SHA_HMAC_EN && CALIB_ECC_SUPPORT) +#endif + +/** \def CALIB_SHA_CONTEXT_EN + * + * Requires: + * CALIB_SHA_BASE + * + * Use the SHA command to compute an HMAC/SHA-256 operation + * + * Supported API's: calib_sha_read_context + **/ +#ifndef CALIB_SHA_CONTEXT_EN +#define CALIB_SHA_CONTEXT_EN (ATCAB_SHA_CONTEXT_EN && CALIB_ECC608_EN) +#endif + + /****** SIGN command ******/ + +/** \def CALIB_SIGN_EN + * + * Enable CALIB_SIGN_EN to generate a signature using the ECDSA algorithm + * + * Supported API's: calib_sign + * +**/ +#ifndef CALIB_SIGN_EN +#define CALIB_SIGN_EN (ATCAB_SIGN_EN && (CALIB_ECC108_EN || CALIB_ECC508_EN || CALIB_ECC608_EN)) +#endif + +/** \def CALIB_SIGN_ECC204_EN + * + * Enable CALIB_SIGN_ECC204_EN to generate a signature using the ECDSA algorithm + * + * Supported API's: calib_sign_base + * +**/ +#ifndef CALIB_SIGN_ECC204_EN +#define CALIB_SIGN_ECC204_EN (ATCAB_SIGN_EN && CALIB_ECC204_EN) +#endif + +/** \def CALIB_SIGN_MODE_ENCODING + * + * Requires: CALIB_RANDOM + * CALIB_NONCE_MODE_ENCODING + * CALIB_NONCE_BASE + * CALIB_SIGN_MODE_ENCODING + * CALIB_SIGN_BASE + * + * Use CALIB_SIGN_MODE_ENCODING to sign a 32-byte external message using the private key in the specified slot. + * + * Use CALIB_SIGN_MODE_ENCODING to sign a internally generated message + * + * Supported API's: calib_sign , calib_sign_internal + **/ +#ifndef CALIB_SIGN_INTERNAL_EN +#define CALIB_SIGN_INTERNAL_EN (ATCAB_SIGN_INTERNAL_EN && CALIB_SIGN_EN) +#endif + + /***** UPDATEEXTRA command ****/ + +/** \def CALIB_UPDATEEXTRA_EN + * + * Enable CALIB_UPDATEEXTRA_EN to update the values of the two extra bytes within the configuration + * zone (bytes 84 and 85) + * + * Supported API's: calib_updateextra + **/ +#ifndef CALIB_UPDATEEXTRA_EN +#define CALIB_UPDATEEXTRA_EN (ATCAB_UPDATEEXTRA_EN && CALIB_FULL_FEATURE) +#endif + + /******** VERIFY command ********/ + +/** \def CALIB_VERIFY_EN + * + * Enable CALIB_VERIFY_EN which takes an ECDSA [R,S] signature and verifies that it is correctly + * generated from a given message and public key. In all cases, the signature is an input to the command + * + * Supported API's: calib_verify + **/ +#ifndef CALIB_VERIFY_EN +#define CALIB_VERIFY_EN (ATCAB_VERIFY_EN && (CALIB_ECC108_EN || CALIB_ECC508_EN || CALIB_ECC608_EN)) +#endif + +/** \def CALIB_VERIFY_MAC_EN + * + * Requires: CALIB_NONCE_MODE_ENCODING + * CALIB_NONCE_BASE + * ATCAH_VERIFY_MAC + * ATCAC_SW_SHA2_256 + * CALIB_VERIFY + * + * Executes verification command with verification MAC for the External or Stored Verify modes + * + * Supported API's: calib_verify_extern_stored_mac, calib_verify_extern_mac, calib_verify_stored_mac + **/ +#ifndef CALIB_VERIFY_MAC_EN +#define CALIB_VERIFY_MAC_EN (ATCAB_VERIFY_EXTERN_STORED_MAC_EN && CALIB_ECC608_EN) +#endif + +/** \def CALIB_VERIFY_EXTERN + * + * Requires: CALIB_NONCE_MODE_ENCODING + * CALIB_NONCE_BASE + * CALIB_VERIFY + * + * Verifies a signature (ECDSA verify operation) with all components (message, signature, and + * public key) supplied + * + * Supported API's: calib_verify_extern + **/ +#ifndef CALIB_VERIFY_EXTERN_EN +#define CALIB_VERIFY_EXTERN_EN (ATCAB_VERIFY_EXTERN_EN && CALIB_VERIFY_EN) +#endif + +/** \def CALIB_VERIFY_STORED_EN + * + * Requires: CALIB_NONCE_MODE_ENCODING + * CALIB_NONCE_BASE + * CALIB_VERIFY + * + * Verifies a signature (ECDSA verify operation) with a public key stored in the device + * + * Supported API's: calib_verify_stored + **/ +#ifndef CALIB_VERIFY_STORED_EN +#define CALIB_VERIFY_STORED_EN (ATCAB_VERIFY_STORED_EN && CALIB_VERIFY_EN) +#endif + +/** \def CALIB_VERIFY_VALIDATE + * + * Requires: CALIB_VERIFY + * CALIB_VERIFY_VALIDATE + * + * Executes verification command in Validate mode to validate a public key stored in a slot + * + * Supported API's: calib_verify_validate + **/ +#ifndef CALIB_VERIFY_VALIDATE_EN +#define CALIB_VERIFY_VALIDATE_EN (ATCAB_VERIFY_VALIDATE_EN && CALIB_VERIFY_EN) +#endif + + /****** WRITE command ******/ + +/** \def ATCAB_WRITE_EN + * + * Enable CALIB_WRITE which writes either one four byte word or a 32-byte block to one of the + * EEPROM zones on the device + * + * Supported API's: calib_write + * + * Supported ECC204 specific API's: calib_ecc204_write + **/ +#ifndef CALIB_WRITE_EN +#define CALIB_WRITE_EN (ATCAB_WRITE_EN && (CALIB_FULL_FEATURE || CALIB_SHA206_EN)) +#endif + +/** \def CALIB_WRITE_ENC_EN + * + * Requires: CALIB_NONCE_MODE_ENCODING + * CALIB_NONCE_BASE + * CALIB_READ_ZONE + * CALIB_GENDIG + * ATCAH_GENDIG + * ATCAH_WRITE_AUTH_MAC + * ATCAH_NONCE + * ATCAC_SW_SHA2_256 + * CALIB_WRITE + * ATCAH_GEN_SESSION_KEY + * + * Performs an encrypted write of a 32 byte block into given slot + * + * Supported API's: calib_write_enc + * + * Supported ECC204 specific API's: calib_ecc204_write_enc + **/ +#ifndef CALIB_WRITE_ENC_EN +#define CALIB_WRITE_ENC_EN (ATCAB_WRITE_ENC_EN && CALIB_FULL_FEATURE) +#endif + +/** \def ATCAB_WRITE_EN + * + * Enable CALIB_WRITE which writes either one four byte word or a 32-byte block to one of the + * EEPROM zones on the device + * + * Supported API's: calib_write + * + * Supported ECC204 specific API's: calib_ecc204_write + **/ +#ifndef CALIB_WRITE_ECC204_EN +#define CALIB_WRITE_ECC204_EN (ATCAB_WRITE_EN && CALIB_ECC204_EN) +#endif + +/** \def ATCAB_WRITE_EN + * + * Enable CALIB_WRITE_ENC_ECC204_EN to enable encrypted writes to the ECC204 device - only + * used for provisioning activities + * + **/ +#ifndef CALIB_WRITE_ENC_ECC204_EN +#define CALIB_WRITE_ENC_ECC204_EN (ATCAB_WRITE_ENC_EN && CALIB_WRITE_ECC204_EN && CALIB_NONCE_EN) +#endif + + +/* Check host side configuration for missing components */ + +/* Check for any commands that require a sha implementation */ +#if !ATCA_HOSTLIB_EN && !ATCAC_SHA256_EN + +#if (CALIB_ECDH_ENC || CALIB_PRIVWRITE_EN || CALIB_READ_ENC_EN || CALIB_WRITE_ENC_EN || CALIB_SECUREBOOT_MAC_EN) +#error "Config Check: a host side sha256 implementation has to be provided to support host side hashing operations" +#endif + +#endif + +#endif /* CALIB_CONFIG_CHECK_H */ diff --git a/lib/calib/calib_counter.c b/lib/calib/calib_counter.c index 0a53d40f6..0471c789c 100644 --- a/lib/calib/calib_counter.c +++ b/lib/calib/calib_counter.c @@ -34,6 +34,7 @@ #include "cryptoauthlib.h" +#if CALIB_COUNTER_EN /** \brief Compute the Counter functions * \param[in] device Device context pointer * \param[in] mode the mode used for the counter @@ -125,3 +126,4 @@ ATCA_STATUS calib_counter_read(ATCADevice device, uint16_t counter_id, uint32_t* { return calib_counter(device, COUNTER_MODE_READ, counter_id, counter_value); } +#endif /* CALIB_COUNTER_EN */ \ No newline at end of file diff --git a/lib/calib/calib_derivekey.c b/lib/calib/calib_derivekey.c index dfc388105..d66b45385 100644 --- a/lib/calib/calib_derivekey.c +++ b/lib/calib/calib_derivekey.c @@ -34,6 +34,7 @@ #include "cryptoauthlib.h" +#if CALIB_DERIVEKEY_EN /** \brief Executes the DeviveKey command for deriving a new key from a * nonce (TempKey) and an existing key. * @@ -84,3 +85,4 @@ ATCA_STATUS calib_derivekey(ATCADevice device, uint8_t mode, uint16_t target_key return status; } +#endif /* CALIB_DERIVEKEY_EN */ diff --git a/lib/calib/calib_ecdh.c b/lib/calib/calib_ecdh.c index 895efc753..e750a5829 100644 --- a/lib/calib/calib_ecdh.c +++ b/lib/calib/calib_ecdh.c @@ -34,8 +34,10 @@ */ #include "cryptoauthlib.h" + #include "host/atca_host.h" +#if CALIB_ECDH_EN /** \brief Base function for generating premaster secret key using ECDH. * \param[in] device Device context pointer * \param[in] mode Mode to be used for ECDH computation @@ -116,7 +118,9 @@ ATCA_STATUS calib_ecdh(ATCADevice device, uint16_t key_id, const uint8_t* public return status; } +#endif /* CALIB_ECDH */ +#if CALIB_ECDH_ENC_EN /** \brief ECDH command with a private key in a slot and the premaster secret * is read from the next slot. * @@ -212,6 +216,7 @@ ATCA_STATUS calib_ecdh_ioenc(ATCADevice device, uint16_t key_id, const uint8_t* return status; } +#endif /* CALIB_ECDH_ENC_EN */ /** \brief ECDH command with a private key in TempKey and the premaster secret * is returned in the clear. @@ -225,6 +230,7 @@ ATCA_STATUS calib_ecdh_ioenc(ATCADevice device, uint16_t key_id, const uint8_t* * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if CALIB_ECDH_EN ATCA_STATUS calib_ecdh_tempkey(ATCADevice device, const uint8_t* public_key, uint8_t* pms) { // Perform ECDH operation with TempKey @@ -232,6 +238,7 @@ ATCA_STATUS calib_ecdh_tempkey(ATCADevice device, const uint8_t* public_key, uin return calib_ecdh_base(device, mode, 0x0000, public_key, pms, NULL); } +#endif /* CALIB_ECDH */ /** \brief ECDH command with a private key in TempKey and the premaster secret * is returned encrypted using the IO protection key. @@ -246,6 +253,8 @@ ATCA_STATUS calib_ecdh_tempkey(ATCADevice device, const uint8_t* public_key, uin * * \return ATCA_SUCCESS on success, otherwise an error code. */ + +#if CALIB_ECDH_ENC_EN ATCA_STATUS calib_ecdh_tempkey_ioenc(ATCADevice device, const uint8_t* public_key, uint8_t* pms, const uint8_t* io_key) { uint8_t mode = ECDH_MODE_SOURCE_TEMPKEY | ECDH_MODE_OUTPUT_ENC | ECDH_MODE_COPY_OUTPUT_BUFFER; @@ -272,3 +281,4 @@ ATCA_STATUS calib_ecdh_tempkey_ioenc(ATCADevice device, const uint8_t* public_ke return status; } +#endif /* CALIB_ECDH_ENC */ diff --git a/lib/calib/calib_execution.c b/lib/calib/calib_execution.c index 0cc58334e..dd2e7ccd5 100644 --- a/lib/calib/calib_execution.c +++ b/lib/calib/calib_execution.c @@ -192,24 +192,24 @@ static const device_execution_time_t device_execution_time_608_m2[] = { { ATCA_VERIFY, 1085}, { ATCA_WRITE, 45} }; +#endif /*Execution times for ECC204 supported commands...*/ static const device_execution_time_t device_execution_time_ecc204[] = { - { ATCA_COUNTER, 1}, - { ATCA_GENKEY, 100}, - { ATCA_INFO, 1}, - { ATCA_LOCK, 6}, - { ATCA_NONCE, 35}, - { ATCA_READ, 1}, - { ATCA_SELFTEST, 110}, - { ATCA_SHA, 4}, - { ATCA_SIGN, 100}, - { ATCA_WRITE, 10} + { ATCA_COUNTER, 20}, + { ATCA_DELETE, 200}, + { ATCA_GENKEY, 500}, + { ATCA_INFO, 20}, + { ATCA_LOCK, 80}, + { ATCA_NONCE, 20}, + { ATCA_READ, 40}, + { ATCA_SELFTEST, 600}, + { ATCA_SHA, 80}, + { ATCA_SIGN, 500}, + { ATCA_WRITE, 80} }; // *INDENT-ON* -#endif -#ifdef ATCA_NO_POLL /** \brief return the typical execution time for the given command * \param[in] opcode Opcode value of the command * \param[in] ca_cmd Command object for which the execution times are associated @@ -224,6 +224,7 @@ ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCADevice device) switch (device->mIface.mIfaceCFG->devtype) { +#ifdef ATCA_NO_POLL case ATSHA204A: execution_times = device_execution_time_204; no_of_commands = sizeof(device_execution_time_204) / sizeof(device_execution_time_t); @@ -262,6 +263,7 @@ ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCADevice device) no_of_commands = sizeof(device_execution_time_608_m0) / sizeof(device_execution_time_t); } break; +#endif case ECC204: execution_times = device_execution_time_ecc204; @@ -292,7 +294,6 @@ ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCADevice device) return status; } -#endif ATCA_STATUS calib_execute_send(ATCADevice device, uint8_t device_address, uint8_t* txdata, uint16_t txlength) { @@ -309,7 +310,7 @@ ATCA_STATUS calib_execute_send(ATCADevice device, uint8_t device_address, uint8_ #else if (atca_iface_is_kit(&device->mIface)) { - status = atsend(&device->mIface, 0xFF, (uint8_t*)txdata, (int)txlength - 1); + status = atsend(&device->mIface, 0xFF, (uint8_t*)&txdata[1], (int)txlength - 1); } else { @@ -454,6 +455,19 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) #else execution_or_wait_time = ATCA_POLLING_INIT_TIME_MSEC; max_delay_count = ATCA_POLLING_MAX_TIME_MSEC / ATCA_POLLING_FREQUENCY_TIME_MSEC; + + #if defined(ATCA_ECC204_SUPPORT) || defined(ATCA_TA010_SUPPORT) + if ((ATCA_SWI_GPIO_IFACE == device->mIface.mIfaceCFG->iface_type) && ((ECC204 == device->mIface.mIfaceCFG->devtype) || + (TA010 == device->mIface.mIfaceCFG->devtype))) + { + if ((status = calib_get_execution_time(packet->opcode, device)) != ATCA_SUCCESS) + { + return status; + } + execution_or_wait_time = device->execution_time_msec; + max_delay_count = 0; + } + #endif #endif retries = atca_iface_get_retries(&device->mIface); do @@ -467,7 +481,7 @@ ATCA_STATUS calib_execute_command(ATCAPacket* packet, ATCADevice device) } /* Send the command packet to the device */ - if (ATCA_I2C_IFACE == device->mIface.mIfaceCFG->iface_type) + if ((ATCA_I2C_IFACE == device->mIface.mIfaceCFG->iface_type) || (ATCA_CUSTOM_IFACE == device->mIface.mIfaceCFG->iface_type)) { packet->_reserved = 0x03; } diff --git a/lib/calib/calib_execution.h b/lib/calib/calib_execution.h index df94884e5..0875c15e0 100644 --- a/lib/calib/calib_execution.h +++ b/lib/calib/calib_execution.h @@ -53,7 +53,6 @@ extern "C" { #define CALIB_SWI_FLAG_IDLE 0xBB //!< flag requesting to go into Idle mode #define CALIB_SWI_FLAG_SLEEP 0xCC //!< flag requesting to go into Sleep mode -#ifdef ATCA_NO_POLL /** \brief Structure to hold the device execution time and the opcode for the * corresponding command */ @@ -64,7 +63,6 @@ typedef struct }device_execution_time_t; ATCA_STATUS calib_get_execution_time(uint8_t opcode, ATCADevice device); -#endif #ifndef ATCA_HAL_LEGACY_API ATCA_STATUS calib_execute_receive(ATCADevice device, uint8_t device_address, uint8_t* rxdata, uint16_t* rxlength); diff --git a/lib/calib/calib_gendig.c b/lib/calib/calib_gendig.c index ec00966b6..b9c09ddb2 100644 --- a/lib/calib/calib_gendig.c +++ b/lib/calib/calib_gendig.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_GENDIG_EN /** \brief Issues a GenDig command, which performs a SHA256 hash on the source data indicated by zone with the * contents of TempKey. See the CryptoAuth datasheet for your chip to see what the values of zone * correspond to. @@ -90,3 +91,4 @@ ATCA_STATUS calib_gendig(ATCADevice device, uint8_t zone, uint16_t key_id, const return status; } +#endif /* CALIB_GENDIG_EN */ diff --git a/lib/calib/calib_genkey.c b/lib/calib/calib_genkey.c index 539f4b69f..938ca9551 100644 --- a/lib/calib/calib_genkey.c +++ b/lib/calib/calib_genkey.c @@ -34,6 +34,7 @@ #include "cryptoauthlib.h" +#if CALIB_GENKEY_EN /** \brief Issues GenKey command, which can generate a private key, compute a * public key, nd/or compute a digest of a public key. * @@ -136,6 +137,7 @@ ATCA_STATUS calib_get_pubkey(ATCADevice device, uint16_t key_id, uint8_t *public { return calib_genkey_base(device, GENKEY_MODE_PUBLIC, key_id, NULL, public_key); } +#endif /* CALIB_GENKEY_EN */ /** \brief Uses Genkey command to calculate SHA256 digest MAC of combining public key * and session key @@ -149,6 +151,8 @@ ATCA_STATUS calib_get_pubkey(ATCADevice device, uint16_t key_id, uint8_t *public * * \return ATCA_SUCCESS on success, otherwise an error code. */ + +#if CALIB_GENKEY_MAC_EN ATCA_STATUS calib_genkey_mac(ATCADevice device, uint8_t* public_key, uint8_t* mac) { ATCAPacket packet; @@ -197,3 +201,4 @@ ATCA_STATUS calib_genkey_mac(ATCADevice device, uint8_t* public_key, uint8_t* ma return status; } +#endif /* CALIB_GENKEY_MAC_EN */ diff --git a/lib/calib/calib_helpers.c b/lib/calib/calib_helpers.c index 96e0b6e67..db644675f 100644 --- a/lib/calib/calib_helpers.c +++ b/lib/calib/calib_helpers.c @@ -36,6 +36,7 @@ * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if CALIB_READ_EN ATCA_STATUS calib_is_slot_locked(ATCADevice device, uint16_t slot, bool* is_locked) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -107,8 +108,27 @@ ATCA_STATUS calib_is_locked(ATCADevice device, uint8_t zone, bool* is_locked) return status; } +ATCA_STATUS calib_is_locked_ext(ATCADevice device, uint8_t zone, bool* is_locked) +{ +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + if (LOCK_ZONE_DATA == zone) + { + zone = ATCA_ZONE_DATA; + } + return calib_ecc204_is_locked(device, zone, is_locked); + } + else +#endif + { + return calib_is_locked(device, zone, is_locked); + } +} -#ifdef ATCA_ECC204_SUPPORT +#endif /* CALIB_READ_EN */ + +#if defined(ATCA_ECC204_SUPPORT) /** \brief Use Info command to check ECC204 Config zone lock status * * \param[in] device Device context pointer @@ -219,7 +239,6 @@ ATCA_STATUS calib_ecc204_is_locked(ATCADevice device, uint8_t zone, bool* is_loc #endif - /** \brief Check if a slot is a private key * * \param[in] device Device context pointer @@ -237,6 +256,7 @@ ATCA_STATUS calib_is_private(ATCADevice device, uint16_t slot, bool* is_private) { switch (dev_type) { +#if CALIB_READ_EN case ATECC108A: /* fallthrough */ case ATECC508A: @@ -250,8 +270,10 @@ ATCA_STATUS calib_is_private(ATCADevice device, uint16_t slot, bool* is_private) } break; } +#endif #ifdef ATCA_ECC204_SUPPORT case ECC204: + *is_private = (0 == slot) ? true : false; break; #endif default: @@ -262,3 +284,35 @@ ATCA_STATUS calib_is_private(ATCADevice device, uint16_t slot, bool* is_private) return status; } + +/** \brief Parse the revision field to get the device type */ +ATCADeviceType calib_get_devicetype(uint8_t revision[4]) +{ + ATCADeviceType ret = ATCA_DEV_UNKNOWN; + switch(revision[2]) + { + case 0x00: + /* fallthrough */ + case 0x02: + ret = ATSHA204A; + break; + case 0x10: + ret = ATECC108A; + break; + case 0x50: + ret = ATECC508A; + break; + case 0x60: + ret = ATECC608; + break; + case 0x20: + ret = ECC204; + break; + case 0x40: + ret = ATSHA206A; + break; + default: + break; + } + return ret; +} diff --git a/lib/calib/calib_hmac.c b/lib/calib/calib_hmac.c index 058218317..193bdb524 100644 --- a/lib/calib/calib_hmac.c +++ b/lib/calib/calib_hmac.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_HMAC_EN /** \brief Issues a HMAC command, which computes an HMAC/SHA-256 digest of a * key stored in the device, a challenge, and other information on the * device. @@ -91,3 +92,4 @@ ATCA_STATUS calib_hmac(ATCADevice device, uint8_t mode, uint16_t key_id, uint8_t return status; } +#endif /* CALIB_HMAC_EN */ diff --git a/lib/calib/calib_info.c b/lib/calib/calib_info.c index 7f4a2870e..180717c16 100644 --- a/lib/calib/calib_info.c +++ b/lib/calib/calib_info.c @@ -129,6 +129,7 @@ ATCA_STATUS calib_info(ATCADevice device, uint8_t* revision) return calib_info_base(device, INFO_MODE_REVISION, 0, revision); } +#if CALIB_INFO_LATCH_EN /** \brief Use the Info command to get the persistent latch current state for * an ATECC608 device. * @@ -173,6 +174,7 @@ ATCA_STATUS calib_info_set_latch(ATCADevice device, bool state) param2 |= state ? INFO_PARAM2_LATCH_SET : INFO_PARAM2_LATCH_CLEAR; return calib_info_base(device, INFO_MODE_VOL_KEY_PERMIT, param2, NULL); } +#endif /* CALIB_INFO_LATCH_EN */ /** \brief Use Info command to check ECC Private key stored in key slot is valid or not * @@ -201,4 +203,4 @@ ATCA_STATUS calib_info_lock_status(ATCADevice device, uint16_t param2, uint8_t* { return calib_info_base(device, INFO_MODE_LOCK_STATUS, param2, is_locked); } -#endif +#endif /* ATCA_ECC204_SUPPORT */ diff --git a/lib/calib/calib_kdf.c b/lib/calib/calib_kdf.c index 07a1095f3..e21fc3f62 100644 --- a/lib/calib/calib_kdf.c +++ b/lib/calib/calib_kdf.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_KDF_EN /** \brief Executes the KDF command, which derives a new key in PRF, AES, or * HKDF modes. * @@ -136,3 +137,4 @@ ATCA_STATUS calib_kdf(ATCADevice device, uint8_t mode, uint16_t key_id, const ui return status; } +#endif /* CALIB_KDF */ diff --git a/lib/calib/calib_lock.c b/lib/calib/calib_lock.c index f7fee5f65..04f27b9c2 100644 --- a/lib/calib/calib_lock.c +++ b/lib/calib/calib_lock.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_LOCK_EN || CALIB_LOCK_ECC204_EN /** \brief The Lock command prevents future modifications of the Configuration * and/or Data and OTP zones. If the device is so configured, then * this command can be used to lock individual data slots. This @@ -81,7 +82,9 @@ ATCA_STATUS calib_lock(ATCADevice device, uint8_t mode, uint16_t summary_crc) return status; } +#endif +#if CALIB_LOCK_EN /** \brief Unconditionally (no CRC required) lock the config zone. * * \param[in] device Device context pointer @@ -89,7 +92,17 @@ ATCA_STATUS calib_lock(ATCADevice device, uint8_t mode, uint16_t summary_crc) */ ATCA_STATUS calib_lock_config_zone(ATCADevice device) { - return calib_lock(device, LOCK_ZONE_NO_CRC | LOCK_ZONE_CONFIG, 0); +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_lock_config_zone(device); + } + else +#endif + { + return calib_lock(device, LOCK_ZONE_NO_CRC | LOCK_ZONE_CONFIG, 0); + } + } /** \brief Lock the config zone with summary CRC. @@ -105,7 +118,16 @@ ATCA_STATUS calib_lock_config_zone(ATCADevice device) */ ATCA_STATUS calib_lock_config_zone_crc(ATCADevice device, uint16_t summary_crc) { - return calib_lock(device, LOCK_ZONE_CONFIG, summary_crc); +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + return ATCA_UNIMPLEMENTED; + } + else +#endif + { + return calib_lock(device, LOCK_ZONE_CONFIG, summary_crc); + } } /** \brief Unconditionally (no CRC required) lock the data zone (slots and OTP). @@ -117,7 +139,16 @@ ATCA_STATUS calib_lock_config_zone_crc(ATCADevice device, uint16_t summary_crc) */ ATCA_STATUS calib_lock_data_zone(ATCADevice device) { - return calib_lock(device, LOCK_ZONE_NO_CRC | LOCK_ZONE_DATA, 0); +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_lock_data_zone(device); + } + else +#endif + { + return calib_lock(device, LOCK_ZONE_NO_CRC | LOCK_ZONE_DATA, 0); + } } /** \brief Lock the data zone (slots and OTP) with summary CRC. @@ -133,7 +164,16 @@ ATCA_STATUS calib_lock_data_zone(ATCADevice device) */ ATCA_STATUS calib_lock_data_zone_crc(ATCADevice device, uint16_t summary_crc) { - return calib_lock(device, LOCK_ZONE_DATA, summary_crc); +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + return ATCA_UNIMPLEMENTED; + } + else +#endif + { + return calib_lock(device, LOCK_ZONE_DATA, summary_crc); + } } /** \brief Lock an individual slot in the data zone on an ATECC device. Not @@ -147,9 +187,20 @@ ATCA_STATUS calib_lock_data_zone_crc(ATCADevice device, uint16_t summary_crc) */ ATCA_STATUS calib_lock_data_slot(ATCADevice device, uint16_t slot) { - return calib_lock(device, ((uint8_t)slot << 2) | LOCK_ZONE_DATA_SLOT, 0); +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_lock_data_slot(device, slot); + } + else +#endif + { + return calib_lock(device, ((uint8_t)slot << 2) | LOCK_ZONE_DATA_SLOT, 0); + } } +#endif +#if CALIB_LOCK_ECC204_EN /** \brief Use Lock command to lock individual configuration zone slots * * \param[in] device Device context pointer @@ -256,3 +307,4 @@ ATCA_STATUS calib_ecc204_lock_data_zone(ATCADevice device) return status; } +#endif diff --git a/lib/calib/calib_mac.c b/lib/calib/calib_mac.c index 1c362204d..b09599e6a 100644 --- a/lib/calib/calib_mac.c +++ b/lib/calib/calib_mac.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_MAC_EN /** \brief Executes MAC command, which computes a SHA-256 digest of a key * stored in the device, a challenge, and other information on the * device. @@ -93,3 +94,4 @@ ATCA_STATUS calib_mac(ATCADevice device, uint8_t mode, uint16_t key_id, const ui return status; } +#endif /* CALIB_MAC_EN */ diff --git a/lib/calib/calib_nonce.c b/lib/calib/calib_nonce.c index 35e65fd73..c704a7b68 100644 --- a/lib/calib/calib_nonce.c +++ b/lib/calib/calib_nonce.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" +#if CALIB_NONCE_EN /** \brief Executes Nonce command, which loads a random or fixed nonce/data * into the device for use by subsequent commands. * @@ -119,7 +120,6 @@ ATCA_STATUS calib_nonce_base(ATCADevice device, uint8_t mode, uint16_t param2, c return status; } - /** \brief Execute a Nonce command in pass-through mode to initialize TempKey * to a specified value. * @@ -133,7 +133,6 @@ ATCA_STATUS calib_nonce(ATCADevice device, const uint8_t *num_in) return calib_nonce_base(device, NONCE_MODE_PASSTHROUGH, 0, num_in, NULL); } - /** \brief Execute a Nonce command in pass-through mode to load one of the * device's internal buffers with a fixed value. * @@ -234,3 +233,4 @@ ATCA_STATUS calib_nonce_gen_session_key(ATCADevice device, uint16_t param2, uint { return calib_nonce_base(device, NONCE_MODE_GEN_SESSION_KEY, param2, num_in, rand_out); } +#endif /* CALIB_NONCE_EN */ diff --git a/lib/calib/calib_privwrite.c b/lib/calib/calib_privwrite.c index db0733c36..7fff23aae 100644 --- a/lib/calib/calib_privwrite.c +++ b/lib/calib/calib_privwrite.c @@ -33,6 +33,9 @@ */ #include "cryptoauthlib.h" + +#if CALIB_PRIVWRITE_EN + #include "host/atca_host.h" /** \brief Executes PrivWrite command, to write externally generated ECC @@ -188,3 +191,4 @@ ATCA_STATUS calib_priv_write(ATCADevice device, uint16_t key_id, const uint8_t p return status; } +#endif /* CALIB_PRIVWRITE_EN */ diff --git a/lib/calib/calib_random.c b/lib/calib/calib_random.c index 90516a13c..e9087a327 100644 --- a/lib/calib/calib_random.c +++ b/lib/calib/calib_random.c @@ -33,6 +33,7 @@ #include "cryptoauthlib.h" +#if CALIB_RANDOM_EN /** \brief Executes Random command, which generates a 32 byte random number * from the CryptoAuth device. * @@ -86,3 +87,4 @@ ATCA_STATUS calib_random(ATCADevice device, uint8_t *rand_out) return status; } +#endif /* CALIB_RANDOM_EN */ diff --git a/lib/calib/calib_read.c b/lib/calib/calib_read.c index 4acefea7f..a7c2d13af 100644 --- a/lib/calib/calib_read.c +++ b/lib/calib/calib_read.c @@ -34,8 +34,12 @@ */ #include "cryptoauthlib.h" + +#if CALIB_READ_ENC_EN #include "host/atca_host.h" +#endif +#if CALIB_READ_EN /** \brief Executes Read command, which reads either 4 or 32 bytes of data from * a given slot, configuration zone, or the OTP zone. * @@ -63,17 +67,8 @@ ATCA_STATUS calib_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint do { // Check the input parameters - if ((device == NULL) || (data == NULL)) - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - break; - } - - if (len != 4 && len != 32) - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid length received"); - break; - } + ATCA_CHECK_INVALID_MSG((!device || !data), ATCA_BAD_PARAM, "NULL pointer received"); + ATCA_CHECK_INVALID_MSG((len != 4 && len != 32), ATCA_BAD_PARAM, "NULL pointer received"); // The get address function checks the remaining variables if ((status = calib_get_addr(zone, slot, block, offset, &addr)) != ATCA_SUCCESS) @@ -110,6 +105,7 @@ ATCA_STATUS calib_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint return status; } + /** \brief Executes Read command, which reads the 9 byte serial number of the * device from the config zone. * @@ -143,7 +139,30 @@ ATCA_STATUS calib_read_serial_number(ATCADevice device, uint8_t* serial_number) return status; } +/** \brief Executes Read command, which reads the 9 byte serial number of the + * device from the config zone. + * + * \param[in] device Device context pointer + * \param[out] serial_number 9 byte serial number is returned here. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_read_serial_number_ext(ATCADevice device, uint8_t* serial_number) +{ +#if CALIB_ECC204_EN + if (ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_read_serial_number(device, serial_number); + } + else +#endif + { + return calib_read_serial_number(device, serial_number); + } +} +#endif +#if CALIB_READ_ENC_EN /** \brief Executes Read command on a slot configured for encrypted reads and * decrypts the data to return it as plaintext. * @@ -265,415 +284,250 @@ ATCA_STATUS calib_read_enc(ATCADevice device, uint16_t key_id, uint8_t block, ui return status; } +#endif /* CALIB_READ_ENC_EN */ -/** \brief Executes Read command to read the complete device configuration - * zone. +#if CALIB_READ_EN +/** \brief Used to read an arbitrary number of bytes from any zone configured + * for clear reads. * - * \param[in] device Device context pointer - * \param[out] config_data Configuration zone data is returned here. 88 bytes - * for ATSHA devices, 128 bytes for ATECC devices. + * This function will issue the Read command as many times as is required to + * read the requested data. * - * \returns ATCA_SUCCESS on success, otherwise an error code. + * \param[in] device Device context pointer + * \param[in] zone Zone to read data from. Option are ATCA_ZONE_CONFIG(0), + * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). + * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). + * Ignored for all other zones. + * \param[in] offset Byte offset within the zone to read from. + * \param[out] data Read data is returned here. + * \param[in] length Number of bytes to read starting from the offset. + * + * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS calib_read_config_zone(ATCADevice device, uint8_t* config_data) +ATCA_STATUS calib_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length) { ATCA_STATUS status = ATCA_GEN_FAIL; + size_t zone_size = 0; + uint8_t read_buf[32]; + size_t data_idx = 0; + size_t cur_block = 0; + size_t cur_offset = 0; + uint8_t read_size = ATCA_BLOCK_SIZE; + size_t read_buf_idx = 0; + size_t copy_length = 0; + size_t read_offset = 0; - do - { - // Verify the inputs - if (config_data == NULL) - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - break; - } - - if (atIsSHAFamily(device->mIface.mIfaceCFG->devtype)) - { - status = calib_read_bytes_zone(device, ATCA_ZONE_CONFIG, 0, 0x00, config_data, ATCA_SHA_CONFIG_SIZE); - } - else - { - status = calib_read_bytes_zone(device, ATCA_ZONE_CONFIG, 0, 0x00, config_data, ATCA_ECC_CONFIG_SIZE); - } - - if (status != ATCA_SUCCESS) - { - ATCA_TRACE(status, "calib_read_bytes_zone - failed"); - break; - } + ATCA_CHECK_INVALID_MSG((zone != ATCA_ZONE_CONFIG && zone != ATCA_ZONE_OTP && zone != ATCA_ZONE_DATA), ATCA_BAD_PARAM, "Invalid zone received"); + ATCA_CHECK_INVALID_MSG((zone == ATCA_ZONE_DATA && slot > 15), ATCA_BAD_PARAM, "Invalid slot received"); + if (length == 0) + { + return ATCA_SUCCESS; // Always succeed reading 0 bytes } - while (0); - return status; -} - -/** \brief Compares a specified configuration zone with the configuration zone - * currently on the device. - * - * This only compares the static portions of the configuration zone and skips - * those that are unique per device (first 16 bytes) and areas that can change - * after the configuration zone has been locked (e.g. LastKeyUse). - * - * \param[in] device Device context pointer - * \param[in] config_data Full configuration data to compare the device - * against. - * \param[out] same_config Result is returned here. True if the static portions - * on the configuration zones are the same. - * - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config) -{ - ATCA_STATUS status = ATCA_GEN_FAIL; - uint8_t device_config_data[ATCA_ECC_CONFIG_SIZE]; /** Max for all configs */ - size_t config_size = 0; + ATCA_CHECK_INVALID_MSG(!data, ATCA_BAD_PARAM, "NULL pointer received"); do { - // Check the inputs - if ((config_data == NULL) || (same_config == NULL)) + if (ATCA_SUCCESS != (status = calib_get_zone_size(device, zone, slot, &zone_size))) { - status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + ATCA_TRACE(status, "calib_get_zone_size - failed"); break; } - // Set the boolean to false - *same_config = false; - - // Read all of the configuration bytes from the device - if ((status = calib_read_config_zone(device, device_config_data)) != ATCA_SUCCESS) - { - ATCA_TRACE(status, "Read config zone failed"); break; - } - /* Get the config size of the device being tested */ - if (ATCA_SUCCESS != (status = calib_get_zone_size(device, ATCA_ZONE_CONFIG, 0, &config_size))) - { - ATCA_TRACE(status, "Failed to get config zone size"); break; - } + // Can't read past the end of a zone + ATCA_CHECK_INVALID_MSG((offset + length > zone_size), ATCA_BAD_PARAM, "Invalid parameter received"); - /* Compare the lower writable bytes (16-51) */ - if (memcmp(&device_config_data[16], &config_data[16], 52 - 16)) - { - /* Difference found */ - break; - } + cur_block = offset / ATCA_BLOCK_SIZE; - if (ATECC608 == device->mIface.mIfaceCFG->devtype) + while (data_idx < length) { - /* Skip Counter[0], Counter[1], which can change during operation */ + if (read_size == ATCA_BLOCK_SIZE && zone_size - cur_block * ATCA_BLOCK_SIZE < ATCA_BLOCK_SIZE) + { + // We have less than a block to read and can't read past the end of the zone, switch to word reads + read_size = ATCA_WORD_SIZE; + cur_offset = ((data_idx + offset) / ATCA_WORD_SIZE) % (ATCA_BLOCK_SIZE / ATCA_WORD_SIZE); + } - /* Compare UseLock through Reserved (68 --> 83) */ - if (memcmp(&device_config_data[68], &config_data[68], 84 - 68)) + // Read next chunk of data + if (ATCA_SUCCESS != (status = calib_read_zone(device, zone, slot, (uint8_t)cur_block, (uint8_t)cur_offset, read_buf, read_size))) { - /* Difference found */ + ATCA_TRACE(status, "calib_read_zone - falied"); break; } - /* Skip UserExtra, UserExtraAdd, LockValue, LockConfig, and SlotLocked */ + // Calculate where in the read buffer we need data from + read_offset = cur_block * ATCA_BLOCK_SIZE + cur_offset * ATCA_WORD_SIZE; + if (read_offset < offset) + { + read_buf_idx = offset - read_offset; // Read data starts before the requested chunk + } + else + { + read_buf_idx = 0; // Read data is within the requested chunk - } - else - { - /* Skip the counter & LastKeyUse bytes [52-83] */ - /* Skip User Extra & Selector [84-85] */ - /* Skip all lock bytes [86-89] */ - } + } + // Calculate how much data from the read buffer we want to copy + if (length - data_idx < read_size - read_buf_idx) + { + copy_length = length - data_idx; + } + else + { + copy_length = read_size - read_buf_idx; + } - if (90 < config_size) - { - /* Compare the upper writable bytes (90-config_size) */ - if (memcmp(&device_config_data[90], &config_data[90], config_size - 90)) + memcpy(&data[data_idx], &read_buf[read_buf_idx], copy_length); + data_idx += copy_length; + if (read_size == ATCA_BLOCK_SIZE) { - /* Difference found */ - break; + cur_block += 1; + } + else + { + cur_offset += 1; } } - - /* All Matched */ - *same_config = true; + if (status != ATCA_SUCCESS) + { + break; + } } - while (0); + while (false); return status; } - -/** \brief Executes Read command to read a 64 byte ECDSA P256 signature from a - * slot configured for clear reads. +/** \brief Used to read an arbitrary number of bytes from any zone configured + * for clear reads. + * + * This function will issue the Read command as many times as is required to + * read the requested data. * * \param[in] device Device context pointer - * \param[in] slot Slot number to read from. Only slots 8 to 15 are large - * enough for a signature. - * \param[out] sig Signature will be returned here (64 bytes). Format will be - * the 32 byte R and S big-endian integers concatenated. + * \param[in] zone Zone to read data from. Option are ATCA_ZONE_CONFIG(0), + * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). + * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). + * Ignored for all other zones. + * \param[in] offset Byte offset within the zone to read from. + * \param[out] data Read data is returned here. + * \param[in] length Number of bytes to read starting from the offset. * * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS calib_read_sig(ATCADevice device, uint16_t slot, uint8_t* sig) +ATCA_STATUS calib_read_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length) { - ATCA_STATUS status = ATCA_GEN_FAIL; +#if CALIB_ECC204_EN + if (ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_read_bytes_zone(device, zone, slot, offset, data, length); + } + else +#endif + { + return calib_read_bytes_zone(device, zone, slot, offset, data, length); + } +} - do +/** \brief Compares a specified configuration zone with the configuration zone + * currently on the SHA device. + * + * This only compares the static portions of the configuration zone and skips + * those that are unique per device (first 16 bytes) and areas that can change + * after the configuration zone has been locked (e.g. Counter). + + * \return TRUE if the zones pass the comparison test otherwise FALSE + */ +bool calib_sha_compare_config( + uint8_t* expected, /**< [in] Expected configuration zone */ + uint8_t* other /**< [in] Read or Other buffer to compare */ + ) +{ + bool same = false; + + if (expected && other) { - // Check the value of the slot - if (sig == NULL) + /* Compare only the user writeable and lockable bytes of the + config zone - i.e. those that do not change with the device operation + and are not configured by the factory + Bytes [16 - 52] */ + if (!memcmp(&expected[16], &other[16], 52 - 16)) { - status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - break; + same = true; } + } + return same; +} - if (slot < 8 || slot > 15) - { - status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); - break; - } +/** \brief Compares a specified configuration zone with the configuration zone + * currently on the ECC device. + * + * \return TRUE if the zones pass the comparison test otherwise FALSE + */ +bool calib_ecc_compare_config( + uint8_t* expected, /**< [in] Expected configuration zone */ + uint8_t* other /**< [in] Read or Other buffer to compare */ + ) +{ + bool same = false; - // Read the first block - if ((status = calib_read_zone(device, ATCA_ZONE_DATA, slot, 0, 0, &sig[0], ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + if (expected && other) + { + /* Compare only the user writeable and lockable bytes of the + config zone - i.e. those that do not change with the device operation + and are not configured by the factory + Bytes [16 - 52] & [90 - 128]*/ + if (!memcmp(&expected[16], &other[16], 52 - 16) && + !memcmp(&expected[90], &other[90], 128 - 90)) { - ATCA_TRACE(status, "calib_read_zone - failed"); - break; + same = true; } + } + return same; +} - // Read the second block - if ((status = calib_read_zone(device, ATCA_ZONE_DATA, slot, 1, 0, &sig[ATCA_BLOCK_SIZE], ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) +/** \brief Compares a specified configuration zone with the configuration zone + * currently on the ECC608 device. + * + * \return TRUE if the zones pass the comparison test otherwise FALSE + */ +bool calib_ecc608_compare_config( + uint8_t* expected, /**< [in] Expected configuration zone */ + uint8_t* other /**< [in] Read or Other buffer to compare */ + ) +{ + bool same = false; + + if (expected && other) + { + /* Compare only the user writeable and lockable bytes of the + config zone - i.e. those that do not change with the device operation + and are not configured by the factory: + Bytes [16 - 52] & [68 - 84] & [90 - 128]*/ + if (!memcmp(&expected[16], &other[16], 52 - 16) && + !memcmp(&expected[68], &other[68], 84 - 68) && + !memcmp(&expected[90], &other[90], 128 - 90)) { - ATCA_TRACE(status, "calib_read_zone - failed"); - break; + same = true; } } - while (0); - - return status; + return same; } -/** \brief Executes Read command to read an ECC P256 public key from a slot - * configured for clear reads. +#endif /* CALIB_READ_EN */ + +#if CALIB_READ_ECC204_EN +/** \brief Use Read command to reads words 16 bytes from one of the slots in the EEPROM Configuration + * zone or 32 bytes in Data zone. * - * This function assumes the public key is stored using the ECC public key - * format specified in the datasheet. - * - * \param[in] device Device context pointer - * \param[in] slot Slot number to read from. Only slots 8 to 15 are - * large enough for a public key. - * \param[out] public_key Public key is returned here (64 bytes). Format will - * be the 32 byte X and Y big-endian integers - * concatenated. - * - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_read_pubkey(ATCADevice device, uint16_t slot, uint8_t *public_key) -{ - ATCA_STATUS status = ATCA_GEN_FAIL; - uint8_t read_buf[ATCA_BLOCK_SIZE]; - uint8_t block = 0; - uint8_t offset = 0; - uint8_t cpy_index = 0; - uint8_t cpy_size = 0; - uint8_t read_index = 0; - - // Check the pointers - if (public_key == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } - // Check the value of the slot - if (slot < 8 || slot > 0xF) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); - } - - do - { - // The 64 byte P256 public key gets written to a 72 byte slot in the following pattern - // | Block 1 | Block 2 | Block 3 | - // | Pad: 4 Bytes | PubKey[0:27] | PubKey[28:31] | Pad: 4 Bytes | PubKey[32:55] | PubKey[56:63] | - - // Read the block - block = 0; - if ((status = calib_read_zone(device, ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) - { - ATCA_TRACE(status, "calib_read_zone - failed"); - break; - } - - // Copy. Account for 4 byte pad - cpy_size = ATCA_BLOCK_SIZE - ATCA_PUB_KEY_PAD; - read_index = ATCA_PUB_KEY_PAD; - memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); - cpy_index += cpy_size; - - // Read the next block - block = 1; - if ((status = calib_read_zone(device, ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) - { - ATCA_TRACE(status, "calib_read_zone - failed"); - break; - } - - // Copy. First four bytes - cpy_size = ATCA_PUB_KEY_PAD; - read_index = 0; - memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); - cpy_index += cpy_size; - // Copy. Skip four bytes - read_index = ATCA_PUB_KEY_PAD + ATCA_PUB_KEY_PAD; - cpy_size = ATCA_BLOCK_SIZE - read_index; - memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); - cpy_index += cpy_size; - - // Read the next block - block = 2; - if ((status = calib_read_zone(device, ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) - { - ATCA_TRACE(status, "calib_read_zone - failed"); - break; - } - - // Copy. The remaining 8 bytes - cpy_size = ATCA_PUB_KEY_PAD + ATCA_PUB_KEY_PAD; - read_index = 0; - memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); - - } - while (0); - - return status; -} - -/** \brief Used to read an arbitrary number of bytes from any zone configured - * for clear reads. - * - * This function will issue the Read command as many times as is required to - * read the requested data. - * - * \param[in] device Device context pointer - * \param[in] zone Zone to read data from. Option are ATCA_ZONE_CONFIG(0), - * ATCA_ZONE_OTP(1), or ATCA_ZONE_DATA(2). - * \param[in] slot Slot number to read from if zone is ATCA_ZONE_DATA(2). - * Ignored for all other zones. - * \param[in] offset Byte offset within the zone to read from. - * \param[out] data Read data is returned here. - * \param[in] length Number of bytes to read starting from the offset. - * - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_read_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset, uint8_t *data, size_t length) -{ - ATCA_STATUS status = ATCA_GEN_FAIL; - size_t zone_size = 0; - uint8_t read_buf[32]; - size_t data_idx = 0; - size_t cur_block = 0; - size_t cur_offset = 0; - uint8_t read_size = ATCA_BLOCK_SIZE; - size_t read_buf_idx = 0; - size_t copy_length = 0; - size_t read_offset = 0; - - if (zone != ATCA_ZONE_CONFIG && zone != ATCA_ZONE_OTP && zone != ATCA_ZONE_DATA) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid zone received"); - } - if (zone == ATCA_ZONE_DATA && slot > 15) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); - } - if (length == 0) - { - return ATCA_SUCCESS; // Always succeed reading 0 bytes - } - if (data == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } - - do - { - if (ATCA_SUCCESS != (status = calib_get_zone_size(device, zone, slot, &zone_size))) - { - ATCA_TRACE(status, "calib_get_zone_size - failed"); - break; - } - if (offset + length > zone_size) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid parameter received"); // Can't read past the end of a zone - - } - cur_block = offset / ATCA_BLOCK_SIZE; - - while (data_idx < length) - { - if (read_size == ATCA_BLOCK_SIZE && zone_size - cur_block * ATCA_BLOCK_SIZE < ATCA_BLOCK_SIZE) - { - // We have less than a block to read and can't read past the end of the zone, switch to word reads - read_size = ATCA_WORD_SIZE; - cur_offset = ((data_idx + offset) / ATCA_WORD_SIZE) % (ATCA_BLOCK_SIZE / ATCA_WORD_SIZE); - } - - // Read next chunk of data - if (ATCA_SUCCESS != (status = calib_read_zone(device, zone, slot, (uint8_t)cur_block, (uint8_t)cur_offset, read_buf, read_size))) - { - ATCA_TRACE(status, "calib_read_zone - falied"); - break; - } - - // Calculate where in the read buffer we need data from - read_offset = cur_block * ATCA_BLOCK_SIZE + cur_offset * ATCA_WORD_SIZE; - if (read_offset < offset) - { - read_buf_idx = offset - read_offset; // Read data starts before the requested chunk - } - else - { - read_buf_idx = 0; // Read data is within the requested chunk - - } - // Calculate how much data from the read buffer we want to copy - if (length - data_idx < read_size - read_buf_idx) - { - copy_length = length - data_idx; - } - else - { - copy_length = read_size - read_buf_idx; - } - - memcpy(&data[data_idx], &read_buf[read_buf_idx], copy_length); - data_idx += copy_length; - if (read_size == ATCA_BLOCK_SIZE) - { - cur_block += 1; - } - else - { - cur_offset += 1; - } - } - if (status != ATCA_SUCCESS) - { - break; - } - } - while (false); - - return status; -} - -#if defined(ATCA_ECC204_SUPPORT) -/** \brief Use Read command to reads words 16 bytes from one of the slots in the EEPROM Configuration - * zone or 32 bytes in Data zone. - * - * \param[in] device Device context pointer - * \param[in] zone Selects config or data zone - * \param[in] slot select slot in config or data zone - * \param[in] block select the lock in given slot - * \param[in] offset 16 byte work index within the block. Ignored for 32 byte - * reads. - * \param[out] data Read data is returned here. - * \param[in] len Length of the data to be read. Must be either 16 or 32. + * \param[in] device Device context pointer + * \param[in] zone Selects config or data zone + * \param[in] slot select slot in config or data zone + * \param[in] block select the lock in given slot + * \param[in] offset 16 byte work index within the block. Ignored for 32 byte + * reads. + * \param[out] data Read data is returned here. + * \param[in] len Length of the data to be read. Must be either 16 or 32. * * \return ATCA_SUCCESS on success, otherwise an error code */ @@ -694,7 +548,7 @@ ATCA_STATUS calib_ecc204_read_zone(ATCADevice device, uint8_t zone, uint16_t slo { status = ATCA_TRACE(ATCA_BAD_PARAM, "Encountered Null pointer"); } - else if (ATCA_ZONE_DATA == zone) + else if (ATCA_ECC204_ZONE_DATA == read_zone) { if (32 != len) { @@ -704,21 +558,13 @@ ATCA_STATUS calib_ecc204_read_zone(ATCADevice device, uint8_t zone, uint16_t slo { status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot number received"); } - else - { - read_zone = ATCA_ECC204_ZONE_DATA; - } } - else if (ATCA_ECC204_ZONE_CONFIG == zone) + else if (ATCA_ECC204_ZONE_CONFIG == read_zone) { if (16 != len) { status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid parameter received"); } - else - { - read_zone = ATCA_ECC204_ZONE_CONFIG; - } } if (ATCA_SUCCESS == status) @@ -766,7 +612,7 @@ ATCA_STATUS calib_ecc204_read_config_zone(ATCADevice device, uint8_t* config_dat while (slot <= 3) { - if (ATCA_SUCCESS != (status = calib_ecc204_read_zone(device, ATCA_ECC204_ZONE_CONFIG, + if (ATCA_SUCCESS != (status = calib_ecc204_read_zone(device, ATCA_ZONE_CONFIG, slot, 0, 0, &config_data[ATCA_ECC204_CONFIG_SLOT_SIZE * slot], ATCA_ECC204_CONFIG_SLOT_SIZE))) @@ -793,7 +639,7 @@ ATCA_STATUS calib_ecc204_read_serial_number(ATCADevice device, uint8_t* serial_n uint8_t read_buf[ATCA_ECC204_CONFIG_SLOT_SIZE]; - status = calib_ecc204_read_zone(device, ATCA_ECC204_ZONE_CONFIG, 0, 0, 0, read_buf, + status = calib_ecc204_read_zone(device, ATCA_ZONE_CONFIG, 0, 0, 0, read_buf, ATCA_ECC204_CONFIG_SLOT_SIZE); if (ATCA_SUCCESS == status) @@ -825,7 +671,7 @@ ATCA_STATUS calib_ecc204_read_bytes_zone(ATCADevice device, uint8_t zone, uint16 size_t offset, uint8_t* data, size_t length) { ATCA_STATUS status = ATCA_GEN_FAIL; - uint8_t block_size = (zone == ATCA_ECC204_ZONE_CONFIG) ? ATCA_ECC204_CONFIG_SLOT_SIZE : ATCA_BLOCK_SIZE; + uint8_t block_size = (zone == ATCA_ZONE_CONFIG) ? ATCA_ECC204_CONFIG_SLOT_SIZE : ATCA_BLOCK_SIZE; uint8_t no_of_blocks; uint8_t data_idx = 0; size_t cur_block = 0; @@ -834,8 +680,12 @@ ATCA_STATUS calib_ecc204_read_bytes_zone(ATCADevice device, uint8_t zone, uint16 { return ATCA_TRACE(ATCA_BAD_PARAM, "Encountered NULL pointer"); } - else if ((ATCA_ECC204_ZONE_DATA == zone) && (((length > 64) && (2 == slot)) || - ((length > 320) && (1 == slot)) || (3 == slot) || (0 == slot))) + else if ((ATCA_ZONE_DATA == zone) && (((length > 64) && (2 == slot)) || + ((length > 320) && (1 == slot)) || (3 == slot) || (0 == slot))) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid parameter received"); + } + else if (ATCA_ZONE_CONFIG == zone) { return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid parameter received"); } @@ -856,26 +706,126 @@ ATCA_STATUS calib_ecc204_read_bytes_zone(ATCADevice device, uint8_t zone, uint16 break; } - if (zone == ATCA_ECC204_ZONE_CONFIG) + cur_block += 1; + data_idx += 1; // increment data index + } + + return status; +} + +/** \brief Compares a specified configuration zone with the configuration zone + * currently on the ECC204 device. + * + * This only compares the static portions of the configuration zone and skips + * those that are unique per device (first 16 bytes) and areas that can change + * after the configuration zone has been locked (e.g. Counter). + + * \return TRUE if the zones pass the comparison test otherwise FALSE + */ +bool calib_ecc204_compare_config( + uint8_t* expected, /**< [in] Expected configuration zone */ + uint8_t* other /**< [in] Read or Other buffer to compare */ + ) +{ + bool same = false; + + if (expected && other) + { + // compare slot 1 and slot 3 data && skip first 16 bytes and counter value + if (!((memcmp(&expected[16], &other[16], ATCA_ECC204_CONFIG_SLOT_SIZE)) || + (memcmp(&expected[48], &other[48], ATCA_ECC204_CONFIG_SLOT_SIZE)))) { - slot += 1; + same = true; } - else + } + return same; +} +#endif /* CALIB_READ_EN */ + +#if CALIB_READ_EN || CALIB_READ_ECC204_EN +/** \brief Checks the device type and maps to the correct read operation + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_read_zone_ext( + ATCADevice device, /**< [in] Device context pointer */ + uint8_t zone, /**< [in] Zone to be read from device. Options are + ATCA_ZONE_CONFIG, ATCA_ZONE_OTP, or ATCA_ZONE_DATA.*/ + uint16_t slot, /**< [in] Slot number for data zone and ignored for other zones. */ + uint8_t block, /**< [in] 32 byte block index within the zone. */ + uint8_t offset, /**< [in] 4 byte work index within the block. Ignored for 32 byte + reads. */ + uint8_t * data, /**< [out] Read data is returned here. */ + uint8_t len /**< [in] Length of the data to be read. Must be either 4 or 32. */ + ) +{ +#if CALIB_ECC204_EN + ATCADeviceType devtype = atcab_get_device_type_ext(device); + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (ECC204 == devtype) + { + status = calib_ecc204_read_zone(device, zone, slot, block, offset, data, len); + } +#if CALIB_READ_EN + else if (atcab_is_ca_device(devtype)) + { + status = calib_read_zone(device, zone, slot, block, offset, data, len); + } +#endif /* CALIB_READ_EN */ + return status; +#else + return calib_read_zone(device, zone, slot, block, offset, data, len); +#endif /* CALIB_ECC204_EN */ +} + +/** \brief Executes Read command to read the complete device configuration + * zone. + * + * \param[in] device Device context pointer + * \param[out] config_data Configuration zone data is returned here. 88 bytes + * for ATSHA devices, 128 bytes for ATECC devices. + * + * \returns ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_read_config_zone(ATCADevice device, uint8_t* config_data) +{ + ATCADeviceType devtype = atcab_get_device_type_ext(device); + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (config_data) + { + switch (devtype) { - cur_block += 1; +#if CALIB_SHA204_EN || CALIB_SHA206_EN + case ATSHA204A: + /* fallthrough */ + case ATSHA206A: + status = calib_read_bytes_zone(device, ATCA_ZONE_CONFIG, 0, 0x00, config_data, ATCA_SHA_CONFIG_SIZE); + break; +#endif +#if CALIB_ECC204_EN + case ECC204: + status = calib_ecc204_read_config_zone(device, config_data); + break; +#endif + default: +#if CALIB_ECC108_EN || CALIB_ECC508_EN || CALIB_ECC608_EN + /* ECCx08 as the default */ + status = calib_read_bytes_zone(device, ATCA_ZONE_CONFIG, 0, 0x00, config_data, ATCA_ECC_CONFIG_SIZE); +#endif + break; } - data_idx += 1; // increment data index } return status; } /** \brief Compares a specified configuration zone with the configuration zone - * currently on the ECC204 device. + * currently on the device. * * This only compares the static portions of the configuration zone and skips * those that are unique per device (first 16 bytes) and areas that can change - * after the configuration zone has been locked (e.g. Counter). + * after the configuration zone has been locked (e.g. LastKeyUse). * * \param[in] device Device context pointer * \param[in] config_data Full configuration data to compare the device @@ -885,36 +835,200 @@ ATCA_STATUS calib_ecc204_read_bytes_zone(ATCADevice device, uint8_t zone, uint16 * * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS calib_ecc204_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config) +ATCA_STATUS calib_cmp_config_zone(ATCADevice device, uint8_t* config_data, bool* same_config) { - ATCA_STATUS status = ATCA_SUCCESS; - uint8_t device_config_data[ATCA_ECC204_CONFIG_SIZE]; + ATCA_STATUS status = ATCA_BAD_PARAM; + ATCADeviceType devtype = atcab_get_device_type_ext(device); + uint8_t device_config_data[ATCA_ECC_CONFIG_SIZE]; /** Max for all configs */ - if ((NULL == device) || (NULL == config_data) || (NULL == same_config)) + do { - status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); + // Check the inputs + if (!device || !config_data || !same_config) + { + break; + } + // Set the boolean to false + *same_config = false; + + // Read all of the configuration bytes from the device + if ((status = calib_read_config_zone(device, device_config_data)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "Read config zone failed"); + break; + } + + switch (devtype) + { +#if CALIB_SHA204_EN || CALIB_SHA206_EN + case ATSHA204A: + /* fallthrough */ + case ATSHA206A: + *same_config = calib_sha_compare_config(config_data, device_config_data); + break; +#endif +#if CALIB_ECC608_EN + case ATECC608: + *same_config = calib_ecc608_compare_config(config_data, device_config_data); + break; +#endif +#if CALIB_ECC204_EN + case ECC204: + *same_config = calib_ecc204_compare_config(config_data, device_config_data); + break; +#endif + default: +#if CALIB_ECC108_EN || CALIB_ECC508_EN + *same_config = calib_ecc_compare_config(config_data, device_config_data); +#endif + break; + } } + while (0); - if (ATCA_SUCCESS == status) + return status; +} + +/** \brief Executes Read command to read a 64 byte ECDSA P256 signature from a + * slot configured for clear reads. + * + * \param[in] device Device context pointer + * \param[in] slot Slot number to read from. Only slots 8 to 15 are large + * enough for a signature. + * \param[out] sig Signature will be returned here (64 bytes). Format will be + * the 32 byte R and S big-endian integers concatenated. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_read_sig(ATCADevice device, uint16_t slot, uint8_t* sig) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + + do { - *same_config = false; - if (ATCA_SUCCESS != (status = calib_ecc204_read_config_zone(device, device_config_data))) + // Check the value of the slot + if (sig == NULL) { - ATCA_TRACE(status, "calib_ecc204_read_config_zone - failed"); + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + break; + } + + if (slot < 8 || slot > 15) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); + break; + } + + // Read the first block + if ((status = calib_read_zone_ext(device, ATCA_ZONE_DATA, slot, 0, 0, &sig[0], ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "calib_read_zone - failed"); + break; + } + + // Read the second block + if ((status = calib_read_zone_ext(device, ATCA_ZONE_DATA, slot, 1, 0, &sig[ATCA_BLOCK_SIZE], ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "calib_read_zone - failed"); + break; } } + while (0); - if (ATCA_SUCCESS == status) + return status; +} + +/** \brief Executes Read command to read an ECC P256 public key from a slot + * configured for clear reads. + * + * This function assumes the public key is stored using the ECC public key + * format specified in the datasheet. + * + * \param[in] device Device context pointer + * \param[in] slot Slot number to read from. Only slots 8 to 15 are + * large enough for a public key. + * \param[out] public_key Public key is returned here (64 bytes). Format will + * be the 32 byte X and Y big-endian integers + * concatenated. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_read_pubkey(ATCADevice device, uint16_t slot, uint8_t *public_key) +{ + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t read_buf[ATCA_BLOCK_SIZE]; + uint8_t block = 0; + uint8_t offset = 0; + uint8_t cpy_index = 0; + uint8_t cpy_size = 0; + uint8_t read_index = 0; + + // Check the pointers + if (public_key == NULL) { - // compare slot 1 and slot 3 data && skip first 16 bytes and counter value - if (!((memcmp(&device_config_data[16], &config_data[16], ATCA_ECC204_CONFIG_SLOT_SIZE)) || - (memcmp(&device_config_data[48], &config_data[48], ATCA_ECC204_CONFIG_SLOT_SIZE)))) + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + // Check the value of the slot + if (slot < 8 || slot > 0xF) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "Invalid slot received"); + } + + do + { + // The 64 byte P256 public key gets written to a 72 byte slot in the following pattern + // | Block 1 | Block 2 | Block 3 | + // | Pad: 4 Bytes | PubKey[0:27] | PubKey[28:31] | Pad: 4 Bytes | PubKey[32:55] | PubKey[56:63] | + + // Read the block + block = 0; + if ((status = calib_read_zone_ext(device, ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "calib_read_zone - failed"); + break; + } + + // Copy. Account for 4 byte pad + cpy_size = ATCA_BLOCK_SIZE - ATCA_PUB_KEY_PAD; + read_index = ATCA_PUB_KEY_PAD; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + cpy_index += cpy_size; + + // Read the next block + block = 1; + if ((status = calib_read_zone_ext(device, ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) + { + ATCA_TRACE(status, "calib_read_zone - failed"); + break; + } + + // Copy. First four bytes + cpy_size = ATCA_PUB_KEY_PAD; + read_index = 0; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + cpy_index += cpy_size; + // Copy. Skip four bytes + read_index = ATCA_PUB_KEY_PAD + ATCA_PUB_KEY_PAD; + cpy_size = ATCA_BLOCK_SIZE - read_index; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + cpy_index += cpy_size; + + // Read the next block + block = 2; + if ((status = calib_read_zone_ext(device, ATCA_ZONE_DATA, slot, block, offset, read_buf, ATCA_BLOCK_SIZE)) != ATCA_SUCCESS) { - *same_config = true; + ATCA_TRACE(status, "calib_read_zone - failed"); + break; } + + // Copy. The remaining 8 bytes + cpy_size = ATCA_PUB_KEY_PAD + ATCA_PUB_KEY_PAD; + read_index = 0; + memcpy(&public_key[cpy_index], &read_buf[read_index], cpy_size); + } + while (0); return status; } - #endif diff --git a/lib/calib/calib_secureboot.c b/lib/calib/calib_secureboot.c index 0908cedf8..9673233ff 100644 --- a/lib/calib/calib_secureboot.c +++ b/lib/calib/calib_secureboot.c @@ -32,8 +32,12 @@ */ #include "cryptoauthlib.h" + +#if CALIB_SECUREBOOT_MAC_EN #include "host/atca_host.h" +#endif +#if CALIB_SECUREBOOT_EN /** \brief Executes Secure Boot command, which provides support for secure * boot of an external MCU or MPU. * @@ -93,7 +97,9 @@ ATCA_STATUS calib_secureboot(ATCADevice device, uint8_t mode, uint16_t param2, c return status; } +#endif /* CALIB_SECUREBOOT_EN */ +#if CALIB_SECUREBOOT_MAC_EN /** \brief Executes Secure Boot command with encrypted digest and validated * MAC response using the IO protection key. * @@ -215,3 +221,4 @@ ATCA_STATUS calib_secureboot_mac(ATCADevice device, uint8_t mode, const uint8_t* return status; } +#endif /* CALIB_SECUREBOOT_MAC_EN */ diff --git a/lib/calib/calib_selftest.c b/lib/calib/calib_selftest.c index d49ab2f51..c9b806768 100644 --- a/lib/calib/calib_selftest.c +++ b/lib/calib/calib_selftest.c @@ -33,6 +33,7 @@ #include "cryptoauthlib.h" +#if CALIB_SELFTEST_EN /** \brief Executes the SelfTest command, which performs a test of one or more * of the cryptographic engines within the ATECC608 chip. * @@ -105,3 +106,4 @@ ATCA_STATUS calib_selftest(ATCADevice device, uint8_t mode, uint16_t param2, uin return status; } +#endif /* CALIB_SELFTEST_EN */ diff --git a/lib/calib/calib_sha.c b/lib/calib/calib_sha.c index ff54aa673..698d8cfca 100644 --- a/lib/calib/calib_sha.c +++ b/lib/calib/calib_sha.c @@ -34,6 +34,8 @@ #include "cryptoauthlib.h" +#if CALIB_SHA_EN + typedef struct { uint32_t total_msg_size; //!< Total number of message bytes processed @@ -72,19 +74,13 @@ ATCA_STATUS calib_sha_base(ATCADevice device, uint8_t mode, uint16_t length, con ATCA_STATUS status = ATCA_GEN_FAIL; uint8_t cmd_mode = (mode & SHA_MODE_MASK); - if (device == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } - if (cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START && - cmd_mode != SHA_MODE_ECC204_HMAC_START && length > 0 && message == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); // message data indicated, but nothing provided - } - if (data_out != NULL && data_out_size == NULL) - { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); - } + ATCA_CHECK_INVALID_MSG(!device, ATCA_BAD_PARAM, "NULL pointer received"); + + ATCA_CHECK_INVALID_MSG((cmd_mode != SHA_MODE_SHA256_PUBLIC && cmd_mode != SHA_MODE_HMAC_START && + cmd_mode != SHA_MODE_ECC204_HMAC_START && length > 0 && message == NULL), + ATCA_BAD_PARAM, "NULL pointer received");// message data indicated, but nothing provided + + ATCA_CHECK_INVALID_MSG((data_out && !data_out_size), ATCA_BAD_PARAM, "NULL pointer received"); do { @@ -165,6 +161,7 @@ ATCA_STATUS calib_sha_end(ATCADevice device, uint8_t *digest, uint16_t length, c return calib_sha_base(device, SHA_MODE_SHA256_END, length, message, digest, &digest_size); } +#endif /* CALIB_SHA_EN */ /** \brief Executes SHA command to read the SHA-256 context back. Only for * ATECC608 with SHA-256 contexts. HMAC not supported. @@ -177,6 +174,7 @@ ATCA_STATUS calib_sha_end(ATCADevice device, uint8_t *digest, uint16_t length, c * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if CALIB_SHA_CONTEXT_EN ATCA_STATUS calib_sha_read_context(ATCADevice device, uint8_t* context, uint16_t* context_size) { return calib_sha_base(device, SHA_MODE_READ_CONTEXT, 0, NULL, context, context_size); @@ -195,7 +193,9 @@ ATCA_STATUS calib_sha_write_context(ATCADevice device, const uint8_t* context, u { return calib_sha_base(device, SHA_MODE_WRITE_CONTEXT, context_size, context, NULL, NULL); } +#endif /* CALIB_SHA_CONTEXT_EN */ +#if CALIB_SHA_EN /** \brief Use the SHA command to compute a SHA-256 digest. * * \param[in] device Device context pointer @@ -289,17 +289,18 @@ ATCA_STATUS calib_hw_sha2_256_update(ATCADevice device, atca_sha256_ctx_t* ctx, ATCA_STATUS calib_hw_sha2_256_finish(ATCADevice device, atca_sha256_ctx_t* ctx, uint8_t* digest) { ATCA_STATUS status = ATCA_SUCCESS; - uint32_t msg_size_bits; - uint32_t pad_zero_count; - uint16_t digest_size; if (device == NULL) { return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } +#ifdef ATCA_ATSHA204A_SUPPORT if (device->mIface.mIfaceCFG->devtype == ATSHA204A) { + uint32_t msg_size_bits; + uint32_t pad_zero_count; + uint16_t digest_size; // ATSHA204A only implements the raw 64-byte block operation, but // doesn't add in the final footer information. So we do that manually // here. @@ -341,6 +342,7 @@ ATCA_STATUS calib_hw_sha2_256_finish(ATCADevice device, atca_sha256_ctx_t* ctx, } } else +#endif { if (ATCA_SUCCESS != (status = calib_sha_end(device, digest, (uint16_t)ctx->block_size, ctx->block))) { @@ -382,7 +384,9 @@ ATCA_STATUS calib_hw_sha2_256(ATCADevice device, const uint8_t * data, size_t da return ATCA_SUCCESS; } +#endif /* CALIB_SHA_EN */ +#if CALIB_SHA_HMAC_EN /** \brief Executes SHA command to start an HMAC/SHA-256 operation * * \param[in] device Device context pointer @@ -542,3 +546,4 @@ ATCA_STATUS calib_sha_hmac(ATCADevice device, const uint8_t * data, size_t data_ return ATCA_SUCCESS; } +#endif /* CALIB_SHA_HMAC_EN */ diff --git a/lib/calib/calib_sign.c b/lib/calib/calib_sign.c index 940abf2a6..32b1395d6 100644 --- a/lib/calib/calib_sign.c +++ b/lib/calib/calib_sign.c @@ -34,6 +34,7 @@ #include "cryptoauthlib.h" +#if CALIB_SIGN_EN /** \brief Executes the Sign command, which generates a signature using the * ECDSA algorithm. * @@ -116,13 +117,15 @@ ATCA_STATUS calib_sign(ATCADevice device, uint16_t key_id, const uint8_t *msg, u do { +#if CALIB_RANDOM_EN // Make sure RNG has updated its seed if ((status = calib_random(device, NULL)) != ATCA_SUCCESS) { ATCA_TRACE(status, "calib_random - failed"); break; } - +#endif +#ifdef ATCA_ATECC608_SUPPORT // Load message into device if (ATECC608 == device->mIface.mIfaceCFG->devtype) { @@ -130,6 +133,7 @@ ATCA_STATUS calib_sign(ATCADevice device, uint16_t key_id, const uint8_t *msg, u nonce_target = NONCE_MODE_TARGET_MSGDIGBUF; sign_source = SIGN_MODE_SOURCE_MSGDIGBUF; } +#endif if ((status = calib_nonce_load(device, nonce_target, msg, 32)) != ATCA_SUCCESS) { ATCA_TRACE(status, "calib_nonce_load - failed"); @@ -148,6 +152,23 @@ ATCA_STATUS calib_sign(ATCADevice device, uint16_t key_id, const uint8_t *msg, u return status; } +ATCA_STATUS calib_sign_ext(ATCADevice device, uint16_t key_id, const uint8_t *msg, uint8_t *signature) +{ +#if CALIB_ECC204_EN + if (ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_sign(device, key_id, msg, signature); + } + else +#endif + { + return calib_sign(device, key_id, msg, signature); + } +} + +#endif + +#if CALIB_SIGN_INTERNAL_EN /** \brief Executes Sign command to sign an internally generated message. * * \param[in] device Device context pointer @@ -193,7 +214,9 @@ ATCA_STATUS calib_sign_internal(ATCADevice device, uint16_t key_id, bool is_inva return status; } +#endif /* CALIB_SIGN_MODE_ENCODING */ +#if CALIB_SIGN_ECC204_EN /** \brief Execute sign command to sign the 32 bytes message digest using private key * mentioned in slot. * @@ -250,3 +273,4 @@ ATCA_STATUS calib_ecc204_sign(ATCADevice device, uint16_t key_id, const uint8_t* return status; } +#endif diff --git a/lib/calib/calib_updateextra.c b/lib/calib/calib_updateextra.c index 7f55bea2f..95fbe1ff5 100644 --- a/lib/calib/calib_updateextra.c +++ b/lib/calib/calib_updateextra.c @@ -34,6 +34,7 @@ #include "cryptoauthlib.h" +#if CALIB_UPDATEEXTRA_EN /** \brief Executes UpdateExtra command to update the values of the two * extra bytes within the Configuration zone (bytes 84 and 85). * @@ -82,3 +83,4 @@ ATCA_STATUS calib_updateextra(ATCADevice device, uint8_t mode, uint16_t new_valu return status; } +#endif /* CALIB_UPDATEEXTRA */ diff --git a/lib/calib/calib_verify.c b/lib/calib/calib_verify.c index b810a48dd..6e7c0e216 100644 --- a/lib/calib/calib_verify.c +++ b/lib/calib/calib_verify.c @@ -33,8 +33,10 @@ */ #include "cryptoauthlib.h" + #include "host/atca_host.h" +#if CALIB_VERIFY_EN /** \brief Executes the Verify command, which takes an ECDSA [R,S] signature * and verifies that it is correctly generated from a given message and * public key. In all cases, the signature is an input to the command. @@ -123,7 +125,9 @@ ATCA_STATUS calib_verify(ATCADevice device, uint8_t mode, uint16_t key_id, const return status; } +#endif /* CALIB_VERIFY */ +#if CALIB_VERIFY_MAC_EN /** \brief Executes the Verify command with verification MAC for the External * or Stored Verify modes.. This function is only available on the * ATECC608. @@ -213,6 +217,59 @@ static ATCA_STATUS calib_verify_extern_stored_mac(ATCADevice device, uint8_t mod return status; } +/** \brief Executes the Verify command with verification MAC, which verifies a + * signature (ECDSA verify operation) with all components (message, + * signature, and public key) supplied. This function is only available + * on the ATECC608. + * + * \param[in] device Device context pointer + * \param[in] message 32 byte message to be verified. Typically + * the SHA256 hash of the full message. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] public_key The public key to be used for verification. X and + * Y integers in big-endian format. 64 bytes for + * P256 curve. + * \param[in] num_in System nonce (32 byte) used for the verification + * MAC. + * \param[in] io_key IO protection key for verifying the validation MAC. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS calib_verify_extern_mac(ATCADevice device, const uint8_t *message, const uint8_t* signature, const uint8_t* public_key, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified) +{ + return calib_verify_extern_stored_mac(device, VERIFY_MODE_EXTERNAL, VERIFY_KEY_P256, message, signature, public_key, num_in, io_key, is_verified); +} + +/** \brief Executes the Verify command with verification MAC, which verifies a + * signature (ECDSA verify operation) with a public key stored in the + * device. This function is only available on the ATECC608. + * + * \param[in] device Device context pointer + * \param[in] message 32 byte message to be verified. Typically + * the SHA256 hash of the full message. + * \param[in] signature Signature to be verified. R and S integers in + * big-endian format. 64 bytes for P256 curve. + * \param[in] key_id Slot containing the public key to be used in the + * verification. + * \param[in] num_in System nonce (32 byte) used for the verification + * MAC. + * \param[in] io_key IO protection key for verifying the validation MAC. + * \param[out] is_verified Boolean whether or not the message, signature, + * public key verified. + * + * \return ATCA_SUCCESS on verification success or failure, because the + * command still completed successfully. + */ +ATCA_STATUS calib_verify_stored_mac(ATCADevice device, const uint8_t *message, const uint8_t *signature, uint16_t key_id, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified) +{ + return calib_verify_extern_stored_mac(device, VERIFY_MODE_STORED, key_id, message, signature, NULL, num_in, io_key, is_verified); +} +#endif /* CALIB_VERIFY_MAC_EN */ + /** \brief Executes the Verify command, which verifies a signature (ECDSA * verify operation) with all components (message, signature, and * public key) supplied. The message to be signed will be loaded into @@ -233,6 +290,8 @@ static ATCA_STATUS calib_verify_extern_stored_mac(ATCADevice device, uint8_t mod * \return ATCA_SUCCESS on verification success or failure, because the * command still completed successfully. */ + +#if CALIB_VERIFY_EXTERN_EN ATCA_STATUS calib_verify_extern(ATCADevice device, const uint8_t *message, const uint8_t *signature, const uint8_t *public_key, bool *is_verified) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -274,34 +333,9 @@ ATCA_STATUS calib_verify_extern(ATCADevice device, const uint8_t *message, const return status; } +#endif /* CALIB_VERIFY_EXTERN */ -/** \brief Executes the Verify command with verification MAC, which verifies a - * signature (ECDSA verify operation) with all components (message, - * signature, and public key) supplied. This function is only available - * on the ATECC608. - * - * \param[in] device Device context pointer - * \param[in] message 32 byte message to be verified. Typically - * the SHA256 hash of the full message. - * \param[in] signature Signature to be verified. R and S integers in - * big-endian format. 64 bytes for P256 curve. - * \param[in] public_key The public key to be used for verification. X and - * Y integers in big-endian format. 64 bytes for - * P256 curve. - * \param[in] num_in System nonce (32 byte) used for the verification - * MAC. - * \param[in] io_key IO protection key for verifying the validation MAC. - * \param[out] is_verified Boolean whether or not the message, signature, - * public key verified. - * - * \return ATCA_SUCCESS on verification success or failure, because the - * command still completed successfully. - */ -ATCA_STATUS calib_verify_extern_mac(ATCADevice device, const uint8_t *message, const uint8_t* signature, const uint8_t* public_key, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified) -{ - return calib_verify_extern_stored_mac(device, VERIFY_MODE_EXTERNAL, VERIFY_KEY_P256, message, signature, public_key, num_in, io_key, is_verified); -} - +#if CALIB_VERIFY_STORED_EN /** \brief Executes the Verify command, which verifies a signature (ECDSA * verify operation) with a public key stored in the device. The * message to be signed will be loaded into the Message Digest Buffer @@ -361,31 +395,53 @@ ATCA_STATUS calib_verify_stored(ATCADevice device, const uint8_t *message, const return status; } -/** \brief Executes the Verify command with verification MAC, which verifies a - * signature (ECDSA verify operation) with a public key stored in the - * device. This function is only available on the ATECC608. +/** \brief Executes the Verify command, which verifies a signature (ECDSA + * verify operation) with a public key stored in the device. + * keyConfig.reqrandom bit should be set and the message to be signed + * should be already loaded into TempKey for all devices. + * + * Please refer to TEST(atca_cmd_basic_test, verify_stored_on_reqrandom_set) in + * atca_tests_verify.c for proper use of this api * * \param[in] device Device context pointer - * \param[in] message 32 byte message to be verified. Typically - * the SHA256 hash of the full message. * \param[in] signature Signature to be verified. R and S integers in * big-endian format. 64 bytes for P256 curve. * \param[in] key_id Slot containing the public key to be used in the * verification. - * \param[in] num_in System nonce (32 byte) used for the verification - * MAC. - * \param[in] io_key IO protection key for verifying the validation MAC. * \param[out] is_verified Boolean whether or not the message, signature, * public key verified. * * \return ATCA_SUCCESS on verification success or failure, because the * command still completed successfully. */ -ATCA_STATUS calib_verify_stored_mac(ATCADevice device, const uint8_t *message, const uint8_t *signature, uint16_t key_id, const uint8_t* num_in, const uint8_t* io_key, bool* is_verified) +ATCA_STATUS calib_verify_stored_with_tempkey(ATCADevice device, const uint8_t* signature, uint16_t key_id, bool* is_verified) { - return calib_verify_extern_stored_mac(device, VERIFY_MODE_STORED, key_id, message, signature, NULL, num_in, io_key, is_verified); + ATCA_STATUS status = ATCA_GEN_FAIL; + uint8_t verify_source = VERIFY_MODE_SOURCE_TEMPKEY; + + if ((device == NULL) || (is_verified == NULL) || (signature == NULL)) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + + *is_verified = false; + + do + { + status = calib_verify(device, VERIFY_MODE_STORED | verify_source, key_id, signature, NULL, NULL, NULL); + + *is_verified = (status == ATCA_SUCCESS); + if (status == ATCA_CHECKMAC_VERIFY_FAILED) + { + status = ATCA_SUCCESS; // Verify failed, but command succeeded + } + } while (0); + + return status; } +#endif /* CALIB_VERIFY_STORED */ +#if CALIB_VERIFY_VALIDATE_EN /** \brief Executes the Verify command in Validate mode to validate a public * key stored in a slot. * @@ -461,3 +517,4 @@ ATCA_STATUS calib_verify_invalidate(ATCADevice device, uint16_t key_id, const ui return status; } +#endif /* CALIB_VERIFY_VALIDATE_EN */ diff --git a/lib/calib/calib_write.c b/lib/calib/calib_write.c index d07b686cf..82ac2e35d 100644 --- a/lib/calib/calib_write.c +++ b/lib/calib/calib_write.c @@ -35,8 +35,10 @@ */ #include "cryptoauthlib.h" + #include "host/atca_host.h" +#if CALIB_WRITE_EN /** * \brief Executes the Write command, which writes either one four byte word or * a 32-byte block to one of the EEPROM zones on the device. Depending @@ -105,6 +107,20 @@ ATCA_STATUS calib_write(ATCADevice device, uint8_t zone, uint16_t address, const return status; } +ATCA_STATUS calib_write_ext(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac) +{ +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_write(device, zone, address, value, mac); + } + else +#endif + { + return calib_write_ext(device, zone, address, value, mac); + } +} + /** \brief Executes the Write command, which writes either 4 or 32 bytes of * data into a device zone. * @@ -158,8 +174,9 @@ ATCA_STATUS calib_write_zone(ATCADevice device, uint8_t zone, uint16_t slot, uin return status; } +#endif /* CALIB_WRITE_EN */ - +#if CALIB_WRITE_ENC_EN /** \brief Executes the Write command, which performs an encrypted write of * a 32 byte block into given slot. * @@ -301,6 +318,7 @@ ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, c return status; } +#endif /* CALIB_WRITE_ENC_EN */ /** \brief Executes the Write command, which writes the configuration zone. * @@ -318,6 +336,8 @@ ATCA_STATUS calib_write_enc(ATCADevice device, uint16_t key_id, uint8_t block, c * * \returns ATCA_SUCCESS on success, otherwise an error code. */ + +#if CALIB_WRITE_EN ATCA_STATUS calib_write_config_zone(ATCADevice device, const uint8_t* config_data) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -362,50 +382,18 @@ ATCA_STATUS calib_write_config_zone(ATCADevice device, const uint8_t* config_dat return status; } -/** \brief Uses the write command to write a public key to a slot in the - * proper format. - * - * \param[in] device Device context pointer - * \param[in] slot Slot number to write. Only slots 8 to 15 are large - * enough to store a public key. - * \param[in] public_key Public key to write into the slot specified. X and Y - * integers in big-endian format. 64 bytes for P256 - * curve. - * - * \return ATCA_SUCCESS on success, otherwise an error code. - */ -ATCA_STATUS calib_write_pubkey(ATCADevice device, uint16_t slot, const uint8_t *public_key) +ATCA_STATUS calib_write_config_zone_ext(ATCADevice device, const uint8_t* config_data) { - ATCA_STATUS status = ATCA_SUCCESS; - uint8_t public_key_formatted[ATCA_BLOCK_SIZE * 3]; - uint8_t block; - - // Check the pointers - if (public_key == NULL) +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + return calib_ecc204_write_config_zone(device, config_data); } - - // The 64 byte P256 public key gets written to a 72 byte slot in the following pattern - // | Block 1 | Block 2 | Block 3 | - // | Pad: 4 Bytes | PubKey[0:27] | PubKey[28:31] | Pad: 4 Bytes | PubKey[32:55] | PubKey[56:63] | - - memset(public_key_formatted, 0, sizeof(public_key_formatted)); - memcpy(&public_key_formatted[4], &public_key[0], 32); // Move X to padded position - memcpy(&public_key_formatted[40], &public_key[32], 32); // Move Y to padded position - - // Using this instead of calib_write_zone_bytes, as that function doesn't work when - // the data zone is unlocked - for (block = 0; block < 3; block++) + else +#endif { - if (ATCA_SUCCESS != (status = calib_write_zone(device, ATCA_ZONE_DATA, slot, block, 0, &public_key_formatted[ATCA_BLOCK_SIZE * block], ATCA_BLOCK_SIZE))) - { - ATCA_TRACE(status, "calib_write_zone - failed"); - break; - } + return calib_write_config_zone(device, config_data); } - - return status; } /** \brief Executes the Write command, which writes data into the @@ -512,6 +500,20 @@ ATCA_STATUS calib_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slo return status; } +ATCA_STATUS calib_write_bytes_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, size_t offset_bytes, const uint8_t *data, size_t length) +{ +#if CALIB_ECC204_EN + if(ECC204 == atcab_get_device_type_ext(device)) + { + return calib_ecc204_write_bytes_zone(device, zone, slot, offset_bytes, data, length); + } + else +#endif + { + return calib_write_bytes_zone(device, zone, slot, offset_bytes, data, length); + } +} + /** \brief Initialize one of the monotonic counters in device with a specific * value. * @@ -556,8 +558,8 @@ ATCA_STATUS calib_write_config_counter(ATCADevice device, uint16_t counter_id, u return status; } +#endif /* CALIB_WRITE_EN */ -#if defined(ATCA_ECC204_SUPPORT) /** \brief Execute write command to write either 16 byte or 32 byte to one of the EEPROM zones * on the ECC204 device. * @@ -571,11 +573,13 @@ ATCA_STATUS calib_write_config_counter(ATCADevice device, uint16_t counter_id, u * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if CALIB_WRITE_ECC204_EN ATCA_STATUS calib_ecc204_write(ATCADevice device, uint8_t zone, uint16_t address, const uint8_t *value, const uint8_t *mac) { ATCA_STATUS status = ATCA_SUCCESS; ATCAPacket packet; + uint8_t write_zone = (zone == ATCA_ZONE_CONFIG) ? ATCA_ECC204_ZONE_CONFIG : ATCA_ECC204_ZONE_DATA; if ((NULL == device) && (NULL == value)) { @@ -584,14 +588,14 @@ ATCA_STATUS calib_ecc204_write(ATCADevice device, uint8_t zone, uint16_t address if (ATCA_SUCCESS == status) { - packet.param1 = zone; + packet.param1 = write_zone; packet.param2 = address; - if (ATCA_ECC204_ZONE_CONFIG == zone) + if (ATCA_ECC204_ZONE_CONFIG == write_zone) { memcpy(packet.data, value, 16); } - else if (ATCA_ECC204_ZONE_DATA == zone) + else if (ATCA_ECC204_ZONE_DATA == write_zone) { memcpy(packet.data, value, ATCA_BLOCK_SIZE); } @@ -602,12 +606,12 @@ ATCA_STATUS calib_ecc204_write(ATCADevice device, uint8_t zone, uint16_t address if (ATCA_SUCCESS == status) { - if (mac && (ATCA_ECC204_ZONE_DATA == zone)) + if (mac && (ATCA_ECC204_ZONE_DATA == write_zone)) { memcpy(&packet.data[ATCA_BLOCK_SIZE], mac, MAC_SIZE); } - (void)atWrite(atcab_get_device_type_ext(device), &packet, mac && (ATCA_ECC204_ZONE_DATA == zone)); + (void)atWrite(atcab_get_device_type_ext(device), &packet, mac && (ATCA_ECC204_ZONE_DATA == write_zone)); } } @@ -641,7 +645,6 @@ ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t sl { ATCA_STATUS status = ATCA_SUCCESS; uint16_t addr; - uint8_t write_zone = (zone == ATCA_ZONE_CONFIG) ? ATCA_ECC204_ZONE_CONFIG : ATCA_ECC204_ZONE_DATA; ((void)offset); @@ -649,22 +652,22 @@ ATCA_STATUS calib_ecc204_write_zone(ATCADevice device, uint8_t zone, uint16_t sl { status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer encountered"); } - else if (((ATCA_ECC204_ZONE_CONFIG == write_zone) && (16 != len)) || - ((ATCA_ECC204_ZONE_DATA == write_zone) && (ATCA_BLOCK_SIZE != len))) + else if (((ATCA_ZONE_CONFIG == zone) && (16 != len)) || + ((ATCA_ZONE_DATA == zone) && (ATCA_BLOCK_SIZE != len))) { status = ATCA_TRACE(ATCA_BAD_PARAM, "Invalid length received"); } if (ATCA_SUCCESS == status) { - if (ATCA_SUCCESS != (status = calib_ecc204_get_addr(write_zone, slot, block, 0, &addr))) + if (ATCA_SUCCESS != (status = calib_ecc204_get_addr(zone, slot, block, 0, &addr))) { ATCA_TRACE(status, "calib_ecc204_get_addr - failed"); } if (ATCA_SUCCESS == status) { - status = calib_ecc204_write(device, write_zone, addr, data, NULL); + status = calib_ecc204_write(device, zone, addr, data, NULL); } } @@ -692,7 +695,7 @@ ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, const uint8_t* con { while (slot <= 3) { - if (ATCA_SUCCESS != (status = calib_ecc204_write_zone(device, ATCA_ECC204_ZONE_CONFIG, slot, + if (ATCA_SUCCESS != (status = calib_ecc204_write_zone(device, ATCA_ZONE_CONFIG, slot, 0, 0, &config_data[16 * slot], 16))) { ATCA_TRACE(status, "calib_ecc204_write_zone - failed"); @@ -703,7 +706,9 @@ ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, const uint8_t* con return status; } +#endif /* CALIB_WRITE_EN */ +#if CALIB_WRITE_ENC_EN && defined(ATCA_ECC204_SUPPORT) /** \brief Executes write command, performs an encrypted write of a 32 byte block into given slot. * * \param[in] device Device context pointer @@ -715,17 +720,9 @@ ATCA_STATUS calib_ecc204_write_config_zone(ATCADevice device, const uint8_t* con * * \return ATCA_SUCCESS on success, otherwise an error code */ -#if defined(ATCA_USE_CONSTANT_HOST_NONCE) -ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* data, uint8_t* transport_key, - uint8_t transport_key_id) -{ - uint8_t num_in[NONCE_NUMIN_SIZE] = { 0 }; - -#else ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* data, uint8_t* transport_key, uint8_t transport_key_id, uint8_t num_in[NONCE_NUMIN_SIZE]) { -#endif ATCA_STATUS status = ATCA_SUCCESS; atca_nonce_in_out_t nonce_params; atca_write_mac_in_out_t write_mac_param; @@ -790,7 +787,7 @@ ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* da break; } - if (ATCA_SUCCESS != (status = calib_ecc204_get_addr(ATCA_ECC204_ZONE_DATA, slot, 0, 0, &addr))) + if (ATCA_SUCCESS != (status = calib_ecc204_get_addr(ATCA_ZONE_DATA, slot, 0, 0, &addr))) { ATCA_TRACE(status, "Calculate slot address failed"); break; @@ -815,12 +812,13 @@ ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* da break; } - status = calib_ecc204_write(device, write_mac_param.zone, write_mac_param.key_id, write_mac_param.encrypted_data, write_mac_param.auth_mac); + status = calib_ecc204_write(device, ATCA_ZONE_DATA, write_mac_param.key_id, write_mac_param.encrypted_data, write_mac_param.auth_mac); } while (0); return status; } +#endif /* CALIB_WRITE_ENC_EN */ /** \brief Use Write command to write bytes * @@ -836,6 +834,7 @@ ATCA_STATUS calib_ecc204_write_enc(ATCADevice device, uint16_t slot, uint8_t* da * * \return ATCA_SUCCESS on success, otheriwse an error code */ +#if CALIB_WRITE_ECC204_EN ATCA_STATUS calib_ecc204_write_bytes_zone(ATCADevice device, uint8_t zone, uint16_t slot, size_t block, const uint8_t *data, size_t length) { @@ -881,5 +880,73 @@ ATCA_STATUS calib_ecc204_write_bytes_zone(ATCADevice device, uint8_t zone, uint1 return status; } +#endif /* CALIB_WRITE_ECC204_EN */ + +#if CALIB_WRITE_EN || CALIB_WRITE_ECC204_EN +ATCA_STATUS calib_write_zone_ext(ATCADevice device, uint8_t zone, uint16_t slot, uint8_t block, uint8_t offset, const uint8_t *data, uint8_t len) +{ +#if CALIB_ECC204_EN + ATCADeviceType devtype = atcab_get_device_type_ext(device); + ATCA_STATUS status = ATCA_BAD_PARAM; + if(ECC204 == devtype) + { + status = calib_ecc204_write_zone(device, zone, slot, block, offset, data, len); + } +#if CALIB_WRITE_EN + else if (atcab_is_ca_device(devtype)) + { + status = calib_write_zone(device, zone, slot, block, offset, data, len); + } +#endif /* CALIB_WRITE_EN */ + return status; +#else + return calib_write_zone(device, zone, slot, block, offset, data, len); +#endif /* CALIB_ECC204_EN */ +} + +/** \brief Uses the write command to write a public key to a slot in the + * proper format. + * + * \param[in] device Device context pointer + * \param[in] slot Slot number to write. Only slots 8 to 15 are large + * enough to store a public key. + * \param[in] public_key Public key to write into the slot specified. X and Y + * integers in big-endian format. 64 bytes for P256 + * curve. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS calib_write_pubkey(ATCADevice device, uint16_t slot, const uint8_t *public_key) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t public_key_formatted[ATCA_BLOCK_SIZE * 3]; + uint8_t block; + + // Check the pointers + if (public_key == NULL) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + + // The 64 byte P256 public key gets written to a 72 byte slot in the following pattern + // | Block 1 | Block 2 | Block 3 | + // | Pad: 4 Bytes | PubKey[0:27] | PubKey[28:31] | Pad: 4 Bytes | PubKey[32:55] | PubKey[56:63] | + + memset(public_key_formatted, 0, sizeof(public_key_formatted)); + memcpy(&public_key_formatted[4], &public_key[0], 32); // Move X to padded position + memcpy(&public_key_formatted[40], &public_key[32], 32); // Move Y to padded position + // Using this instead of calib_write_zone_bytes, as that function doesn't work when + // the data zone is unlocked + for (block = 0; block < 3; block++) + { + if (ATCA_SUCCESS != (status = calib_write_zone_ext(device, ATCA_ZONE_DATA, slot, block, 0, &public_key_formatted[ATCA_BLOCK_SIZE * block], ATCA_BLOCK_SIZE))) + { + ATCA_TRACE(status, "calib_write_zone - failed"); + break; + } + } + + return status; +} #endif diff --git a/lib/cmake/pkcs11.cmake b/lib/cmake/pkcs11.cmake index d317bbb63..dd3304e19 100644 --- a/lib/cmake/pkcs11.cmake +++ b/lib/cmake/pkcs11.cmake @@ -1,32 +1,28 @@ # Helper CMake file for PKCS11 extension to the library # PKCS11 Configuration Options - See pkcs11_config.h.in -set(PKCS11_DEBUG_ENABLE OFF CACHE BOOL "Enable PKCS#11 Debugging Messages") -set(PKCS11_USE_STATIC_MEMORY ${ATCA_NO_HEAP} CACHE BOOL "Use Static Memory Allocation") -set(PKCS11_USE_STATIC_CONFIG OFF CACHE BOOL "Use a compiled configuration rather than loading from a filestore") +option(PKCS11_DEBUG_ENABLE "Enable debug of PKCS11 implementation - NOT SECURE" OFF) +option(PKCS11_USE_STATIC_MEMORY "Use statically allocated library context" ${ATCA_NO_HEAP}) +option(PKCS11_USE_STATIC_CONFIG "Use a compiled configuration rather than loading from a filestore - only intended for embedded devices" OFF) +option(PKCS11_EXTERNAL_FUNCTION_LIST "Use an alternative function list - only for embedded devices" OFF) +option(PKCS11_TESTING_ENABLE "Enable testing functions that shouldn't be part of production builds" OFF) +option(PKCS11_PIN_KDF_ALWAYS "Always a kdf function to convert a provide pin to a stored key" OFF) +option(PKCS11_PIN_PBKDF2_EN "Use the PBKDF2 algorithm to convert pin to stored key value" OFF) +option(PKCS11_LOCK_PIN_SLOT "Define to lock the PIN slot after writing" OFF) +option(PKCS11_TOKEN_INIT_SUPPORT "Enable device initialization using pkcs11 token initialization - UNSAFE" OFF) +option(PKCS11_MONOTONIC_ENABLE "Map device counters to the pkcs11 montotonic counter class" OFF) +option(PKCS11_AUTO_ID_ENABLE "Generate CKA_ID values based on standards" ON) + set(PKCS11_MAX_SLOTS_ALLOWED 1 CACHE STRING "Maximum number of slots allowed in the system") set(PKCS11_MAX_SESSIONS_ALLOWED 10 CACHE STRING "Maximum number of total sessions allowed in the system") set(PKCS11_MAX_OBJECTS_ALLOWED 16 CACHE STRING "Maximum number of cryptographic objects allowed to be cached") set(PKCS11_MAX_LABEL_SIZE 30 CACHE STRING "Maximum label size in characters") -set(PKCS11_LOCK_PIN_SLOT OFF CACHE BOOL "Define to lock the PIN slot after writing") -set(PKCS11_PIN_KDF_ALWAYS OFF CACHE BOOL "Define to always convert PIN using KDF") -set(PKCS11_PIN_PBKDF2_EN OFF CACHE BOOL "Define to use PBKDF2 for PIN KDF") +set(PKCS11_MAX_CONFIG_ALLOWED 7 CACHE STRING "Maximum depth to configuration options") set(PKCS11_PIN_PBKDF2_ITERATIONS 2 CACHE STRING "Define how many iterations PBKDF2 will use for PIN KDF") set(PKCS11_SEARCH_CACHE_SIZE 250 CACHE STRING "Static Search Attribute Cache in bytes") -set(PKCS11_TOKEN_INIT_SUPPORT OFF CACHE BOOL "Support for configuring a blank or new device") -set(PKCS11_MONOTONIC_ENABLE OFF CACHE BOOL "Include the monotonic hardware feature as an object") -set(PKCS11_AUTO_ID_ENABLE ON CACHE BOOL "Generate CKA_ID values based on standards") file(GLOB PKCS11_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "pkcs11/*.c") file(GLOB PKCS11_INC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "pkcs11/*.h") configure_file(pkcs11/pkcs11_config.h.in ${CMAKE_CURRENT_BINARY_DIR}/pkcs11_config.h @ONLY) set(PKCS11_INC ${PKCS11_INC} ${CMAKE_CURRENT_BINARY_DIR}/pkcs11_config.h) - -if(ATCA_TNGTLS_SUPPORT OR ATCA_TNGLORA_SUPPORT OR ATCA_TFLEX_SUPPORT) -SET(TNG_SRC ${TNG_SRC} ../app/pkcs11/trust_pkcs11_config.c) -endif() - -if(${CMAKE_VERSION} VERSION_GREATER "3.8.0") -source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${PKCS11_SRC}) -endif() diff --git a/lib/crypto/atca_crypto_hw_aes.h b/lib/crypto/atca_crypto_hw_aes.h index 99f9d525a..650888b11 100644 --- a/lib/crypto/atca_crypto_hw_aes.h +++ b/lib/crypto/atca_crypto_hw_aes.h @@ -29,16 +29,39 @@ #define ATCA_CRYPTO_HW_AES_H #include "cryptoauthlib.h" +#include "crypto_config_check.h" +#ifdef __cplusplus +extern "C" { +#endif + +#if ATCAB_AES_CBC_ENCRYPT_EN || ATCAB_AES_CBC_DECRYPT_EN typedef struct atca_aes_cbc_ctx { ATCADevice device; //!< Device Context Pointer uint16_t key_id; //!< Key location. Can either be a slot number or ATCA_TEMPKEY_KEYID for TempKey. uint8_t key_block; //!< Index of the 16-byte block to use within the key location for the actual key. uint8_t ciphertext[ATCA_AES128_BLOCK_SIZE]; //!< Ciphertext from last operation. +#ifdef ATCAB_AES_CBC_UPDATE_EN + uint8_t block_size; //!< Number of bytes in unprocessed block. + uint8_t block[ATCA_AES128_BLOCK_SIZE]; //!< Unprocessed message storage. +#endif } atca_aes_cbc_ctx_t; +ATCA_STATUS atcab_aes_cbc_init_ext(ATCADevice device, atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv); +ATCA_STATUS atcab_aes_cbc_init(atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t key_block, const uint8_t* iv); +ATCA_STATUS atcab_aes_cbc_encrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext); +ATCA_STATUS atcab_aes_cbc_decrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext); +#ifdef ATCAB_AES_CBC_UPDATE_EN +ATCA_STATUS atcab_aes_cbc_encrypt_update(atca_aes_cbc_ctx_t* ctx, uint8_t* plaintext, size_t plaintext_len, uint8_t* ciphertext, size_t * ciphertext_len); +ATCA_STATUS atcab_aes_cbc_encrypt_finish(atca_aes_cbc_ctx_t* ctx, uint8_t* ciphertext, size_t * ciphertext_len, uint8_t padding); +ATCA_STATUS atcab_aes_cbc_decrypt_update(atca_aes_cbc_ctx_t* ctx, const uint8_t* ciphertext, size_t ciphertext_len, uint8_t* plaintext, size_t * plaintext_len); +ATCA_STATUS atcab_aes_cbc_decrypt_finish(atca_aes_cbc_ctx_t* ctx, uint8_t* plaintext, size_t * plaintext_len, uint8_t padding); +#endif + +#endif +#if ATCAB_AES_CMAC_EN typedef struct atca_aes_cmac_ctx { atca_aes_cbc_ctx_t cbc_ctx; //!< CBC context @@ -46,7 +69,13 @@ typedef struct atca_aes_cmac_ctx uint8_t block[ATCA_AES128_BLOCK_SIZE]; //!< Unprocessed message storage. } atca_aes_cmac_ctx_t; +ATCA_STATUS atcab_aes_cmac_init_ext(ATCADevice device, atca_aes_cmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); +ATCA_STATUS atcab_aes_cmac_init(atca_aes_cmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); +ATCA_STATUS atcab_aes_cmac_update(atca_aes_cmac_ctx_t* ctx, const uint8_t* data, uint32_t data_size); +ATCA_STATUS atcab_aes_cmac_finish(atca_aes_cmac_ctx_t* ctx, uint8_t* cmac, uint32_t cmac_size); +#endif +#if ATCAB_AES_CTR_EN typedef struct atca_aes_ctr_ctx { ATCADevice device; //!< Device Context Pointer @@ -56,7 +85,17 @@ typedef struct atca_aes_ctr_ctx uint8_t counter_size; //!< Size of counter in the initialization vector. }atca_aes_ctr_ctx_t; +ATCA_STATUS atcab_aes_ctr_init_ext(ATCADevice device, atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, const uint8_t* iv); +ATCA_STATUS atcab_aes_ctr_init(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, const uint8_t* iv); +ATCA_STATUS atcab_aes_ctr_init_rand_ext(ATCADevice device, atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, uint8_t* iv); +ATCA_STATUS atcab_aes_ctr_init_rand(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t counter_size, uint8_t* iv); +ATCA_STATUS atcab_aes_ctr_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* input, uint8_t* output); +ATCA_STATUS atcab_aes_ctr_encrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* plaintext, uint8_t* ciphertext); +ATCA_STATUS atcab_aes_ctr_decrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* ciphertext, uint8_t* plaintext); +ATCA_STATUS atcab_aes_ctr_increment(atca_aes_ctr_ctx_t* ctx); +#endif +#if ATCAB_AES_CBCMAC_EN typedef struct atca_aes_cbcmac_ctx { atca_aes_cbc_ctx_t cbc_ctx; //!< CBC context @@ -64,7 +103,13 @@ typedef struct atca_aes_cbcmac_ctx uint8_t block[ATCA_AES128_BLOCK_SIZE]; //!< Unprocessed message storage. } atca_aes_cbcmac_ctx_t; +ATCA_STATUS atcab_aes_cbcmac_init_ext(ATCADevice device, atca_aes_cbcmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); +ATCA_STATUS atcab_aes_cbcmac_init(atca_aes_cbcmac_ctx_t* ctx, uint16_t key_id, uint8_t key_block); +ATCA_STATUS atcab_aes_cbcmac_update(atca_aes_cbcmac_ctx_t* ctx, const uint8_t* data, uint32_t data_size); +ATCA_STATUS atcab_aes_cbcmac_finish(atca_aes_cbcmac_ctx_t* ctx, uint8_t* mac, uint32_t mac_size); +#endif +#if ATCAB_AES_CCM_EN typedef struct atca_aes_ccm_ctx { atca_aes_cbcmac_ctx_t cbc_mac_ctx; //!< CBC_MAC context @@ -80,5 +125,20 @@ typedef struct atca_aes_ccm_ctx uint8_t ciphertext_block[ATCA_AES128_BLOCK_SIZE]; //!< Last ciphertext block } atca_aes_ccm_ctx_t; +ATCA_STATUS atcab_aes_ccm_init_ext(ATCADevice device, atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); +ATCA_STATUS atcab_aes_ccm_init(atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); +ATCA_STATUS atcab_aes_ccm_init_rand_ext(ATCADevice device, atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); +ATCA_STATUS atcab_aes_ccm_init_rand(atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t key_block, uint8_t* iv, size_t iv_size, size_t aad_size, size_t text_size, size_t tag_size); +ATCA_STATUS atcab_aes_ccm_aad_update(atca_aes_ccm_ctx_t* ctx, const uint8_t* aad, size_t aad_size); +ATCA_STATUS atcab_aes_ccm_aad_finish(atca_aes_ccm_ctx_t* ctx); +ATCA_STATUS atcab_aes_ccm_encrypt_update(atca_aes_ccm_ctx_t* ctx, const uint8_t* plaintext, uint32_t plaintext_size, uint8_t* ciphertext); +ATCA_STATUS atcab_aes_ccm_decrypt_update(atca_aes_ccm_ctx_t* ctx, const uint8_t* ciphertext, uint32_t ciphertext_size, uint8_t* plaintext); +ATCA_STATUS atcab_aes_ccm_encrypt_finish(atca_aes_ccm_ctx_t* ctx, uint8_t* tag, uint8_t* tag_size); +ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* tag, bool* is_verified); +#endif + +#ifdef __cplusplus +} +#endif #endif diff --git a/lib/crypto/atca_crypto_hw_aes_cbc.c b/lib/crypto/atca_crypto_hw_aes_cbc.c index 3d92ffe43..c91cfca1b 100644 --- a/lib/crypto/atca_crypto_hw_aes_cbc.c +++ b/lib/crypto/atca_crypto_hw_aes_cbc.c @@ -39,6 +39,7 @@ #include #endif +#if (ATCAB_AES_CBC_ENCRYPT_EN || ATCAB_AES_CBC_DECRYPT_EN) /** \brief Initialize context for AES CBC operation. * * \param[in] device Device context pointer @@ -82,7 +83,9 @@ ATCA_STATUS atcab_aes_cbc_init(atca_aes_cbc_ctx_t* ctx, uint16_t key_id, uint8_t { return atcab_aes_cbc_init_ext(atcab_get_device(), ctx, key_id, key_block, iv); } +#endif /* ATCAB_AES_CBC_ENCRYPT || ATCAB_AES_CBC_DECRYPT */ +#if ATCAB_AES_CBC_ENCRYPT_EN /** \brief Encrypt a block of data using CBC mode and a key within the * device. atcab_aes_cbc_init() should be called before the * first use of this function. @@ -121,7 +124,9 @@ ATCA_STATUS atcab_aes_cbc_encrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* return status; } +#endif /* ATCAB_AES_CBC_ENCRYPT_EN */ +#if ATCAB_AES_CBC_DECRYPT_EN /** \brief Decrypt a block of data using CBC mode and a key within the * device. atcab_aes_cbc_init() should be called before the * first use of this function. @@ -140,7 +145,7 @@ ATCA_STATUS atcab_aes_cbc_decrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* if (ctx == NULL || ciphertext == NULL || plaintext == NULL) { - return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received");; + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); } // Block decrypt of ciphertext @@ -160,3 +165,201 @@ ATCA_STATUS atcab_aes_cbc_decrypt_block(atca_aes_cbc_ctx_t* ctx, const uint8_t* return status; } + +#ifdef ATCAB_AES_CBC_UPDATE_EN + +ATCA_STATUS atcab_aes_cbc_encrypt_update(atca_aes_cbc_ctx_t* ctx, uint8_t* plaintext, size_t plaintext_len, uint8_t* ciphertext, size_t * ciphertext_len) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (!ctx || !plaintext || !ciphertext || !ciphertext_len) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + + if ((ctx->block_size + plaintext_len) / ATCA_AES128_BLOCK_SIZE > *ciphertext_len) + { + return ATCA_TRACE(ATCA_SMALL_BUFFER, "Output buffer is too small"); + } + + *ciphertext_len = 0; + + do + { + if (ctx->block_size) + { + size_t copy_size = ATCA_AES128_BLOCK_SIZE - ctx->block_size; + if (plaintext_len < copy_size) + { + copy_size = plaintext_len; + } + memcpy(&ctx->block[ctx->block_size], plaintext, copy_size); + plaintext += copy_size; + ctx->block_size += copy_size; + plaintext_len -= copy_size; + } + if (ATCA_AES128_BLOCK_SIZE == ctx->block_size) + { + if (ATCA_SUCCESS != (status = atcab_aes_cbc_encrypt_block(ctx, ctx->block, ciphertext))) + { + break; + } + ctx->block_size = 0; + ciphertext += ATCA_AES128_BLOCK_SIZE; + *ciphertext_len += ATCA_AES128_BLOCK_SIZE; + } + if (ATCA_AES128_BLOCK_SIZE <= plaintext_len) + { + if (ATCA_SUCCESS != (status = atcab_aes_cbc_encrypt_block(ctx, plaintext, ciphertext))) + { + break; + } + plaintext += ATCA_AES128_BLOCK_SIZE; + ciphertext += ATCA_AES128_BLOCK_SIZE; + *ciphertext_len += ATCA_AES128_BLOCK_SIZE; + plaintext_len -= ATCA_AES128_BLOCK_SIZE; + } + if (plaintext_len && (ATCA_AES128_BLOCK_SIZE > plaintext_len)) + { + memcpy(ctx->block, plaintext, plaintext_len); + ctx->block_size = plaintext_len; + plaintext_len -= plaintext_len; + } + } while(plaintext_len); + + return status; +} + +ATCA_STATUS atcab_aes_cbc_encrypt_finish(atca_aes_cbc_ctx_t* ctx, uint8_t* ciphertext, size_t * ciphertext_len, uint8_t padding) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (!ctx || !ciphertext || !ciphertext_len) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + + if (padding == 1) + { + /* Use PKCS7 padding */ + size_t buflen = ATCA_AES128_BLOCK_SIZE; + status = atcac_pkcs7_pad(ctx->block, &buflen, ctx->block_size, ATCA_AES128_BLOCK_SIZE); + ctx->block_size = ATCA_AES128_BLOCK_SIZE; + } + else + { + if (ctx->block_size) + { + /* Pad with zeros */ + memset(ctx->block, 0, ATCA_AES128_BLOCK_SIZE - ctx->block_size); + } + } + + if (ATCA_SUCCESS == status && ctx->block_size) + { + status = atcab_aes_cbc_encrypt_block(ctx, ctx->block, ciphertext); + *ciphertext_len = ATCA_AES128_BLOCK_SIZE; + } + else + { + *ciphertext_len = 0; + } + + memset(ctx, 0, sizeof(atca_aes_cbc_ctx_t)); + + return status; +} + +ATCA_STATUS atcab_aes_cbc_decrypt_update(atca_aes_cbc_ctx_t* ctx, const uint8_t* ciphertext, size_t ciphertext_len, uint8_t* plaintext, size_t * plaintext_len) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (!ctx || !ciphertext || !ciphertext_len || !plaintext || !plaintext_len) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + + if ((ctx->block_size + ciphertext_len) / ATCA_AES128_BLOCK_SIZE > *plaintext_len) + { + return ATCA_TRACE(ATCA_SMALL_BUFFER, "Output buffer is too small"); + } + + *plaintext_len = 0; + + do + { + if (ctx->block_size && ctx->block_size < ATCA_AES128_BLOCK_SIZE) + { + size_t copy_size = ATCA_AES128_BLOCK_SIZE - ctx->block_size; + if (ciphertext_len < copy_size) + { + copy_size = ciphertext_len; + } + memcpy(&ctx->block[ctx->block_size], ciphertext, copy_size); + ciphertext += copy_size; + ctx->block_size += copy_size; + ciphertext_len -= copy_size; + } + if (ATCA_AES128_BLOCK_SIZE == ctx->block_size && ciphertext_len) + { + if (ATCA_SUCCESS != (status = atcab_aes_cbc_decrypt_block(ctx, ctx->block, plaintext))) + { + break; + } + ctx->block_size = 0; + plaintext += ATCA_AES128_BLOCK_SIZE; + *plaintext_len += ATCA_AES128_BLOCK_SIZE; + } + if (ATCA_AES128_BLOCK_SIZE <= ciphertext_len) + { + if (ATCA_SUCCESS != (status = atcab_aes_cbc_decrypt_block(ctx, ciphertext, plaintext))) + { + break; + } + plaintext += ATCA_AES128_BLOCK_SIZE; + ciphertext += ATCA_AES128_BLOCK_SIZE; + ciphertext_len -= ATCA_AES128_BLOCK_SIZE; + *plaintext_len += ATCA_AES128_BLOCK_SIZE; + } + if (ciphertext_len && (ATCA_AES128_BLOCK_SIZE > ciphertext_len)) + { + memcpy(ctx->block, ciphertext, ciphertext_len); + ctx->block_size = ciphertext_len; + ciphertext_len -= ciphertext_len; + } + } while(ciphertext_len); + + return status; +} + +ATCA_STATUS atcab_aes_cbc_decrypt_finish(atca_aes_cbc_ctx_t* ctx, uint8_t* plaintext, size_t * plaintext_len, uint8_t padding) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + if (!ctx || !plaintext || !plaintext_len) + { + return ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received"); + } + + if (ATCA_AES128_BLOCK_SIZE == ctx->block_size) + { + status = atcab_aes_cbc_decrypt_block(ctx, ctx->block, plaintext); + *plaintext_len = ATCA_AES128_BLOCK_SIZE; + + if ((ATCA_SUCCESS == status) && (padding == 1)) + { + status = atcac_pkcs7_unpad(plaintext, plaintext_len, ATCA_AES128_BLOCK_SIZE); + } + } + else if (ctx->block_size) + { + return ATCA_TRACE(ATCA_GEN_FAIL, "Remaining ciphertext does not match the block size"); + } + + memset(ctx, 0, sizeof(atca_aes_cbc_ctx_t)); + + return status; +} +#endif /* ATCAB_AES_CBC_UPDATE_EN */ + +#endif /* ATCAB_AES_CBC_DECRYPT_EN */ diff --git a/lib/crypto/atca_crypto_hw_aes_cbcmac.c b/lib/crypto/atca_crypto_hw_aes_cbcmac.c index ee4437c7e..f6dfe29c2 100644 --- a/lib/crypto/atca_crypto_hw_aes_cbcmac.c +++ b/lib/crypto/atca_crypto_hw_aes_cbcmac.c @@ -34,6 +34,9 @@ */ #include "cryptoauthlib.h" +#include "crypto_config_check.h" + +#if ATCAB_AES_CBCMAC_EN /** \brief Initialize context for AES CBC-MAC operation. * * \param[in] ctx AES CBC-MAC context to be initialized @@ -159,3 +162,4 @@ ATCA_STATUS atcab_aes_cbcmac_finish(atca_aes_cbcmac_ctx_t* ctx, uint8_t* mac, ui return ATCA_SUCCESS; } +#endif /* ATCAB_AES_CBCMAC_EN */ diff --git a/lib/crypto/atca_crypto_hw_aes_ccm.c b/lib/crypto/atca_crypto_hw_aes_ccm.c index fdbba037d..3d6469d9c 100644 --- a/lib/crypto/atca_crypto_hw_aes_ccm.c +++ b/lib/crypto/atca_crypto_hw_aes_ccm.c @@ -36,7 +36,7 @@ #include "cryptoauthlib.h" - +#if ATCAB_AES_CCM_EN /** \brief Initialize context for AES CCM operation with an existing IV, which * is common when starting a decrypt operation. * @@ -205,7 +205,9 @@ ATCA_STATUS atcab_aes_ccm_init(atca_aes_ccm_ctx_t* ctx, uint16_t key_id, uint8_t { return atcab_aes_ccm_init_ext(atcab_get_device(), ctx, key_id, key_block, iv, iv_size, aad_size, text_size, tag_size); } +#endif /* ATCAB_AES_CCM_EN */ +#if ATCAB_AES_CCM_RAND_IV_EN /** \brief Initialize context for AES CCM operation with a random nonce * * \param[in] ctx AES CCM context to be initialized @@ -232,11 +234,19 @@ ATCA_STATUS atcab_aes_ccm_init_rand_ext(ATCADevice device, atca_aes_ccm_ctx_t* c if (iv_size < 7 || iv_size > 13) { // Generating random number to feed into calib_aes_ccm_init function. - status = atcab_random_ext(device, random_nonce); - if (status != ATCA_SUCCESS) +#if ATCA_HOSTLIB_EN + if (ATCA_SUCCESS != (status = atcac_sw_random(random_nonce, 32))) + { + return status; + } +#elif CALIB_RANDOM_EN || TALIB_RANDOM_EN + if (ATCA_SUCCESS != (status = atcab_random_ext(device, random_nonce))) { return status; } +#else + return ATCA_GEN_FAIL; +#endif memcpy(iv, random_nonce, iv_size); } @@ -271,7 +281,9 @@ ATCA_STATUS atcab_aes_ccm_init_rand(atca_aes_ccm_ctx_t* ctx, uint16_t key_id, ui { return atcab_aes_ccm_init_rand_ext(atcab_get_device(), ctx, key_id, key_block, iv, iv_size, aad_size, text_size, tag_size); } +#endif /* ATCAB_AES_CCM_RAND_IV_EN */ +#if ATCAB_AES_CCM_EN /** \brief Process Additional Authenticated Data (AAD) using CCM mode and a * key within the ATECC608A device. * @@ -595,3 +607,4 @@ ATCA_STATUS atcab_aes_ccm_decrypt_finish(atca_aes_ccm_ctx_t* ctx, const uint8_t* return ATCA_SUCCESS; } +#endif /* ATCAB_AES_CCM_EN */ diff --git a/lib/crypto/atca_crypto_hw_aes_cmac.c b/lib/crypto/atca_crypto_hw_aes_cmac.c index a6c15e353..70488564f 100644 --- a/lib/crypto/atca_crypto_hw_aes_cmac.c +++ b/lib/crypto/atca_crypto_hw_aes_cmac.c @@ -39,6 +39,8 @@ #include #endif +#if ATCAB_AES_CMAC_EN + static const uint8_t g_aes_zero_block[ATCA_AES128_BLOCK_SIZE] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 @@ -232,3 +234,4 @@ ATCA_STATUS atcab_aes_cmac_finish(atca_aes_cmac_ctx_t* ctx, uint8_t* cmac, uint3 return ATCA_SUCCESS; } +#endif /* ATCAB_AES_CMAC_EN */ diff --git a/lib/crypto/atca_crypto_hw_aes_ctr.c b/lib/crypto/atca_crypto_hw_aes_ctr.c index d580956f0..7cc48403f 100644 --- a/lib/crypto/atca_crypto_hw_aes_ctr.c +++ b/lib/crypto/atca_crypto_hw_aes_ctr.c @@ -35,6 +35,7 @@ #include "cryptoauthlib.h" #include "atca_crypto_hw_aes.h" +#if ATCAB_AES_CTR_EN /** \brief Initialize context for AES CTR operation with an existing IV, which * is common when start a decrypt operation. * @@ -94,7 +95,9 @@ ATCA_STATUS atcab_aes_ctr_init(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, uint8_t { return atcab_aes_ctr_init_ext(atcab_get_device(), ctx, key_id, key_block, counter_size, iv); } +#endif /* ATCAB_AES_CTR_EN */ +#if ATCAB_AES_CTR_RAND_IV_EN /** \brief Initialize context for AES CTR operation with a random nonce and * counter set to 0 as the IV, which is common when starting an * encrypt operation. @@ -136,10 +139,19 @@ ATCA_STATUS atcab_aes_ctr_init_rand_ext(ATCADevice device, atca_aes_ctr_ctx_t* c if (nonce_size != 0) { uint8_t random_nonce[32]; +#if ATCA_HOSTLIB_EN + if (ATCA_SUCCESS != (status = atcac_sw_random(random_nonce, 32))) + { + return status; + } +#elif CALIB_RANDOM_EN || TALIB_RANDOM_EN if (ATCA_SUCCESS != (status = atcab_random_ext(device, random_nonce))) { return status; } +#else + return ATCA_GEN_FAIL; +#endif memcpy(iv, random_nonce, nonce_size); } memcpy(ctx->cb, iv, ATCA_AES128_BLOCK_SIZE); @@ -171,7 +183,9 @@ ATCA_STATUS atcab_aes_ctr_init_rand(atca_aes_ctr_ctx_t* ctx, uint16_t key_id, ui { return atcab_aes_ctr_init_rand_ext(atcab_get_device(), ctx, key_id, key_block, counter_size, iv); } +#endif /* ATCAB_AES_CTR_RAND_IV_EN */ +#if ATCAB_AES_CTR_EN /** \brief Increments AES CTR counter value. * * \param[in,out] ctx AES CTR context @@ -278,3 +292,4 @@ ATCA_STATUS atcab_aes_ctr_decrypt_block(atca_aes_ctr_ctx_t* ctx, const uint8_t* { return atcab_aes_ctr_block(ctx, ciphertext, plaintext); } +#endif /* ATCAB_AES_CTR_EN */ diff --git a/lib/crypto/atca_crypto_pad.c b/lib/crypto/atca_crypto_pad.c new file mode 100644 index 000000000..93adeb192 --- /dev/null +++ b/lib/crypto/atca_crypto_pad.c @@ -0,0 +1,127 @@ +/** + * \file + * \brief Implementation of PKCS7 Padding for block encryption + * + * \copyright (c) 2022 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "cryptoauthlib.h" +#include "atca_crypto_sw.h" + +#ifdef ATCAC_PKCS7_PAD_EN + +ATCA_STATUS atcac_pkcs7_pad( + uint8_t * buffer, /**< [in/out] The buffer that will be padded */ + size_t * buflen, /**< [in/out] Input: the length of the buffer, Ouput: The padded length */ + const size_t datalen, /**< [in] Length of the input data */ + const uint8_t blocksize /**< [in] The block size in bytes to pad to */ + ) +{ + size_t outlen; + uint8_t padsym; + + if (!buffer || !buflen) + { + return ATCA_BAD_PARAM; + } + + if (datalen < blocksize) + { + outlen = blocksize; + } + else + { + /* Whole number of blocks */ + outlen = datalen / blocksize; + /* Round to the next block */ + outlen = outlen * blocksize + blocksize; + } + + if (*buflen < outlen) + { + return ATCA_SMALL_BUFFER; + } + + /* Determine what padding symbol to use - should never be 0 */ + padsym = (uint8_t)(outlen - datalen); + + /* Fill the end of the buffer with the symbol */ + memset(&buffer[datalen], padsym, padsym); + + *buflen = outlen; + + return ATCA_SUCCESS; +} + +ATCA_STATUS atcac_pkcs7_unpad( + uint8_t * buffer, /**< [in/out] The buffer that will be padded */ + size_t * buflen, /**< [in/out] Input: the length of the buffer, Ouput: The actual length */ + const uint8_t blocksize /**< [in] The block size in bytes to pad to */ + ) +{ + uint8_t padsym; + size_t i; + size_t outlen; + + if (!buffer || !buflen || !*buflen) + { + return ATCA_BAD_PARAM; + } + + /* There must at minimum one padding byte */ + padsym = buffer[*buflen - 1]; + + /* Padding bytes must be in the range 1..blocksize */ + if (!padsym || padsym > blocksize) + { + return ATCA_GEN_FAIL; + } + + outlen = *buflen - padsym; + + for (i=*buflen - 1; i >= outlen; i--) + { + if (buffer[i] != padsym) + { + /* Bad padding byte found */ + break; + } + else + { + /* null it */ + buffer[i] = 0; + } + } + + if (i == outlen - 1) + { + *buflen = outlen; + return ATCA_SUCCESS; + } + else + { + return ATCA_GEN_FAIL; + } +} + +#endif /* ATCAC_PKCS7_PAD_EN */ diff --git a/lib/crypto/atca_crypto_pbkdf2.c b/lib/crypto/atca_crypto_pbkdf2.c index 2af4b6cba..15160aa02 100644 --- a/lib/crypto/atca_crypto_pbkdf2.c +++ b/lib/crypto/atca_crypto_pbkdf2.c @@ -28,6 +28,7 @@ #include "cryptoauthlib.h" +#if ATCAC_PBKDF2_SHA256_EN /** \brief Calculate a PBKDF2 hash of a given password and salt * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -111,7 +112,9 @@ ATCA_STATUS atcac_pbkdf2_sha256( } return status; } +#endif /* ATCAC_PBKDF2_SHA256 */ +#if ATCAB_PBKDF2_SHA256_EN /** \brief Calculate a PBKDF2 password hash using a stored key inside a device. The key length is * determined by the device being used. ECCx08: 32 bytes, TA100: 16-64 bytes * @@ -193,3 +196,4 @@ ATCA_STATUS atcab_pbkdf2_sha256( { return atcab_pbkdf2_sha256_ext(atcab_get_device(), iter, slot, salt, salt_len, result, result_len); } +#endif /* ATCAB_PBKDF2_SHA256_EN */ diff --git a/lib/crypto/atca_crypto_sw.h b/lib/crypto/atca_crypto_sw.h index 8e92a98b1..317fa385e 100644 --- a/lib/crypto/atca_crypto_sw.h +++ b/lib/crypto/atca_crypto_sw.h @@ -28,10 +28,11 @@ #ifndef ATCA_CRYPTO_SW_H #define ATCA_CRYPTO_SW_H + #include #include -#include "atca_config.h" +#include "crypto/crypto_config_check.h" #include "atca_status.h" #ifdef __cplusplus @@ -114,18 +115,6 @@ typedef atca_wc_ctx atcac_pk_ctx; #include "wolfssl/wolfcrypt/ecc.h" #else -#ifndef ATCA_ENABLE_SHA1_IMPL -#define ATCA_ENABLE_SHA1_IMPL 1 -#endif - -#ifndef ATCA_ENABLE_SHA256_IMPL -#define ATCA_ENABLE_SHA256_IMPL 1 -#endif - -#ifndef ATCA_ENABLE_RAND_IMPL -#define ATCA_ENABLE_RAND_IMPL 1 -#endif - typedef struct { uint32_t pad[32]; //!< Filler value to make sure the actual implementation has enough room to store its context. uint32_t is used to remove some alignment warnings. @@ -152,12 +141,12 @@ ATCA_STATUS atcac_aes_cmac_init(atcac_aes_cmac_ctx* ctx, const uint8_t* key, con ATCA_STATUS atcac_aes_cmac_update(atcac_aes_cmac_ctx* ctx, const uint8_t* data, const size_t data_size); ATCA_STATUS atcac_aes_cmac_finish(atcac_aes_cmac_ctx* ctx, uint8_t* cmac, size_t* cmac_size); -ATCA_STATUS atcac_pk_init(atcac_pk_ctx* ctx, uint8_t* buf, size_t buflen, uint8_t key_type, bool pubkey); -ATCA_STATUS atcac_pk_init_pem(atcac_pk_ctx* ctx, uint8_t* buf, size_t buflen, bool pubkey); +ATCA_STATUS atcac_pk_init(atcac_pk_ctx* ctx, const uint8_t* buf, size_t buflen, uint8_t key_type, bool pubkey); +ATCA_STATUS atcac_pk_init_pem(atcac_pk_ctx* ctx, const uint8_t* buf, size_t buflen, bool pubkey); ATCA_STATUS atcac_pk_free(atcac_pk_ctx* ctx); ATCA_STATUS atcac_pk_public(atcac_pk_ctx* ctx, uint8_t* buf, size_t* buflen); -ATCA_STATUS atcac_pk_sign(atcac_pk_ctx* ctx, uint8_t* digest, size_t dig_len, uint8_t* signature, size_t* sig_len); -ATCA_STATUS atcac_pk_verify(atcac_pk_ctx* ctx, uint8_t* digest, size_t dig_len, uint8_t* signature, size_t sig_len); +ATCA_STATUS atcac_pk_sign(atcac_pk_ctx* ctx, const uint8_t* digest, size_t dig_len, uint8_t* signature, size_t* sig_len); +ATCA_STATUS atcac_pk_verify(atcac_pk_ctx* ctx, const uint8_t* digest, size_t dig_len, const uint8_t* signature, size_t sig_len); ATCA_STATUS atcac_pk_derive(atcac_pk_ctx* private_ctx, atcac_pk_ctx* public_ctx, uint8_t* buf, size_t* buflen); #endif @@ -179,8 +168,15 @@ ATCA_STATUS atcac_aes_gcm_decrypt(atcac_aes_gcm_ctx* ctx, const uint8_t* ciphert size_t tag_len, const uint8_t* aad, const size_t aad_len, bool* is_verified); #endif +#if ATCA_HOSTLIB_EN +int atcac_sw_random(uint8_t* data, size_t data_size); +#endif + ATCA_STATUS atcac_pbkdf2_sha256(const uint32_t iter, const uint8_t* password, const size_t password_len, const uint8_t* salt, const size_t salt_len, uint8_t* result, size_t result_len); +ATCA_STATUS atcac_pkcs7_pad(uint8_t * buffer, size_t * buflen, const size_t datalen, uint8_t blocksize); +ATCA_STATUS atcac_pkcs7_unpad(uint8_t * buffer, size_t * buflen, const uint8_t blocksize); + #ifdef __cplusplus } #endif diff --git a/lib/crypto/atca_crypto_sw_sha1.c b/lib/crypto/atca_crypto_sw_sha1.c index 534a8c50e..d4096e996 100644 --- a/lib/crypto/atca_crypto_sw_sha1.c +++ b/lib/crypto/atca_crypto_sw_sha1.c @@ -28,9 +28,9 @@ #include "atca_crypto_sw_sha1.h" #include "hashes/sha1_routines.h" +#include "cryptoauthlib.h" -#if ATCA_ENABLE_SHA1_IMPL - +#if ATCA_CRYPTO_SHA1_EN /** \brief Initialize context for performing SHA1 hash in software. * \param[in] ctx Hash context * \return ATCA_SUCCESS on success, otherwise an error code. @@ -72,8 +72,9 @@ int atcac_sw_sha1_finish(atcac_sha1_ctx* ctx, uint8_t digest[ATCA_SHA1_DIGEST_SI return ATCA_SUCCESS; } -#endif +#endif /* ATCA_CRYPTO_SHA1_EN */ +#if ATCAC_SHA1_EN /** \brief Perform SHA1 hash of data in software. * \param[in] data Data to be hashed * \param[in] data_size Data size in bytes @@ -105,3 +106,4 @@ int atcac_sw_sha1(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA return ATCA_SUCCESS; } +#endif /* ATCA_CRYPTO_SHA1_EN */ diff --git a/lib/crypto/atca_crypto_sw_sha2.c b/lib/crypto/atca_crypto_sw_sha2.c index 633257cb0..9621387a8 100644 --- a/lib/crypto/atca_crypto_sw_sha2.c +++ b/lib/crypto/atca_crypto_sw_sha2.c @@ -29,7 +29,7 @@ #include "atca_crypto_sw_sha2.h" #include "hashes/sha2_routines.h" -#if ATCA_ENABLE_SHA256_IMPL +#if ATCA_CRYPTO_SHA2_EN /** \brief initializes the SHA256 software * \param[in] ctx ptr to context data structure * \return ATCA_SUCCESS on success, otherwise an error code. @@ -73,7 +73,43 @@ int atcac_sw_sha2_256_finish(atcac_sha2_256_ctx* ctx, uint8_t digest[ATCA_SHA2_2 return ATCA_SUCCESS; } +#endif /* ATCA_CRYPTO_SHA2_EN */ +#if ATCAC_SHA256_EN +/** \brief single call convenience function which computes Hash of given data using SHA256 software + * \param[in] data pointer to stream of data to hash + * \param[in] data_size size of data stream to hash + * \param[out] digest result + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +int atcac_sw_sha2_256(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]) +{ + int ret; + atcac_sha2_256_ctx ctx; + + ret = atcac_sw_sha2_256_init(&ctx); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_256_update(&ctx, data, data_size); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_256_finish(&ctx, digest); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + return ATCA_SUCCESS; +} +#endif /* ATCAC_SHA256_EN */ + +#if ATCA_CRYPTO_SHA2_HMAC_EN /** \brief Initialize context for performing HMAC (sha256) in software. * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -150,7 +186,7 @@ ATCA_STATUS atcac_sha256_hmac_finish( { ATCA_STATUS status = ATCA_BAD_PARAM; - if (ctx) + if (ctx && digest_len && *digest_len >= ATCA_SHA2_256_DIGEST_SIZE ) { uint8_t temp_dig[ATCA_SHA2_256_DIGEST_SIZE]; @@ -166,43 +202,9 @@ ATCA_STATUS atcac_sha256_hmac_finish( } return status; } +#endif /* ATCA_CRYPTO_SHA2_HMAC_EN */ - -#endif /* ATCA_ENABLE_SHA256_IMPL */ - -/** \brief single call convenience function which computes Hash of given data using SHA256 software - * \param[in] data pointer to stream of data to hash - * \param[in] data_size size of data stream to hash - * \param[out] digest result - * \return ATCA_SUCCESS on success, otherwise an error code. - */ - -int atcac_sw_sha2_256(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]) -{ - int ret; - atcac_sha2_256_ctx ctx; - - ret = atcac_sw_sha2_256_init(&ctx); - if (ret != ATCA_SUCCESS) - { - return ret; - } - - ret = atcac_sw_sha2_256_update(&ctx, data, data_size); - if (ret != ATCA_SUCCESS) - { - return ret; - } - - ret = atcac_sw_sha2_256_finish(&ctx, digest); - if (ret != ATCA_SUCCESS) - { - return ret; - } - - return ATCA_SUCCESS; -} - +#if ATCA_CRYPTO_SHA2_HMAC_CTR_EN /** \brief Implements SHA256 HMAC-Counter per NIST SP 800-108 used for KDF like operations */ ATCA_STATUS atcac_sha256_hmac_counter( atcac_hmac_sha256_ctx* ctx, @@ -234,3 +236,4 @@ ATCA_STATUS atcac_sha256_hmac_counter( } return ret; } +#endif /* ATCA_CRYPTO_SHA2_HMAC_CTR_EN */ diff --git a/lib/crypto/crypto_config_check.h b/lib/crypto/crypto_config_check.h new file mode 100644 index 000000000..9219cc803 --- /dev/null +++ b/lib/crypto/crypto_config_check.h @@ -0,0 +1,270 @@ +/** + * \file + * \brief Consistency checks for configuration options + * + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef CRYPTO_CONFIG_CHECK_H +#define CRYPTO_CONFIG_CHECK_H + +#include "atca_config_check.h" + +#if ATCA_CA_SUPPORT +#include "calib/calib_config_check.h" +#endif + +#if ATCA_TA_SUPPORT +#include "talib/talib_config_check.h" +#endif + +/** \def ATCAB_AES_EXTRAS_EN + * + * Automatically set base on other configuation options but can be overridden to disable all + * CBC, CBCMAC, CTR, & CCM modes at once rather than individually + */ +#ifndef ATCAB_AES_EXTRAS_EN +#define ATCAB_AES_EXTRAS_EN (CALIB_AES_EN || TALIB_AES_EN) +#endif + +#ifndef ATCAB_AES_RANDOM_IV_EN +#define ATCAB_AES_RANDOM_IV_EN (ATCA_HOSTLIB_EN || CALIB_RANDOM_EN || TALIB_RANDOM_EN) +#endif + +/** \def ATCAB_AES_UPDATE_EN + * Enable update/finalize APIs for block ciphers + */ +#ifndef ATCAB_AES_UPDATE_EN +#define ATCAB_AES_UPDATE_EN ATCAB_AES_EXTRAS_EN +#endif + + /****** ATCA_CRYPTO_HW_AES_CBC ******/ + +/** \def ATCAB_AES_CBC_ENCRYPT_EN + * + * Requires: ATCAB_AES_EN + * + * Enable ATCAB_AES_CBC_ENCRYPT_EN to encrypt a block of data using CBC mode and a key within the + * device. atcab_aes_cbc_init() should be called before the first use of this function + * + * Supported API's: atcab_aes_cbc_encrypt_block , atcab_aes_cbc_init_ext, atcab_aes_cbc_init + **/ +#ifndef ATCAB_AES_CBC_ENCRYPT_EN +#define ATCAB_AES_CBC_ENCRYPT_EN ATCAB_AES_EXTRAS_EN +#endif + +/** \def ATCAB_AES_CBC_DECRYPT_EN + * + * Requires: ATCAB_AES_EN + * + * Enable ATCAB_AES_CBC_DECRYPT to decrypt a block of data using CBC mode and a key within the + * device. atcab_aes_cbc_init() should be called before the first use of this function + * + * Supported API's: atcab_aes_cbc_decrypt_block, atcab_aes_cbc_init_ext, atcab_aes_cbc_init + **/ +#ifndef ATCAB_AES_CBC_DECRYPT_EN +#define ATCAB_AES_CBC_DECRYPT_EN ATCAB_AES_EXTRAS_EN +#endif + +#ifndef ATCAB_AES_CBC_UPDATE_EN +#define ATCAB_AES_CBC_UPDATE_EN ATCAB_AES_UPDATE_EN +#endif + + /****** ATCA_CRYPTO_HW_AES_CBCMAC ******/ + +/** \def ATCAB_AES_CBCMAC_EN + * + * Requires: ATCAB_AES_CBCMAC + * ATCAB_AES_CBC_ENCRYPT + * ATCAB_AES_MODE_ENCODING + * CALIB_AES_MODE_ENCODING + * CALIB_AES + * + * Enable ATCAB_AES_CBCMAC to initialize context for AES CBC-MAC operation + * Enable ATCAB_AES_CBCMAC to calculate AES CBC-MAC with key stored within ECC608 device + * Enable ATCAB_AES_CBCMAC to finish a CBC-MAC operation returning the CBC-MAC value + * + * Supported API's: atcab_aes_cbcmac_init_ext + * atcab_aes_cbcmac_init, atcab_aes_cbcmac_init_update, atcab_aes_cbcmac_finish + **/ +#ifndef ATCAB_AES_CBCMAC_EN +#define ATCAB_AES_CBCMAC_EN ATCAB_AES_CBC_ENCRYPT_EN +#endif + + /****** ATCA_CRYPTO_HW_AES_CTR ******/ + +/** \def ATCAB_AES_CTR_EN + * + * Requires: ATCAB_AES_EN + * + * Enable ATCAB_AES_CTR_EN to support AES-CTR mode + * + **/ +#ifndef ATCAB_AES_CTR_EN +#define ATCAB_AES_CTR_EN ATCAB_AES_EXTRAS_EN +#endif + +/** \def ATCAB_AES_CTR_RAND_IV_EN + * + * Requires: ATCAB_AES_CTR_EN + * ATCAB_RANDOM_EN + * + * Enable ATCAB_AES_CTR_RAND_IV_EN to initialize context for AES CTR operation with a random nonce and + * counter set to 0 as the IV, which is common when starting an encrypt operation + * + * Supported API's: atcab_aes_ctr_init_rand_ext, atcab_aes_ctr_init_rand + **/ +#ifndef ATCAB_AES_CTR_RAND_IV_EN +#define ATCAB_AES_CTR_RAND_IV_EN (ATCAB_AES_CTR_EN && ATCAB_AES_RANDOM_IV_EN) +#endif + + /****** ATCA_CRYPTO_HW_AES_CCM ******/ + +/** \def ATCAB_AES_CCM_EN + * + * Requires: ATCAB_AES_EN + * ATCAB_AES_CTR_EN + * + * Enable ATCAB_AES_CCM_EN to enable AES CCM operation + * + **/ +#ifndef ATCAB_AES_CCM_EN +#define ATCAB_AES_CCM_EN (ATCAB_AES_CBCMAC_EN && ATCAB_AES_CTR_EN) +#endif + +/** \def ATCAB_AES_CCM_INIT_RAND + * + * Requires: ATCAB_AES_CCM_INIT_RAND + * ATCAB_AES_CCM_INIT + * ATCAB_RANDOM + * CALIB_RANDOM + * + * Enable ATCAB_AES_CCM_INIT_RAND to initialize context for AES CCM operation with a random nonce + * + * Supported API's: atcab_aes_ccm_init_rand_ext + * atcab_aes_ccm_init_rand + **/ +#ifndef ATCAB_AES_CCM_RAND_IV_EN +#define ATCAB_AES_CCM_INIT_IV_EN (ATCAB_AES_CCM_EN && ATCAB_AES_RANDOM_IV_EN) +#endif + + /****** ATCA_CRYPTO_HW_AES_CMAC ******/ + +/** \def ATCAB_AES_CMAC + * + * Requires: ATCAB_AES_CMAC + * ATCAB_AES_CBC_ENCRYPT + * ATCAB_AES_MODE_ENCODING + * CALIB_AES_MODE_ENCODING + * CALIB_AES + * + * Enable ATCAB_AES_CMAC to initialize a CMAC calculation using an AES-128 key in the device + * Enable ATCAB_AES_CMAC to add data to an initialized CMAC calculation + * Enable ATCAB_AES_CMAC to finish a CMAC operation returning the CMAC value + * + * Supported API's: atcab_aes_cmac_init_ext, left_shift_one + * atcab_aes_cmac_init, atcab_aes_cmac_init_update, atcab_aes_cmac_finish + **/ +#ifndef ATCAB_AES_CMAC_EN +#define ATCAB_AES_CMAC_EN ATCAB_AES_CBC_ENCRYPT_EN +#endif + +/** \def ATCA_CRYPTO_SHA1_EN + * + * Enable ATCAC_SHA1_EN to enable sha1 host side api + * + * Supported API's: atcab_write + **/ +#ifndef ATCA_CRYPTO_SHA1_EN +#define ATCA_CRYPTO_SHA1_EN (ATCAC_SHA1_EN && !ATCA_HOSTLIB_EN) +#endif + +/** \def ATCAC_SHA256_EN + * + * Enable ATCAC_SHA256_EN to enable sha256 host side api + * + * Supported API's: atcab_write + **/ +#ifndef ATCA_CRYPTO_SHA2_EN +#define ATCA_CRYPTO_SHA2_EN (ATCAC_SHA256_EN && !ATCA_HOSTLIB_EN) +#endif + +/** \def ATCA_CRYPTO_SHA2_HMAC_EN + * + * Requires: ATCAC_SHA256_EN + * + * Enable ATCAC_SHA256_HMAC to initialize context for performing HMAC (sha256) in software + * + * Supported API's: atcac_sha256_hmac_init, atcac_sha256_hmac_update, atcac_sha256_hmac_finish + **/ +#ifndef ATCA_CRYPTO_SHA2_HMAC_EN +#define ATCA_CRYPTO_SHA2_HMAC_EN (ATCAC_SHA256_HMAC_EN && !ATCA_HOSTLIB_EN) +#endif + +/** \def ATCA_CRYPTO_SHA2_HMAC_CTR_EN + * + * Requires: ATCAC_SHA256_HMAC_EN + * + * Enable ATCAC_SHA256_HMAC_COUNTER to implement SHA256 HMAC-Counter per NIST SP 800-108 used for + * KDF like operations + * + * Supported API's: atcac_sha256_hmac_counter + **/ +#ifndef ATCA_CRYPTO_SHA2_HMAC_CTR_EN +#define ATCA_CRYPTO_SHA2_HMAC_CTR_EN ATCAC_SHA256_HMAC_CTR_EN +#endif + + /****** ATCA_CRYPTO_PBKDF2 ******/ + +/** \def ATCAC_PBKDF2_SHA256_EN + * + * Requires: ATCAC_SHA256_EN + * ATCAC_SHA256_HMAC_EN + * + * Enable ATCAC_PBKDF2_SHA256_EN to calculate a PBKDF2 hash of a given password and salt + * + * Supported API's: atcac_pbkdf2_256 + **/ +#ifndef ATCAC_PBKDF2_SHA256_EN +#define ATCAC_PBKDF2_SHA256_EN ATCAC_SHA256_HMAC_EN +#endif + +/** \def ATCAB_PBKDF2_SHA256_EN + * + * Requires: CALIB_SHA_HMAC_EN + * + * Enable ATCAB_PBKDF2_SHA256_EN to calculate a PBKDF2 password hash using a stored key inside a + * device. The key length is determined by the device being used. ECCx08: 32 bytes, TA100: 16-64 bytes + * + * Supported API's: atcab_pbkdf2_256, atcab_pbkdf2_256_ext + **/ +#ifndef ATCAB_PBKDF2_SHA256_EN +#define ATCAB_PBKDF2_SHA256_EN (CALIB_SHA_HMAC_EN || TALIB_SHA_HMAC_EN) +#endif + + /****** ATCA_CRYPTO_PKCS7_PADDING ******/ +#ifndef ATCAC_PKCS7_PAD_EN +#define ATCAC_PKCS7_PAD_EN ATCAB_AES_EXTRAS_EN +#endif + +#endif /* CRYPTO_CONFIG_CHECK_H */ diff --git a/lib/crypto/hashes/sha1_routines.c b/lib/crypto/hashes/sha1_routines.c index f386911e6..e5cadb41b 100644 --- a/lib/crypto/hashes/sha1_routines.c +++ b/lib/crypto/hashes/sha1_routines.c @@ -28,7 +28,9 @@ #include "sha1_routines.h" #include #include "atca_compiler.h" +#include "cryptoauthlib.h" +#if ATCA_CRYPTO_SHA1_EN /** * \brief Initialize context for performing SHA1 hash in software. * @@ -322,3 +324,4 @@ void shaEngine(U32 *buf, U32 *h) //} } +#endif /* ATCA_CRYPTO_SHA1_EN */ diff --git a/lib/crypto/hashes/sha2_routines.c b/lib/crypto/hashes/sha2_routines.c index aeae01558..370f5f4dd 100644 --- a/lib/crypto/hashes/sha2_routines.c +++ b/lib/crypto/hashes/sha2_routines.c @@ -25,11 +25,12 @@ * THIS SOFTWARE. */ -#include +#include "cryptoauthlib.h" #include "sha2_routines.h" -#include "atca_compiler.h" + #define rotate_right(value, places) ((value >> places) | (value << (32 - places))) +#if ATCA_CRYPTO_SHA2_EN /** * \brief Processes whole blocks (64 bytes) of data. * @@ -255,3 +256,4 @@ void sw_sha256(const uint8_t* message, unsigned int len, uint8_t digest[SHA256_D sw_sha256_update(&ctx, message, len); sw_sha256_final(&ctx, digest); } +#endif /* ATCA_CRYPTO_SHA2_EN */ diff --git a/lib/cryptoauthlib.h b/lib/cryptoauthlib.h index 0839afdfc..3cbff72f9 100644 --- a/lib/cryptoauthlib.h +++ b/lib/cryptoauthlib.h @@ -37,39 +37,10 @@ /** Library Configuration File - All build attributes should be included in atca_config.h */ -#include "atca_config.h" +#include "atca_config_check.h" #include "atca_compiler.h" #include "atca_version.h" - -/* Configuration Macros to detect device classes */ -#if defined(ATCA_ATSHA204A_SUPPORT) || defined(ATCA_ATSHA206A_SUPPORT) -#define ATCA_SHA_SUPPORT 1 -#endif - -/* Make sure all configuration options work */ -#if defined(ATCA_ATECC608A_SUPPORT) && !defined(ATCA_ATECC608_SUPPORT) -#define ATCA_ATECC608_SUPPORT -#endif - -#if defined(ATCA_ATECC108A_SUPPORT) || defined(ATCA_ATECC508A_SUPPORT) \ - || defined(ATCA_ATECC608_SUPPORT) -#define ATCA_ECC_SUPPORT 1 -#endif - -/* Classic Cryptoauth Devices */ -#if defined(ATCA_SHA_SUPPORT) || defined(ATCA_ECC_SUPPORT) || defined(ATCA_ECC204_SUPPORT) -#define ATCA_CA_SUPPORT 1 -#else -#define ATCA_CA_SUPPORT 0 -#endif - -/* New Trust Anchor Devices */ -#if defined(ATCA_TA100_SUPPORT) -#define ATCA_TA_SUPPORT 1 -#else -#define ATCA_TA_SUPPORT 0 -#endif - +#include "atca_platform.h" #include "atca_status.h" #include "atca_debug.h" #include "atca_iface.h" @@ -116,6 +87,7 @@ #include "talib/talib_basic.h" #endif +/* Common Library Functions */ #include "atca_basic.h" #define ATCA_STRINGIFY(x) #x diff --git a/lib/hal/atca_hal.h b/lib/hal/atca_hal.h index 999925695..4b240fce1 100644 --- a/lib/hal/atca_hal.h +++ b/lib/hal/atca_hal.h @@ -205,27 +205,10 @@ ATCA_STATUS hal_destroy_mutex(void * pMutex); ATCA_STATUS hal_lock_mutex(void * pMutex); ATCA_STATUS hal_unlock_mutex(void * pMutex); -#ifndef ATCA_NO_HEAP -#ifdef ATCA_TESTS_ENABLED +#if !defined(ATCA_NO_HEAP) && defined(ATCA_TESTS_ENABLED) void hal_test_set_memory_f(void* (*malloc_func)(size_t), void (*free_func)(void*)); #endif -#if defined(ATCA_TESTS_ENABLED) || !defined(ATCA_PLATFORM_MALLOC) -void* hal_malloc(size_t size); -void hal_free(void* ptr); -#else -#define hal_malloc ATCA_PLATFORM_MALLOC -#define hal_free ATCA_PLATFORM_FREE -#endif -#endif - -#ifdef memset_s -#define hal_memset_s memset_s -#else -#define hal_memset_s atcab_memset_s -#endif - - ATCA_STATUS hal_iface_register_hal(ATCAIfaceType iface_type, ATCAHAL_t *hal, ATCAHAL_t **old_hal, ATCAHAL_t* phy, ATCAHAL_t** old_phy); uint8_t hal_is_command_word(uint8_t word_address); diff --git a/lib/hal/hal_all_platforms_kit_hidapi.c b/lib/hal/hal_all_platforms_kit_hidapi.c index 51f00b6e9..7f742e4f7 100644 --- a/lib/hal/hal_all_platforms_kit_hidapi.c +++ b/lib/hal/hal_all_platforms_kit_hidapi.c @@ -47,9 +47,6 @@ */ ATCA_STATUS hal_kit_hid_init(ATCAIface iface, ATCAIfaceCfg* cfg) { - int i = 0; - int index = 0; - // Check the input variables if ((cfg == NULL) || (iface == NULL)) { @@ -62,7 +59,7 @@ ATCA_STATUS hal_kit_hid_init(ATCAIface iface, ATCAIfaceCfg* cfg) #endif hid_init(); - iface->hal_data = hid_open(cfg->atcahid.vid, cfg->atcahid.pid, NULL); + iface->hal_data = hid_open(ATCA_IFACECFG_VALUE(cfg, atcahid.vid), ATCA_IFACECFG_VALUE(cfg, atcahid.pid), NULL); return (iface->hal_data) ? ATCA_SUCCESS : ATCA_COMM_FAIL; } @@ -73,6 +70,7 @@ ATCA_STATUS hal_kit_hid_init(ATCAIface iface, ATCAIfaceCfg* cfg) */ ATCA_STATUS hal_kit_hid_post_init(ATCAIface iface) { + ((void)iface); return ATCA_SUCCESS; } @@ -87,7 +85,10 @@ ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txd { ATCAIfaceCfg *cfg = atgetifacecfg(iface); hid_device* pHid = (hid_device*)atgetifacehaldat(iface); - int bytes_written; + uint32_t bytes_written; + + ((void)word_address); + ((void)txlength); if ((txdata == NULL) || (cfg == NULL) || (pHid == NULL)) { @@ -98,8 +99,8 @@ ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txd printf("HID layer: Write: %s", txdata); #endif - bytes_written = hid_write(pHid, txdata, (size_t)cfg->atcahid.packetsize + 1); - if (bytes_written != cfg->atcahid.packetsize + 1) + bytes_written = (uint32_t)hid_write(pHid, txdata, (size_t)ATCA_IFACECFG_VALUE(cfg, atcahid.packetsize) + 1); + if (bytes_written != ATCA_IFACECFG_VALUE(cfg, atcahid.packetsize) + 1) { return ATCA_TX_FAIL; } @@ -117,17 +118,24 @@ ATCA_STATUS hal_kit_hid_send(ATCAIface iface, uint8_t word_address, uint8_t* txd ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, uint16_t* rxsize) { hid_device* pHid = (hid_device*)atgetifacehaldat(iface); + int ret; + + ((void)word_address); if ((rxdata == NULL) || (rxsize == NULL) || (pHid == NULL)) { return ATCA_BAD_PARAM; } - *rxsize = (uint16_t)hid_read(pHid, rxdata, (size_t)*rxsize); - if (*rxsize == -1) + ret = (uint16_t)hid_read(pHid, rxdata, (size_t)*rxsize); + if (ret < 0) { return ATCA_RX_FAIL; } + else + { + *rxsize = (uint16_t)ret; + } #ifdef KIT_DEBUG printf("HID layer: Read: %s", rxdata); @@ -145,8 +153,9 @@ ATCA_STATUS hal_kit_hid_receive(ATCAIface iface, uint8_t word_address, uint8_t* */ ATCA_STATUS hal_kit_hid_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { - (void)param; - (void)paramlen; + ((void)option); + ((void)param); + ((void)paramlen); if (iface && iface->mIfaceCFG) { @@ -163,7 +172,6 @@ ATCA_STATUS hal_kit_hid_control(ATCAIface iface, uint8_t option, void* param, si ATCA_STATUS hal_kit_hid_release(void* hal_data) { hid_device* pHid = (hid_device*)hal_data; - int i = 0; if (pHid == NULL) { diff --git a/lib/hal/hal_i2c_harmony.c b/lib/hal/hal_i2c_harmony.c index c1aca2f93..7ba6b9e4e 100644 --- a/lib/hal/hal_i2c_harmony.c +++ b/lib/hal/hal_i2c_harmony.c @@ -160,7 +160,6 @@ ATCA_STATUS hal_i2c_send(ATCAIface iface, uint8_t address, uint8_t *txdata, int } /* Wait for the I2C bus to be ready */ - /* Since the wait time is unknown, waiting for 30 bytes duration */ status = hal_i2c_wait(plib, cfg->atcai2c.baud, 30); if (ATCA_SUCCESS == status) @@ -256,7 +255,6 @@ ATCA_STATUS change_i2c_speed(ATCAIface iface, uint32_t speed) setup.clkSpeed = speed; /* Make sure I2C is not busy before changing the I2C clock speed */ - /* Since wait time is unknown, wait for 30 bytes */ status = hal_i2c_wait(plib, cfg->atcai2c.baud, 30); if (ATCA_SUCCESS == status) diff --git a/lib/hal/hal_kit_bridge.c b/lib/hal/hal_kit_bridge.c index 9dcee638c..90afc5d60 100644 --- a/lib/hal/hal_kit_bridge.c +++ b/lib/hal/hal_kit_bridge.c @@ -98,31 +98,23 @@ static void hal_kit_phy_packet_free(atca_hal_kit_phy_t* phy, uint8_t* packet) } #endif -/** \brief Request a list of busses from the kit host - */ -ATCA_STATUS hal_kit_discover_buses(int busses[], int max_buses) +/** \brief Configure the header with the necesary values */ +static inline void hal_kit_header(ATCAIfaceCfg* cfg, uint8_t buffer[HAL_KIT_HEADER_LEN], uint8_t command) { - return ATCA_UNIMPLEMENTED; -} - -/** \brief discover any CryptoAuth devices on a given logical bus number - * \param[in] bus_num - logical bus number on which to look for CryptoAuth devices - * \param[out] cfg[] - pointer to head of an array of interface config structures which get filled in by this method - * \param[out] *found - number of devices found on this bus - */ -ATCA_STATUS hal_kit_discover_devices(int bus_num, ATCAIfaceCfg cfg[], int* found) -{ - return ATCA_UNIMPLEMENTED; + buffer[0] = (BRIDGE_PROTOCOL_VERSION & 0x0F); + buffer[1] = command | (ATCA_IFACECFG_VALUE(cfg, atcakit.dev_interface) << 4); + buffer[2] = ATCA_IFACECFG_VALUE(cfg, atcakit.dev_identity); } /** \brief HAL implementation of Kit USB HID init - * \param[in] hal pointer to HAL specific data that is maintained by this HAL + * \param[in] iface instance * \param[in] cfg pointer to HAL specific configuration data that is used to initialize this HAL * \return ATCA_STATUS */ -ATCA_STATUS hal_kit_init(void* hal, ATCAIfaceCfg* cfg) +ATCA_STATUS hal_kit_init(ATCAIface iface, ATCAIfaceCfg* cfg) { ATCA_STATUS status = ATCA_BAD_PARAM; + (void)iface; /* Perform rationality checks on the configuration structure */ if (cfg && cfg->cfg_data) @@ -144,6 +136,7 @@ ATCA_STATUS hal_kit_init(void* hal, ATCAIfaceCfg* cfg) */ ATCA_STATUS hal_kit_post_init(ATCAIface iface) { + (void)iface; return ATCA_SUCCESS; } @@ -168,13 +161,19 @@ ATCA_STATUS hal_kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, if (packet) { - packet[0] = 1; - packet[1] = HAL_KIT_COMMAND_SEND | (iface->mIfaceCFG->atcakit.dev_interface << 4); - packet[2] = iface->mIfaceCFG->atcakit.dev_identity; + hal_kit_header(iface->mIfaceCFG, packet, HAL_KIT_COMMAND_SEND); packet[3] = word_address; - memcpy(&packet[4], &txdata[1], txlength); + if (atcab_is_ta_device(iface->mIfaceCFG->devtype)) + { + memcpy(&packet[4], &txdata[1], txlength-1); + } + else + { + memcpy(&packet[4], txdata, txlength); + txlength++; + } - status = hal_kit_phy_send(phy, packet, txlength + HAL_KIT_HEADER_LEN + 1); + status = hal_kit_phy_send(phy, packet, txlength + HAL_KIT_HEADER_LEN); if (ATCA_SUCCESS == status) { @@ -212,9 +211,7 @@ ATCA_STATUS hal_kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxda if (packet) { - packet[0] = 1; - packet[1] = HAL_KIT_COMMAND_RECV | (iface->mIfaceCFG->atcakit.dev_interface << 4); - packet[2] = iface->mIfaceCFG->atcakit.dev_identity; + hal_kit_header(iface->mIfaceCFG, packet, HAL_KIT_COMMAND_RECV); packet[3] = word_address; packet[4] = *rxsize & 0xFF; packet[5] = (*rxsize >> 8) & 0xFF; @@ -262,10 +259,7 @@ static ATCA_STATUS hal_kit_wake(ATCAIface iface) if (packet) { - packet[0] = 1; - packet[1] = HAL_KIT_COMMAND_WAKE | (iface->mIfaceCFG->atcakit.dev_interface << 4); - packet[2] = iface->mIfaceCFG->atcakit.dev_identity; - + hal_kit_header(iface->mIfaceCFG, packet, HAL_KIT_COMMAND_WAKE); status = hal_kit_phy_send(phy, packet, packet_size); if (ATCA_SUCCESS == status) @@ -302,10 +296,7 @@ static ATCA_STATUS hal_kit_idle(ATCAIface iface) if (packet) { - packet[0] = 1; - packet[1] = HAL_KIT_COMMAND_IDLE | (iface->mIfaceCFG->atcakit.dev_interface << 4); - packet[2] = iface->mIfaceCFG->atcakit.dev_identity; - + hal_kit_header(iface->mIfaceCFG, packet, HAL_KIT_COMMAND_IDLE); status = hal_kit_phy_send(phy, packet, packet_size); if (ATCA_SUCCESS == status) @@ -342,10 +333,7 @@ static ATCA_STATUS hal_kit_sleep(ATCAIface iface) if (packet) { - packet[0] = 1; - packet[1] = HAL_KIT_COMMAND_SLEEP | (iface->mIfaceCFG->atcakit.dev_interface << 4); - packet[2] = iface->mIfaceCFG->atcakit.dev_identity; - + hal_kit_header(iface->mIfaceCFG, packet, HAL_KIT_COMMAND_SLEEP); status = hal_kit_phy_send(phy, packet, packet_size); if (ATCA_SUCCESS == status) @@ -371,8 +359,11 @@ static ATCA_STATUS hal_kit_sleep(ATCAIface iface) * \param[in] option Control option to use * \return ATCA_STATUS */ -ATCA_STATUS hal_kit_control(ATCAIface iface, uint8_t option) +ATCA_STATUS hal_kit_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen) { + (void)param; + (void)paramlen; + switch (option) { case ATCA_HAL_CONTROL_WAKE: @@ -393,6 +384,7 @@ ATCA_STATUS hal_kit_control(ATCAIface iface, uint8_t option) */ ATCA_STATUS hal_kit_release(void* hal_data) { + (void)hal_data; return ATCA_SUCCESS; } diff --git a/lib/hal/hal_kit_bridge.h b/lib/hal/hal_kit_bridge.h index 8ade8f86c..e2b656aee 100644 --- a/lib/hal/hal_kit_bridge.h +++ b/lib/hal/hal_kit_bridge.h @@ -35,6 +35,9 @@ extern "C" { #endif +#define BRIDGE_PROTOCOL_VERSION (2) + + #define HAL_KIT_COMMAND_SEND 0x01 #define HAL_KIT_COMMAND_RECV 0x02 #define HAL_KIT_COMMAND_WAKE 0x03 diff --git a/lib/hal/hal_linux_i2c_userspace.c b/lib/hal/hal_linux_i2c_userspace.c index 6d6c3d4f3..25656fd33 100644 --- a/lib/hal/hal_linux_i2c_userspace.c +++ b/lib/hal/hal_linux_i2c_userspace.c @@ -85,7 +85,7 @@ ATCA_STATUS hal_i2c_init(ATCAIface iface, ATCAIfaceCfg* cfg) else { atca_i2c_host_t * hal_data = malloc(sizeof(atca_i2c_host_t)); - int bus = cfg->atcai2c.bus; // 0-based logical bus number + int bus = ATCA_IFACECFG_VALUE(cfg, atcai2c.bus); // 0-based logical bus number if (hal_data) { diff --git a/lib/hal/hal_linux_spi_userspace.c b/lib/hal/hal_linux_spi_userspace.c index b69719081..b021eb4fb 100644 --- a/lib/hal/hal_linux_spi_userspace.c +++ b/lib/hal/hal_linux_spi_userspace.c @@ -72,8 +72,6 @@ ATCA_STATUS hal_spi_open_file(const char * dev_name, uint32_t speed, int * fd) ATCA_STATUS hal_spi_init(ATCAIface iface, ATCAIfaceCfg *cfg) { - - int f_spi; ATCA_STATUS status = ATCA_BAD_PARAM; if (iface && cfg) @@ -84,7 +82,8 @@ ATCA_STATUS hal_spi_init(ATCAIface iface, ATCAIfaceCfg *cfg) if (hal_data) { (void)snprintf(hal_data->spi_file, sizeof(hal_data->spi_file) - 1, - "/dev/spidev%d.%d", (uint8_t)cfg->atcaspi.bus, (uint8_t)cfg->atcaspi.select_pin); + "/dev/spidev%d.%d", (uint8_t)ATCA_IFACECFG_VALUE(cfg, atcaspi.bus), + (uint8_t)ATCA_IFACECFG_VALUE(cfg, atcaspi.select_pin)); iface->hal_data = hal_data; status = ATCA_SUCCESS; @@ -105,6 +104,7 @@ ATCA_STATUS hal_spi_init(ATCAIface iface, ATCAIfaceCfg *cfg) ATCA_STATUS hal_spi_post_init(ATCAIface iface) { + ((void)iface); return ATCA_SUCCESS; } @@ -120,7 +120,8 @@ ATCA_STATUS hal_spi_select(ATCAIface iface) if (hal_data && cfg) { - return hal_spi_open_file(hal_data->spi_file, cfg->atcaspi.baud, &hal_data->f_spi); + return hal_spi_open_file(hal_data->spi_file, + ATCA_IFACECFG_VALUE(cfg, atcaspi.baud), &hal_data->f_spi); } else { @@ -162,10 +163,11 @@ ATCA_STATUS hal_spi_deselect(ATCAIface iface) */ ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t flags, uint8_t *rxdata, uint16_t *rxlength) { - int f_spi; ATCA_STATUS status = ATCA_BAD_PARAM; atca_spi_host_t * hal_data = (atca_spi_host_t*)atgetifacehaldat(iface); + ((void)flags); + if (hal_data) { struct spi_ioc_transfer spi_xfer = { 0 }; @@ -197,10 +199,10 @@ ATCA_STATUS hal_spi_receive(ATCAIface iface, uint8_t flags, uint8_t *rxdata, uin ATCA_STATUS hal_spi_send(ATCAIface iface, uint8_t flags, uint8_t *txdata, int txlen) { - int f_spi; ATCA_STATUS status = ATCA_SUCCESS; atca_spi_host_t * hal_data = (atca_spi_host_t*)atgetifacehaldat(iface); - int ret; + + ((void)flags); if (hal_data) { diff --git a/lib/hal/hal_linux_uart_userspace.c b/lib/hal/hal_linux_uart_userspace.c index 3b7afe30b..1a998d6db 100644 --- a/lib/hal/hal_linux_uart_userspace.c +++ b/lib/hal/hal_linux_uart_userspace.c @@ -146,12 +146,12 @@ static ATCA_STATUS hal_uart_open_file(atca_uart_host_t * hal_data, ATCAIfaceCfg tty.c_cc[VTIME] = 5; /* Convert baudrate to posix/linux format */ - rate = hal_uart_convert_baudrate(cfg->atcauart.baud); + rate = hal_uart_convert_baudrate(ATCA_IFACECFG_VALUE(cfg, atcauart.baud)); cfsetispeed(&tty, rate); cfsetospeed(&tty, rate); /* set number of stopbits */ - if (1 < cfg->atcauart.stopbits) + if (1 < ATCA_IFACECFG_VALUE(cfg, atcauart.stopbits)) { /* Two stop bits */ tty.c_cflag |= CSTOPB; @@ -164,15 +164,15 @@ static ATCA_STATUS hal_uart_open_file(atca_uart_host_t * hal_data, ATCAIfaceCfg /* Set the transmission word size */ tty.c_cflag &= ~CSIZE; - tty.c_cflag |= hal_uart_convert_wordsize(cfg->atcauart.wordsize); + tty.c_cflag |= hal_uart_convert_wordsize(ATCA_IFACECFG_VALUE(cfg, atcauart.wordsize)); - if (0 == cfg->atcauart.parity) + if (0 == ATCA_IFACECFG_VALUE(cfg, atcauart.parity)) { /* Set Even Parity */ tty.c_cflag |= PARENB; tty.c_cflag &= ~PARODD; } - else if (1 == cfg->atcauart.parity) + else if (1 == ATCA_IFACECFG_VALUE(cfg, atcauart.parity)) { /* Set Odd Parity */ tty.c_cflag |= (PARENB | PARODD); @@ -232,7 +232,7 @@ ATCA_STATUS hal_uart_init(ATCAIface iface, ATCAIfaceCfg *cfg) else { (void)snprintf(hal_data->uart_file, sizeof(hal_data->uart_file) - 1, - "/dev/ttyS%d", (uint8_t)cfg->atcauart.port); + "/dev/ttyS%d", (uint8_t)ATCA_IFACECFG_VALUE(cfg, atcauart.port)); } iface->hal_data = hal_data; diff --git a/lib/hal/hal_swi_gpio.c b/lib/hal/hal_swi_gpio.c index 1662d8621..e87533c68 100644 --- a/lib/hal/hal_swi_gpio.c +++ b/lib/hal/hal_swi_gpio.c @@ -32,6 +32,10 @@ #define ATCA_HAL_SWI #endif +#if defined(ATCA_ECC204_SUPPORT) && (defined(ATCA_HAL_SWI_GPIO) || defined(ATCA_HAL_SWI_BB)) +#define ATCA_HAL_1WIRE +#endif + static ATCA_STATUS hal_swi_gpio_set_bit( ATCAIface iface, /**< [in] Device context */ uint8_t pin_state /**< [in] value to write */ @@ -48,7 +52,6 @@ static ATCA_STATUS hal_swi_gpio_read_bit( return iface->phy->halreceive(iface, 0, pin_state, NULL); } -#ifdef ATCA_HAL_1WIRE static ATCA_STATUS hal_swi_gpio_set_dir( ATCAIface iface, /**< [in] Device context */ uint8_t pin_dir /**< [in] Pin type input/output */ @@ -56,7 +59,6 @@ static ATCA_STATUS hal_swi_gpio_set_dir( { return iface->phy->halcontrol(iface, ATCA_HAL_CONTROL_DIRECTION, &pin_dir, sizeof(pin_dir)); } -#endif /** \brief Function to send logic bit 1 or 0 over GPIO using 1WIRE * @@ -419,13 +421,13 @@ static ATCA_STATUS device_discovery_1wire(ATCAIface iface) } /** \brief Function to read the data ACK for the transmitted byte - * \param[in] dev_addr 7 bit device address + * \param[in] dev_addr 8 bit device address * \param[in] oper indicates read or write operation * \return 8 bit device address for write or read operation */ static uint8_t get_slave_addr_1wire(uint8_t dev_addr, uint8_t oper) { - return (dev_addr << 1) | oper; + return dev_addr | oper; } /** \brief Function to check wake condition for 1WIRE diff --git a/lib/hal/hal_swi_uart.c b/lib/hal/hal_swi_uart.c index 352ce010b..910e2606f 100644 --- a/lib/hal/hal_swi_uart.c +++ b/lib/hal/hal_swi_uart.c @@ -43,7 +43,8 @@ ATCA_STATUS hal_swi_init(ATCAIface iface, ATCAIfaceCfg *cfg) { - + ((void)iface); + ((void)cfg); return ATCA_SUCCESS; } @@ -54,6 +55,7 @@ ATCA_STATUS hal_swi_init(ATCAIface iface, ATCAIfaceCfg *cfg) ATCA_STATUS hal_swi_post_init(ATCAIface iface) { + ((void)iface); return ATCA_SUCCESS; } @@ -294,7 +296,7 @@ ATCA_STATUS hal_swi_control(ATCAIface iface, uint8_t option, void* param, size_t ATCA_STATUS hal_swi_release(void *hal_data) { - + ((void)hal_data); return ATCA_SUCCESS; } diff --git a/lib/hal/kit_protocol.c b/lib/hal/kit_protocol.c index 798346faf..2d159f532 100644 --- a/lib/hal/kit_protocol.c +++ b/lib/hal/kit_protocol.c @@ -80,6 +80,8 @@ const char * kit_id_from_devtype(ATCADeviceType devtype) return "TA100"; case ECC204: return "ECC204"; + case TA010: + return "TA010"; default: return "unknown"; } @@ -145,7 +147,7 @@ ATCA_STATUS kit_phy_send(ATCAIface iface, uint8_t* txdata, int txlength) if (ATCA_HID_IFACE == iface->mIfaceCFG->iface_type) { #ifdef ATCA_HAL_KIT_HID - packetsize = (int)cfg->atcahid.packetsize; + packetsize = (int)ATCA_IFACECFG_VALUE(cfg, atcahid.packetsize); #endif } else if (ATCA_UART_IFACE == iface->mIfaceCFG->iface_type) @@ -315,14 +317,14 @@ ATCA_STATUS kit_init(ATCAIface iface, ATCAIfaceCfg* cfg) { #ifdef ATCA_HAL_KIT_HID case ATCA_HID_IFACE: - iface_type = iface->mIfaceCFG->atcahid.dev_interface; - dev_identity = iface->mIfaceCFG->atcahid.dev_identity; + iface_type = ATCA_IFACECFG_VALUE(iface->mIfaceCFG, atcahid.dev_interface); + dev_identity = ATCA_IFACECFG_VALUE(iface->mIfaceCFG, atcahid.dev_identity); break; #endif #ifdef ATCA_HAL_KIT_UART case ATCA_UART_IFACE: - iface_type = iface->mIfaceCFG->atcauart.dev_interface; - dev_identity = iface->mIfaceCFG->atcauart.dev_identity; + iface_type = ATCA_IFACECFG_VALUE(iface->mIfaceCFG, atcauart.dev_interface); + dev_identity = ATCA_IFACECFG_VALUE(iface->mIfaceCFG, atcauart.dev_identity); break; #endif default: @@ -535,7 +537,6 @@ ATCA_STATUS kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int int nkitbuf; char* pkitbuf = NULL; const char *target; - uint8_t* kit_data = txdata; // Check the pointers if (txdata == NULL) @@ -543,16 +544,6 @@ ATCA_STATUS kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int return ATCA_BAD_PARAM; } - if (0xFF != word_address) - { - txdata[0] = word_address; - txlength++; - } - else - { - kit_data = &txdata[1]; - } - do { // Wrap in kit protocol @@ -562,7 +553,7 @@ ATCA_STATUS kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int target = kit_id_from_devtype(iface->mIfaceCFG->devtype); - if (ATCA_SUCCESS != (status = kit_wrap_cmd(kit_data, txlength, pkitbuf, &nkitbuf, target[0]))) + if (ATCA_SUCCESS != (status = kit_wrap_cmd(txdata, txlength, pkitbuf, &nkitbuf, target))) { status = ATCA_GEN_FAIL; break; @@ -580,7 +571,7 @@ ATCA_STATUS kit_send(ATCAIface iface, uint8_t word_address, uint8_t* txdata, int } // Receive the reply to send "00()\n" - if ('T' == target[0]) + if (strncmp(target, "TA100", 3) == 0) { status = kit_ta_receive_send_rsp(iface); } @@ -621,7 +612,7 @@ ATCA_STATUS kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, } target = kit_id_from_devtype(iface->mIfaceCFG->devtype); - if ('T' == target[0]) + if (strncmp(target, "TA100", 3) == 0) { // Send word address byte to kit protocol to receive a response from device if (ATCA_SUCCESS != (status = kit_ta_send_to_receive(iface, word_address, rxsize))) @@ -631,7 +622,10 @@ ATCA_STATUS kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, } // Receive the response bytes - nkitbuf = (*rxsize * 2) + KIT_RX_WRAP_SIZE; + //! For large data(greater than 1020 bytes) + //! nkitbuf in Kit_phy_receive alligns to 64 byte due to USB HID + //! so alligned with 64 multiples for buffer size + nkitbuf = (((((*rxsize * 2) + KIT_RX_WRAP_SIZE))/64)+1)*64; pkitbuf = hal_malloc(nkitbuf); memset(pkitbuf, 0, nkitbuf); @@ -811,16 +805,15 @@ ATCA_STATUS kit_sleep(ATCAIface iface) * \param[in,out] nkitcmd As input, the size of the pkitcmd buffer. * As output, the number of bytes returned in the * pkitcmd buffer. - * \param[in] target Target char to use 's' for SHA devices, 'e' for ECC - devices. + * \param[in] target Device type * \return ATCA_SUCCESS on success, otherwise an error code. */ -ATCA_STATUS kit_wrap_cmd(const uint8_t* txdata, int txlen, char* pkitcmd, int* nkitcmd, char target) +ATCA_STATUS kit_wrap_cmd(const uint8_t* txdata, int txlen, char* pkitcmd, int* nkitcmd,const char* target) { ATCA_STATUS status = ATCA_SUCCESS; char* ta_cmdpre = "t:send("; char* ca_cmdpre = "d:t("; - char* cmdpre = (target == 'T') ? ta_cmdpre : ca_cmdpre; + char* cmdpre = strncmp(target, "TA100", 3) ? ca_cmdpre : ta_cmdpre; char cmdpost[] = ")\n"; size_t cmdAsciiLen = txlen * 2; size_t cmdlen = txlen * 2 + strlen(cmdpre) + sizeof(cmdpost) - 1; @@ -845,7 +838,7 @@ ATCA_STATUS kit_wrap_cmd(const uint8_t* txdata, int txlen, char* pkitcmd, int* n memcpy(&pkitcmd[cpyindex], cmdpre, cpylen); cpyindex += cpylen; - pkitcmd[0] = target; + pkitcmd[0] = target[0]; // Copy the ascii binary bytes if (ATCA_SUCCESS != (status = atcab_bin2hex_(txdata, txlen, &pkitcmd[cpyindex], &cmdAsciiLen, false, false, true))) diff --git a/lib/hal/kit_protocol.h b/lib/hal/kit_protocol.h index c4485376b..b89e3a690 100644 --- a/lib/hal/kit_protocol.h +++ b/lib/hal/kit_protocol.h @@ -59,7 +59,7 @@ ATCA_STATUS kit_receive(ATCAIface iface, uint8_t word_address, uint8_t* rxdata, ATCA_STATUS kit_control(ATCAIface iface, uint8_t option, void* param, size_t paramlen); ATCA_STATUS kit_release(void* hal_data); -ATCA_STATUS kit_wrap_cmd(const uint8_t* txdata, int txlength, char* pkitbuf, int* nkitbuf, char target); +ATCA_STATUS kit_wrap_cmd(const uint8_t* txdata, int txlength, char* pkitbuf, int* nkitbuf,const char* target); ATCA_STATUS kit_parse_rsp(const char* pkitbuf, int nkitbuf, uint8_t* kitstatus, uint8_t* rxdata, int* nrxdata); ATCA_STATUS kit_wake(ATCAIface iface); diff --git a/lib/host/atca_host.c b/lib/host/atca_host.c index 2f60acd17..6e40a2a45 100644 --- a/lib/host/atca_host.c +++ b/lib/host/atca_host.c @@ -35,6 +35,7 @@ * \param[in,out] param pointer to parameter structure * \return pointer to command buffer byte that was copied last */ +#if ATCAH_INCLUDE_DATA uint8_t *atcah_include_data(struct atca_include_data_in_out *param) { if (param->mode & MAC_MODE_INCLUDE_OTP_88) @@ -89,11 +90,13 @@ uint8_t *atcah_include_data(struct atca_include_data_in_out *param) return param->p_temp; } +#endif /* ATCAH_INCLUDE_DATA */ /** \brief This function calculates host side nonce with the parameters passed. * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_NONCE ATCA_STATUS atcah_nonce(struct atca_nonce_in_out *param) { uint8_t temporary[ATCA_MSG_SIZE_NONCE]; @@ -212,6 +215,7 @@ ATCA_STATUS atcah_nonce(struct atca_nonce_in_out *param) return ATCA_SUCCESS; } +#endif /* atcah_nonce */ /** \brief Decrypt data that's been encrypted by the IO protection key. * The ECDH and KDF commands on the ATECC608 are the only ones that @@ -221,6 +225,7 @@ ATCA_STATUS atcah_nonce(struct atca_nonce_in_out *param) * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_IO_DECRYPT ATCA_STATUS atcah_io_decrypt(struct atca_io_decrypt_in_out *param) { atcac_sha2_256_ctx ctx; @@ -254,7 +259,7 @@ ATCA_STATUS atcah_io_decrypt(struct atca_io_decrypt_in_out *param) return ATCA_SUCCESS; } - +#endif /* ATCAH_IO_DECRYPT */ /** \brief Calculate the expected MAC on the host side for the Verify command. * @@ -262,6 +267,7 @@ ATCA_STATUS atcah_io_decrypt(struct atca_io_decrypt_in_out *param) * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_VERIFY_MAC ATCA_STATUS atcah_verify_mac(atca_verify_mac_in_out_t *param) { uint8_t verify_mode = (param->mode & VERIFY_MODE_MASK); @@ -341,6 +347,7 @@ ATCA_STATUS atcah_verify_mac(atca_verify_mac_in_out_t *param) return ATCA_SUCCESS; } +#endif /** \brief Encrypts the digest for the SecureBoot command when using the * encrypted digest / validating mac option. @@ -349,6 +356,7 @@ ATCA_STATUS atcah_verify_mac(atca_verify_mac_in_out_t *param) * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_SECUREBOOT_ENC ATCA_STATUS atcah_secureboot_enc(atca_secureboot_enc_in_out_t* param) { atcac_sha2_256_ctx ctx; @@ -374,6 +382,7 @@ ATCA_STATUS atcah_secureboot_enc(atca_secureboot_enc_in_out_t* param) return ATCA_SUCCESS; } +#endif /* ATCAH_SECUREBOOT_ENC */ /** \brief Calculates the expected MAC returned from the SecureBoot command * when verification is a success. @@ -385,6 +394,7 @@ ATCA_STATUS atcah_secureboot_enc(atca_secureboot_enc_in_out_t* param) * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_SECUREBOOT_MAC ATCA_STATUS atcah_secureboot_mac(atca_secureboot_mac_in_out_t *param) { atcac_sha2_256_ctx ctx; @@ -424,7 +434,7 @@ ATCA_STATUS atcah_secureboot_mac(atca_secureboot_mac_in_out_t *param) return ATCA_SUCCESS; } - +#endif /* ATCAH_SECUREBOOT_MAC */ /** \brief This function generates an SHA-256 digest (MAC) of a key, challenge, and other information. @@ -435,6 +445,7 @@ ATCA_STATUS atcah_secureboot_mac(atca_secureboot_mac_in_out_t *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_MAC ATCA_STATUS atcah_mac(struct atca_mac_in_out *param) { uint8_t temporary[ATCA_MSG_SIZE_MAC]; @@ -508,7 +519,7 @@ ATCA_STATUS atcah_mac(struct atca_mac_in_out *param) return ATCA_SUCCESS; } - +#endif /* ATCAH_MAC */ @@ -516,6 +527,7 @@ ATCA_STATUS atcah_mac(struct atca_mac_in_out *param) * \param[in,out] param Input and output parameters * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_CHECK_MAC ATCA_STATUS atcah_check_mac(struct atca_check_mac_in_out *param) { uint8_t msg[ATCA_MSG_SIZE_MAC]; @@ -610,7 +622,7 @@ ATCA_STATUS atcah_check_mac(struct atca_check_mac_in_out *param) return ATCA_SUCCESS; } - +#endif /* ATCAH_CHECK_MAC */ /** \brief This function generates an HMAC / SHA-256 hash of a key and other information. @@ -620,6 +632,7 @@ ATCA_STATUS atcah_check_mac(struct atca_check_mac_in_out *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_HMAC ATCA_STATUS atcah_hmac(struct atca_hmac_in_out *param) { // Local Variables @@ -716,7 +729,7 @@ ATCA_STATUS atcah_hmac(struct atca_hmac_in_out *param) return ATCA_SUCCESS; } - +#endif /* ATCAH_HMAC */ /** \brief This function combines the current TempKey with a stored value. @@ -731,6 +744,7 @@ ATCA_STATUS atcah_hmac(struct atca_hmac_in_out *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_GENDIG ATCA_STATUS atcah_gen_dig(struct atca_gen_dig_in_out *param) { uint8_t temporary[ATCA_MSG_SIZE_GEN_DIG]; @@ -903,11 +917,13 @@ ATCA_STATUS atcah_gen_dig(struct atca_gen_dig_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_GENDIG */ /** \brief This function generates mac with session key with a plain text. * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_GEN_MAC ATCA_STATUS atcah_gen_mac(struct atca_gen_dig_in_out *param) { uint8_t temporary[ATCA_MSG_SIZE_GEN_DIG]; @@ -980,6 +996,7 @@ ATCA_STATUS atcah_gen_mac(struct atca_gen_dig_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_GEN_MAC */ /** \brief This function calculates the input MAC for the Write command. @@ -988,6 +1005,7 @@ ATCA_STATUS atcah_gen_mac(struct atca_gen_dig_in_out *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_WRITE_AUTH_MAC ATCA_STATUS atcah_write_auth_mac(struct atca_write_mac_in_out *param) { uint8_t mac_input[ATCA_MSG_SIZE_ENCRYPT_MAC]; @@ -1055,6 +1073,7 @@ ATCA_STATUS atcah_write_auth_mac(struct atca_write_mac_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_WRITE_AUTH_MAC */ /** \brief This function calculates the input MAC for the PrivWrite command. @@ -1063,6 +1082,7 @@ ATCA_STATUS atcah_write_auth_mac(struct atca_write_mac_in_out *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_PRIVWRITE_AUTH_MAC ATCA_STATUS atcah_privwrite_auth_mac(struct atca_write_mac_in_out *param) { uint8_t mac_input[ATCA_MSG_SIZE_PRIVWRITE_MAC]; @@ -1145,6 +1165,7 @@ ATCA_STATUS atcah_privwrite_auth_mac(struct atca_write_mac_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_PRIVWRITE_AUTH_MAC */ /** \brief This function derives a key with a key and TempKey. @@ -1160,6 +1181,7 @@ ATCA_STATUS atcah_privwrite_auth_mac(struct atca_write_mac_in_out *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_DERIVE_KEY ATCA_STATUS atcah_derive_key(struct atca_derive_key_in_out *param) { uint8_t temporary[ATCA_MSG_SIZE_DERIVE_KEY]; @@ -1226,7 +1248,7 @@ ATCA_STATUS atcah_derive_key(struct atca_derive_key_in_out *param) return ATCA_SUCCESS; } - +#endif /* ATCAH_DERIVE_KEY */ /** \brief This function calculates the input MAC for a DeriveKey command. @@ -1235,6 +1257,7 @@ ATCA_STATUS atcah_derive_key(struct atca_derive_key_in_out *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_DERIVE_KEY_MAC ATCA_STATUS atcah_derive_key_mac(struct atca_derive_key_mac_in_out *param) { uint8_t temporary[ATCA_MSG_SIZE_DERIVE_KEY_MAC]; @@ -1276,7 +1299,7 @@ ATCA_STATUS atcah_derive_key_mac(struct atca_derive_key_mac_in_out *param) return ATCA_SUCCESS; } - +#endif /* ATCAH_DERIVE_KEY_MAC */ /** \brief This function decrypts 32-byte encrypted data received with the Read command. @@ -1294,6 +1317,7 @@ ATCA_STATUS atcah_derive_key_mac(struct atca_derive_key_mac_in_out *param) * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_DECRYPT ATCA_STATUS atcah_decrypt(struct atca_decrypt_in_out *param) { uint8_t i; @@ -1334,6 +1358,7 @@ ATCA_STATUS atcah_decrypt(struct atca_decrypt_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_DECRYPT */ /** \brief This function creates a SHA256 digest on a little-endian system. * @@ -1342,10 +1367,12 @@ ATCA_STATUS atcah_decrypt(struct atca_decrypt_in_out *param) * \param[out] digest SHA256 of message * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_SHA256 ATCA_STATUS atcah_sha256(int32_t len, const uint8_t *message, uint8_t *digest) { return (ATCA_STATUS)atcac_sw_sha2_256(message, len, digest); } +#endif /* ATCAH_SHA256 */ /** \brief Calculate the PubKey digest created by GenKey and saved to TempKey. * @@ -1354,6 +1381,7 @@ ATCA_STATUS atcah_sha256(int32_t len, const uint8_t *message, uint8_t *digest) * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_GEN_KEY_MSG ATCA_STATUS atcah_gen_key_msg(struct atca_gen_key_in_out *param) { uint8_t msg[128]; @@ -1406,6 +1434,7 @@ ATCA_STATUS atcah_gen_key_msg(struct atca_gen_key_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_GEN_KEY_MSG */ /** \brief Populate the slot_config, key_config, and is_slot_locked fields in * the atca_sign_internal_in_out structure from the provided config @@ -1423,6 +1452,7 @@ ATCA_STATUS atcah_gen_key_msg(struct atca_gen_key_in_out *param) * \param[in] config Full 128 byte config zone for the device. * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_CONFIG_TO_SIGN_INTERNAL ATCA_STATUS atcah_config_to_sign_internal(ATCADeviceType device_type, struct atca_sign_internal_in_out *param, const uint8_t* config) { const uint8_t* value = NULL; @@ -1459,6 +1489,7 @@ ATCA_STATUS atcah_config_to_sign_internal(ATCADeviceType device_type, struct atc return ATCA_SUCCESS; } +#endif /* ATCAH_CONFIG_TO_SIGN_INTERNAL */ /** \brief Builds the full message that would be signed by the Sign(Internal) * command. @@ -1472,6 +1503,7 @@ ATCA_STATUS atcah_config_to_sign_internal(ATCADeviceType device_type, struct atc * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_SIGN_INTERNAL_MSG ATCA_STATUS atcah_sign_internal_msg(ATCADeviceType device_type, struct atca_sign_internal_in_out *param) { uint8_t msg[55]; @@ -1548,6 +1580,7 @@ ATCA_STATUS atcah_sign_internal_msg(ATCADeviceType device_type, struct atca_sign return ATCA_SUCCESS; } } +#endif /* ATCAH_SIGN_INTERNAL_MSG */ /** \brief Builds the counter match value that needs to be stored in a slot. * @@ -1559,6 +1592,7 @@ ATCA_STATUS atcah_sign_internal_msg(ATCADeviceType device_type, struct atca_sign * * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_ENCODE_COUNTER_MATCH ATCA_STATUS atcah_encode_counter_match(uint32_t counter_value, uint8_t * counter_match_value) { if ((counter_value > COUNTER_MAX_VALUE) || (counter_value % 32 != 0) || (counter_match_value == NULL)) @@ -1577,6 +1611,7 @@ ATCA_STATUS atcah_encode_counter_match(uint32_t counter_value, uint8_t * counter return ATCA_SUCCESS; } +#endif /* ATCAH_ENCODE_COUNTER_MATCAH */ /** \brief This function calculates the input MAC for the ECC204 Write command. @@ -1585,6 +1620,7 @@ ATCA_STATUS atcah_encode_counter_match(uint32_t counter_value, uint8_t * counter * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_WRITE_AUTH_MAC ATCA_STATUS atcah_ecc204_write_auth_mac(struct atca_write_mac_in_out *param) { uint8_t mac_input[ATCA_MSG_SIZE_ENCRYPT_MAC]; @@ -1643,12 +1679,14 @@ ATCA_STATUS atcah_ecc204_write_auth_mac(struct atca_write_mac_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_WRITE_AUTH_MAC */ /** \brief This function calculates the session key for the ECC204. * * \param[in,out] param pointer to parameter structure * \return ATCA_SUCCESS on success, otherwise an error code. */ +#if ATCAH_GEN_SESSION_KEY ATCA_STATUS atcah_gen_session_key(struct atca_session_key_in_out *param) { uint8_t session_key_input[ATCA_MSG_SIZE_SESSION_KEY]; @@ -1694,5 +1732,6 @@ ATCA_STATUS atcah_gen_session_key(struct atca_session_key_in_out *param) return ATCA_SUCCESS; } +#endif /* ATCAH_GEN_SESSION_KEY */ #endif diff --git a/lib/host/atca_host.h b/lib/host/atca_host.h index 2cfcc95f2..4860f8fd5 100644 --- a/lib/host/atca_host.h +++ b/lib/host/atca_host.h @@ -33,6 +33,8 @@ #include "cryptoauthlib.h" // contains definitions used by chip and these routines #include "calib/calib_basic.h" +#include "atca_host_config_check.h" + /** \defgroup atcah Host side crypto methods (atcah_) * * \brief diff --git a/lib/host/atca_host_config_check.h b/lib/host/atca_host_config_check.h new file mode 100644 index 000000000..0dc797130 --- /dev/null +++ b/lib/host/atca_host_config_check.h @@ -0,0 +1,337 @@ +/** + * \file + * \brief Consistency checks for configuration options + * + * \copyright (c) 2015-2021 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef ATCA_HOST_CONFIG_CHECK_H +#define ATCA_HOST_CONFIG_CHECK_H + + /** \def ATCAH_INCLUDE_DATA + * + * Requires: ATCAH_INCLUDE_DATA + * + * Supported API's: atcah_include_data + * + * Enable ATCAH_INCLUDE_DATA to copy otp and sn data into a command buffer + **/ +#ifndef ATCAH_INCLUDE_DATA +#define ATCAH_INCLUDE_DATA (DEFAULT_ENABLED) +#endif + +/** \def ATCAH_NONCE + * + * Requires: ATCAH_NONCE + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_nonce + * + * Enable ATCAH_NONCE to calculate host side nonce with the parameters passed + **/ +#ifndef ATCAH_NONCE +#define ATCAH_NONCE (DEFAULT_ENABLED) +#endif + +/** \def ATCAH_IO_DECRYPT + * + * Requires: ATCAH_IO_DECRYPT + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_io_decrypt + * + * Enable ATCAH_IO_DECRYPT to decrypt data that's been encrypted by the IO protection key.The ECDH and KDF commands on the + * ATECC608 are the only ones that support this operation + **/ +#ifndef ATCAH_IO_DECRYPT +#define ATCAH_IO_DECRYPT (DEFAULT_ENABLED) +#endif + +/** \def ATCAH_VERIFY_MAC + * + * Requires: ATCAH_VERIFY_MAC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_verify_mac + * + * Enable ATCAH_VERIFY_MAC to calculate the expected MAC on the host side for the Verify command + **/ +#ifndef ATCAH_VERIFY_MAC +#define ATCAH_VERIFY_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_SECUREBOOT_ENC + * + * Requires: ATCAH_SECUREBOOT_ENC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_secureboot_enc + * + * Enable ATCAH_SECUREBOOT_ENC to encrypt the digest for the SecureBoot command when using the encrypted digest / validating mac option + **/ +#ifndef ATCAH_SECUREBOOT_ENC +#define ATCAH_SECUREBOOT_ENC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_SECUREBOOT_MAC + * + * Requires: ATCAH_SECUREBOOT_MAC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_secureboot_mac + * + * Enable ATCAH_SECUREBOOT_MAC to calculates the expected MAC returned from the SecureBoot command when verification is a success + **/ +#ifndef ATCAH_SECUREBOOT_MAC +#define ATCAH_SECUREBOOT_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_MAC + * + * Requires: ATCAH_MAC + * ATCAC_SW_SHA2_256 + * ATCAH_INCLUDE_DATA + * + * Supported API's: atcah_mac + * + * Enable ATCAH_MAC to generate an SHA-256 digest (MAC) of a key, challenge, and other information + **/ +#ifndef ATCAH_MAC +#define ATCAH_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_CHECK_MAC + * + * Requires: ATCAH_CHECK_MAC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_check_mac + * + * Enable ATCAH_CHECK_MAC to perform the checkmac operation to generate client response on the host side + **/ +#ifndef ATCAH_CHECK_MAC +#define ATCAH_CHECK_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_HMAC + * + * Requires: ATCAH_HMAC + * ATCAC_SW_SHA2_256 + * ATCAH_INCLUDE_DATA + * + * Supported API's: atcah_hmac + * + * Enable ATCAH_HMAC to generate an HMAC / SHA-256 hash of a key and other information + **/ +#ifndef ATCAH_HMAC +#define ATCAH_HMAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_GENDIG + * + * Requires: ATCAH_GENDIG + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_gen_dig + * + * Enable ATCAH_GENDIG to combine the current TempKey with a stored value + **/ +#ifndef ATCAH_GENDIG +#define ATCAH_GENDIG (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_GEN_MAC + * + * Requires: ATCAH_GEN_MAC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_gen_mac + * + * Enable ATCAH_GEN_MAC to generate mac with session key with a plain text + **/ +#ifndef ATCAH_GEN_MAC +#define ATCAH_GEN_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_WRITE_AUTH_MAC + * + * Requires: ATCAH_WRITE_AUTH_MAC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_write_auth_mac + * ECC204 specific API's: atcah_ecc204_write_auth_mac + * + * Enable ATCAH_WRITE_AUTH_MAC to calculate the input MAC for the Write command + **/ +#ifndef ATCAH_WRITE_AUTH_MAC +#define ATCAH_WRITE_AUTH_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_PRIVWRITE_AUTH_MAC + * + * Requires: ATCAH_PRIVWRITE_AUTH_MAC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_privwrite_auth_mac + * + * Enable ATCAH_PRIVWRITE_AUTH_MAC to calculate the input MAC for the PrivWrite command + **/ +#ifndef ATCAH_PRIVWRITE_AUTH_MAC +#define ATCAH_PRIVWRITE_AUTH_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_DERIVE_KEY + * + * Requires: ATCAH_DERIVE_KEY + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_derive_key + * + * Enable ATCAH_DERIVE_KEY to derive a key with a key and TempKey + **/ +#ifndef ATCAH_DERIVE_KEY +#define ATCAH_DERIVE_KEY (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_DERIVE_KEY_MAC + * + * Requires: ATCAH_DERIVE_KEY_MAC + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_derive_key_mac + * + * Enable ATCAH_DERIVE_KEY_MAC to calculate the input MAC for a DeriveKey command + **/ +#ifndef ATCAH_DERIVE_KEY_MAC +#define ATCAH_DERIVE_KEY_MAC (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_DECRYPT + * + * Requires: ATCAH_DECRYPT + * + * Supported API's: atcah_decrypt + * + * Enable ATCAH_DECRYPT to decrypt 32-byte encrypted data received with the Read command + **/ +#ifndef ATCAH_DECRYPT +#define ATCAH_DECRYPT (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_SHA256 + * + * Requires: ATCAH_SHA256 + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_sha256 + * + * Enable ATCAH_SHA256 to create a SHA256 digest on a little-endian system + **/ +#ifndef ATCAH_SHA256 +#define ATCAH_SHA256 (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_GEN_KEY_MSG + * + * Requires: ATCAH_SHA256 + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_gen_key_msg + * + * Enable ATCAH_GEN_KEY_MSG to calculate the PubKey digest created by GenKey and saved to TempKey + **/ +#ifndef ATCAH_GEN_KEY_MSG +#define ATCAH_GEN_KEY_MSG (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_CONFIG_TO_SIGN_INTERNAL + * + * Requires: ATCAH_CONFIG_TO_SIGN_INTERNAL + * + * Supported API's: atcah_config_to_sign_internal + * + * Enable ATCAH_CONFIG_TO_SIGN_INTERNAL to populate the slot_config, key_config, and is_slot_locked fields in the + * atca_sign_internal_in_out structure from the provided config zone + **/ +#ifndef ATCAH_CONFIG_TO_SIGN_INTERNAL +#define ATCAH_CONFIG_TO_SIGN_INTERNAL (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_SIGN_INTERNAL_MSG + * + * Requires: ATCAH_SIGN_INTERNAL_MSG + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_sign_internal_msg + * + * Enable ATCAH_SIGN_INTERNAL_MSG to build the full message that would be signed by the Sign(Internal) command + **/ +#ifndef ATCAH_SIGN_INTERNAL_MSG +#define ATCAH_SIGN_INTERNAL_MSG (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_ENCODE_COUNTER_MATCH + * + * Requires: ATCAH_ENCODE_COUNTER_MATCH + * + * Supported API's: atcah_encode_counter_match + * + * Enable ATCAH_ENCODE_COUNTER_MATCH to build the counter match value that needs to be stored in a slot + **/ +#ifndef ATCAH_ENCODE_COUNTER_MATCH +#define ATCAH_ENCODE_COUNTER_MATCH (DEFAULT_ENABLED) +#endif + + /** \def ATCAH_GEN_SESSION_KEY + * + * Requires: ATCAH_GEN_SESSION_KEY + * ATCAC_SW_SHA2_256 + * + * Supported API's: atcah_gen_Session_key + * + * Enable ATCAH_GEN_SESSION_KEY to calculate the session key for the ECC204 + **/ +#ifndef ATCAH_GEN_SESSION_KEY +#define ATCAH_GEN_SESSION_KEY (DEFAULT_ENABLED) +#endif + +/* ATCA CRYPTO REQUIREMENTS */ + +#ifndef ATCAC_SW_SHA2_256 +#define ATCAC_SW_SHA2_256 (DEFAULT_ENABLED) +#endif + +/* ATCA_HOST_CHECKS */ + +#if !ATCAC_SW_SHA2_256 && (ATCAH_NONCE || ATCAH_IO_DECRYPT || ATCAH_VERIFY_MAC || ATCAH_SECUREBOOT_ENC || \ + ATCAH_SECUREBOOT_MAC || ATCAH_MAC || ATCAH_CHECK_MAC || ATCAH_HMAC || ATCAH_GENDIG || ATCAH_GEN_MAC || \ + ATCAH_WRITE_AUTH_MAC || ATCAH_PRIVWRITE_AUTH_MAC || ATCAH_DERIVE_KEY || ATCAH_DERIVE_KEY_MAC || \ + ATCAH_SHA256 || ATCAH_GEN_KEY_MSG || ATCAH_SIGN_INTERNAL_MSG || ATCAH_GEN_SESSION_KEY) +#define ATCAC_SW_SHA2_256 (DEFAULT_ENABLED) +#endif + +#if (ATCAH_MAC || ATCAH_HMAC) && !ATCAH_INCLUDE_DATA +#define ATCAH_INCLUDE_DATA (DEFAULT_ENABLED) +#endif + +#endif /* ATCA_HOST_CONFIG_CHECK_H */ diff --git a/lib/jwt/atca_jwt.c b/lib/jwt/atca_jwt.c index 378c8111d..ce1ab201a 100644 --- a/lib/jwt/atca_jwt.c +++ b/lib/jwt/atca_jwt.c @@ -279,6 +279,7 @@ ATCA_STATUS atca_jwt_add_claim_numeric( } } +#if ATCA_HOSTLIB_EN || CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN /** * \brief Verifies the signature of a jwt using the provided public key */ @@ -330,12 +331,34 @@ ATCA_STATUS atca_jwt_verify( break; } +#if CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN /* Do a signature verification using the device */ if (ATCA_SUCCESS != (status = atcab_verify_extern(digest, signature, pubkey, &verified))) { break; } +#elif ATCA_HOSTLIB_EN + atcac_pk_ctx pkey_ctx; + + /* Initialize the key using the provided X,Y cordinantes */ + if(ATCA_SUCCESS != (status = atcac_pk_init(&pkey_ctx, pubkey, + sizeof(pubkey), 0, true))) + { + break; + } + + /* Perform the verification */ + if(ATCA_SUCCESS == (status = atcac_pk_verify(&pkey_ctx, digest, + sizeof(digest), + signature, sizeof(signature)))) + { + verified = true; + } + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); +#endif if (!verified) { @@ -346,3 +369,4 @@ ATCA_STATUS atca_jwt_verify( return status; } +#endif diff --git a/lib/jwt/atca_jwt.h b/lib/jwt/atca_jwt.h index d3608e5af..7f71c4f45 100644 --- a/lib/jwt/atca_jwt.h +++ b/lib/jwt/atca_jwt.h @@ -51,7 +51,10 @@ ATCA_STATUS atca_jwt_add_claim_string(atca_jwt_t* jwt, const char* claim, const ATCA_STATUS atca_jwt_add_claim_numeric(atca_jwt_t* jwt, const char* claim, int32_t value); ATCA_STATUS atca_jwt_finalize(atca_jwt_t* jwt, uint16_t key_id); void atca_jwt_check_payload_start(atca_jwt_t* jwt); + +#if ATCA_HOSTLIB_EN || CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN ATCA_STATUS atca_jwt_verify(const char* buf, uint16_t buflen, const uint8_t* pubkey); +#endif /** @} */ #ifdef __cplusplus diff --git a/lib/mbedtls/atca_mbedtls_wrap.c b/lib/mbedtls/atca_mbedtls_wrap.c index 1e436c4c7..cda552814 100644 --- a/lib/mbedtls/atca_mbedtls_wrap.c +++ b/lib/mbedtls/atca_mbedtls_wrap.c @@ -562,11 +562,11 @@ ATCA_STATUS atcac_sha256_hmac_finish( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_init( - atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ - uint8_t* buf, /**< [in] buffer containing a pem encoded key */ - size_t buflen, /**< [in] length of the input buffer */ - uint8_t key_type, - bool pubkey /**< [in] buffer is a public key */ + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + const uint8_t* buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + uint8_t key_type, + bool pubkey /**< [in] buffer is a public key */ ) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -623,10 +623,10 @@ ATCA_STATUS atcac_pk_init( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_init_pem( - atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ - uint8_t* buf, /**< [in] buffer containing a pem encoded key */ - size_t buflen, /**< [in] length of the input buffer */ - bool pubkey /**< [in] buffer is a public key */ + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + const uint8_t* buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + bool pubkey /**< [in] buffer is a public key */ ) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -706,11 +706,11 @@ ATCA_STATUS atcac_pk_public( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_sign( - atcac_pk_ctx* ctx, - uint8_t* digest, - size_t dig_len, - uint8_t* signature, - size_t* sig_len + atcac_pk_ctx* ctx, + const uint8_t* digest, + size_t dig_len, + uint8_t* signature, + size_t* sig_len ) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -765,11 +765,11 @@ ATCA_STATUS atcac_pk_sign( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_verify( - atcac_pk_ctx* ctx, - uint8_t* digest, - size_t dig_len, - uint8_t* signature, - size_t sig_len + atcac_pk_ctx* ctx, + const uint8_t* digest, + size_t dig_len, + const uint8_t* signature, + size_t sig_len ) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -873,7 +873,7 @@ static int atca_mbedtls_eckey_verify(void *ctx, mbedtls_md_type_t md_alg, const unsigned char *hash, size_t hash_len, const unsigned char *sig, size_t sig_len) { -#ifdef MBEDTLS_ECDSA_VERIFY_ALT +#if defined(MBEDTLS_ECDSA_VERIFY_ALT) || !(CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN) return mbedtls_pk_info_from_type(MBEDTLS_PK_ECKEY)->verify_func(ctx, md_alg, hash, hash_len, sig, sig_len); #else int ret = -1; diff --git a/lib/openssl/atca_openssl_interface.c b/lib/openssl/atca_openssl_interface.c index 560ad70e3..4c2c14397 100644 --- a/lib/openssl/atca_openssl_interface.c +++ b/lib/openssl/atca_openssl_interface.c @@ -580,15 +580,17 @@ ATCA_STATUS atcac_sha256_hmac_finish( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_init( - atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ - uint8_t* buf, /**< [in] buffer containing a pem encoded key */ - size_t buflen, /**< [in] length of the input buffer */ - uint8_t key_type, - bool pubkey /**< [in] buffer is a public key */ + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + const uint8_t* buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + uint8_t key_type, + bool pubkey /**< [in] buffer is a public key */ ) { ATCA_STATUS status = ATCA_BAD_PARAM; + ((void)key_type); + if (ctx) { ctx->ptr = EVP_PKEY_new(); @@ -596,37 +598,38 @@ ATCA_STATUS atcac_pk_init( if (ctx->ptr) { int ret = EVP_PKEY_set_type((EVP_PKEY*)ctx->ptr, EVP_PKEY_EC); - if (0 < ret) { EC_KEY* ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + const EC_GROUP * ec_group = EC_KEY_get0_group(ec_key); + EC_POINT* ec_point = EC_POINT_new(ec_group); if (pubkey) { - /* Configure the public key */ - EC_POINT* ec_point = EC_POINT_new(EC_KEY_get0_group(ec_key)); - BIGNUM* x = BN_bin2bn(buf, 32, NULL); - BIGNUM* y = BN_bin2bn(&buf[32], 32, NULL); - - ret = EC_POINT_set_affine_coordinates(EC_KEY_get0_group(ec_key), ec_point, x, y, NULL); - - if (0 < ret) - { - ret = EC_KEY_set_public_key(ec_key, ec_point); - } - - EC_POINT_free(ec_point); - BN_free(x); + BIGNUM * x = BN_bin2bn(buf, 32, NULL); + BIGNUM * y = BN_bin2bn(&buf[32], 32, NULL); + ret = EC_POINT_set_affine_coordinates(ec_group, ec_point, x, y, NULL); BN_free(y); + BN_free(x); } else { /* Configure a private key */ BIGNUM* d = BN_bin2bn(buf, buflen, NULL); - ret = EC_KEY_set_private_key(ec_key, d); + if (1 == (ret = EC_KEY_set_private_key(ec_key, d))) + { + /* Generate the public key */ + ret = EC_POINT_mul(ec_group, ec_point, NULL, NULL, d, NULL); + } BN_free(d); } + if(1 == ret) + { + ret = EC_KEY_set_public_key(ec_key, ec_point); + } + EC_POINT_free(ec_point); + if (0 < ret) { ret = EVP_PKEY_set1_EC_KEY((EVP_PKEY*)ctx->ptr, ec_key); @@ -656,10 +659,10 @@ ATCA_STATUS atcac_pk_init( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_init_pem( - atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ - uint8_t * buf, /**< [in] buffer containing a pem encoded key */ - size_t buflen, /**< [in] length of the input buffer */ - bool pubkey /**< [in] buffer is a public key */ + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + const uint8_t * buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + bool pubkey /**< [in] buffer is a public key */ ) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -714,19 +717,25 @@ ATCA_STATUS atcac_pk_public( { ATCA_STATUS status = ATCA_BAD_PARAM; - if (ctx && buf && ctx->ptr) + if (ctx && ctx->ptr && buf && buflen && *buflen >= 64) { int ret = -1; if (EVP_PKEY_EC == EVP_PKEY_id((EVP_PKEY*)ctx->ptr)) { - unsigned char pbuf[65]; // UNCOMPRESSED format - unsigned char *out = pbuf; - - ret = i2o_ECPublicKey(EVP_PKEY_get0_EC_KEY((EVP_PKEY*)ctx->ptr), &out); + EC_KEY * ec_key = EVP_PKEY_get0_EC_KEY((EVP_PKEY*)ctx->ptr); + if (ec_key) + { + BIGNUM * x = BN_new(); + BIGNUM * y = BN_new(); - if (ret > 0) + if (1 == (ret = EC_POINT_get_affine_coordinates(EC_KEY_get0_group(ec_key), EC_KEY_get0_public_key(ec_key), x, y, NULL))) { - memcpy(buf, &pbuf[1], *buflen); + BN_bn2bin(x, buf); + BN_bn2bin(y, &buf[32]); + *buflen = 64; + } + BN_free(x); + BN_free(y); } } status = (ret > 0) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; @@ -739,11 +748,11 @@ ATCA_STATUS atcac_pk_public( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_sign( - atcac_pk_ctx* ctx, - uint8_t * digest, - size_t dig_len, - uint8_t* signature, - size_t* sig_len + atcac_pk_ctx* ctx, + const uint8_t * digest, + size_t dig_len, + uint8_t* signature, + size_t* sig_len ) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -806,11 +815,11 @@ ATCA_STATUS atcac_pk_sign( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_verify( - atcac_pk_ctx* ctx, - uint8_t* digest, - size_t dig_len, - uint8_t* signature, - size_t sig_len + atcac_pk_ctx* ctx, + const uint8_t* digest, + size_t dig_len, + const uint8_t* signature, + size_t sig_len ) { ATCA_STATUS status = ATCA_BAD_PARAM; diff --git a/lib/pkcs11/pkcs11_cert.c b/lib/pkcs11/pkcs11_cert.c index a590ed0d2..d2074bc02 100644 --- a/lib/pkcs11/pkcs11_cert.c +++ b/lib/pkcs11/pkcs11_cert.c @@ -42,10 +42,10 @@ /** * \defgroup pkcs11 Key (pkcs11_key_) @{ */ - +#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) static void pkcs11_cert_check_trust_data(pkcs11_object_ptr pObject) { -#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) + if (PKCS11_OBJECT_FLAG_TRUST_TYPE & pObject->flags && !pObject->data) { const atcacert_def_t * cert_def = NULL; @@ -63,13 +63,12 @@ static void pkcs11_cert_check_trust_data(pkcs11_object_ptr pObject) } } } -#endif } +#endif - +#if ATCA_CA_SUPPORT static CK_RV pkcs11_cert_load_ca(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) { -#if ATCA_CA_SUPPORT ATCA_STATUS status = ATCA_SUCCESS; if (pObject->data) @@ -129,15 +128,12 @@ static CK_RV pkcs11_cert_load_ca(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAt { return pkcs11_attrib_empty(NULL, pAttribute); } -#else - return CKR_GENERAL_ERROR; -#endif } +#endif - +#if ATCA_TA_SUPPORT static CK_RV pkcs11_cert_load_ta(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) { -#if ATCA_TA_SUPPORT uint8_t handle_info[TA_HANDLE_INFO_SIZE]; ATCA_STATUS status = talib_info_get_handle_info(atcab_get_device(), pObject->slot, handle_info); @@ -160,11 +156,8 @@ static CK_RV pkcs11_cert_load_ta(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAt return CKR_GENERAL_ERROR; } return CKR_OK; -#else - return CKR_GENERAL_ERROR; -#endif } - +#endif static CK_RV pkcs11_cert_load(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) { @@ -173,13 +166,16 @@ static CK_RV pkcs11_cert_load(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttri if (atcab_is_ca_device(dev_type)) { +#if ATCA_CA_SUPPORT ret = pkcs11_cert_load_ca(pObject, pAttribute); +#endif } else if (atcab_is_ta_device(dev_type)) { +#if ATCA_TA_SUPPORT ret = pkcs11_cert_load_ta(pObject, pAttribute); +#endif } - return ret; } @@ -189,20 +185,24 @@ CK_RV pkcs11_cert_get_encoded(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) if (obj_ptr) { +#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) pkcs11_cert_check_trust_data(obj_ptr); +#endif return pkcs11_cert_load(obj_ptr, pAttribute); } return CKR_ARGUMENTS_BAD; } +#if ATCA_CA_SUPPORT static CK_RV pkcs11_cert_get_type_ca(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pAttribute) { -#if ATCA_CA_SUPPORT CK_RV rv = CKR_ARGUMENTS_BAD; if (pObject) { +#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) pkcs11_cert_check_trust_data(pObject); +#endif if (pObject->data) { @@ -224,18 +224,20 @@ static CK_RV pkcs11_cert_get_type_ca(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR } return rv; -#else - return CKR_GENERAL_ERROR; -#endif } +#endif CK_RV pkcs11_cert_get_type(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { - CK_RV rv; + CK_RV rv = CKR_GENERAL_ERROR; if (atcab_is_ca_device(atcab_get_device_type())) { +#if ATCA_CA_SUPPORT rv = pkcs11_cert_get_type_ca(pObject, pAttribute); +#else + ((void)pObject); +#endif } else { @@ -253,7 +255,9 @@ CK_RV pkcs11_cert_get_subject(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) if (obj_ptr) { +#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) pkcs11_cert_check_trust_data(obj_ptr); +#endif if (obj_ptr->data) { @@ -313,7 +317,9 @@ CK_RV pkcs11_cert_get_subject_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr if (obj_ptr) { +#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) pkcs11_cert_check_trust_data(obj_ptr); +#endif if (obj_ptr->data) { @@ -349,13 +355,13 @@ CK_RV pkcs11_cert_get_subject_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr return CKR_ARGUMENTS_BAD; #else - return pkcs11_attrib_empty(NULL, pAttribute); + return pkcs11_attrib_empty(pObject, pAttribute); #endif } CK_RV pkcs11_cert_get_authority_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { - return pkcs11_attrib_empty(NULL, pAttribute); + return pkcs11_attrib_empty(pObject, pAttribute); } CK_RV pkcs11_cert_get_trusted_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) diff --git a/lib/pkcs11/pkcs11_config.c b/lib/pkcs11/pkcs11_config.c index 20d0816e0..7d57abb4c 100644 --- a/lib/pkcs11/pkcs11_config.c +++ b/lib/pkcs11/pkcs11_config.c @@ -25,14 +25,17 @@ * THIS SOFTWARE. */ +#include "cryptoauthlib.h" #include "pkcs11_config.h" #include "pkcs11_debug.h" -#include "cryptoauthlib.h" #include "pkcs11_slot.h" #include "pkcs11_object.h" #include "pkcs11_key.h" #include "pkcs11_cert.h" #include "pkcs11_os.h" +#include "pkcs11_util.h" + +#include #if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) CK_RV pkcs11_trust_load_objects(pkcs11_slot_ctx_ptr pSlot); @@ -174,6 +177,7 @@ static int pkcs11_config_parse_buffer(char* buffer, size_t len, int argc, char* switch (*s) { case '\n': + /* fallthrough */ case '\r': /* End the line*/ if (arg && !v && !comment) @@ -191,7 +195,9 @@ static int pkcs11_config_parse_buffer(char* buffer, size_t len, int argc, char* break; case '=': v = TRUE; + /* fallthrough */ case ' ': + /* fallthrough */ case '\t': *s = '\0'; arg = 0; @@ -222,7 +228,7 @@ static int pkcs11_config_parse_buffer(char* buffer, size_t len, int argc, char* return args; } -static void pkcs11_config_split_string(char* s, char splitter, int * argc, char* argv[]) +void pkcs11_config_split_string(char* s, char splitter, int * argc, char* argv[]) { char * e; int args = 1; @@ -292,6 +298,7 @@ static CK_RV pkcs11_config_parse_interface(pkcs11_slot_ctx_ptr slot_ctx, char* c int argc = 4; char * argv[4]; CK_RV rv = CKR_GENERAL_ERROR; + ATCAIfaceCfg * cfg = &slot_ctx->interface_config; pkcs11_config_split_string(cfgstr, ',', &argc, argv); @@ -303,22 +310,22 @@ static CK_RV pkcs11_config_parse_interface(pkcs11_slot_ctx_ptr slot_ctx, char* c if (!strcmp(argv[0], "i2c")) { #ifdef ATCA_HAL_I2C - slot_ctx->interface_config.iface_type = ATCA_I2C_IFACE; + cfg->iface_type = ATCA_I2C_IFACE; if (argc > 1) { #ifdef ATCA_ENABLE_DEPRECATED - slot_ctx->interface_config.atcai2c.slave_address = (uint8_t)strtol(argv[1], NULL, 16); + ATCA_IFACECFG_VALUE(cfg, atcai2c.slave_address) = (uint8_t)strtol(argv[1], NULL, 16); #else - slot_ctx->interface_config.atcai2c.address = (uint8_t)strtol(argv[1], NULL, 16); + ATCA_IFACECFG_VALUE(cfg, atcai2c.address) = (uint8_t)strtol(argv[1], NULL, 16); #endif } if (argc > 2) { - slot_ctx->interface_config.atcai2c.bus = (uint8_t)strtol(argv[2], NULL, 16); + ATCA_IFACECFG_VALUE(cfg, atcai2c.bus) = (uint8_t)strtol(argv[2], NULL, 16); } if (argc > 3) { - slot_ctx->interface_config.atcai2c.baud = (uint32_t)strtol(argv[3], NULL, 10); + ATCA_IFACECFG_VALUE(cfg, atcai2c.baud) = (uint32_t)strtol(argv[3], NULL, 10); } rv = CKR_OK; #endif @@ -326,29 +333,29 @@ static CK_RV pkcs11_config_parse_interface(pkcs11_slot_ctx_ptr slot_ctx, char* c else if (!strcmp(argv[0], "hid")) { #ifdef ATCA_HAL_KIT_HID - slot_ctx->interface_config.iface_type = ATCA_HID_IFACE; - slot_ctx->interface_config.atcahid.dev_interface = ATCA_KIT_AUTO_IFACE; - slot_ctx->interface_config.atcahid.vid = 0x03EB; - slot_ctx->interface_config.atcahid.pid = 0x2312; - slot_ctx->interface_config.atcahid.packetsize = 64; + cfg->iface_type = ATCA_HID_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcahid.dev_interface) = ATCA_KIT_AUTO_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcahid.vid) = 0x03EB; + ATCA_IFACECFG_VALUE(cfg, atcahid.pid) = 0x2312; + ATCA_IFACECFG_VALUE(cfg, atcahid.packetsize) = 64; if (argc > 1) { if (!strcmp(argv[1], "i2c")) { - slot_ctx->interface_config.atcahid.dev_interface = ATCA_KIT_I2C_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcahid.dev_interface) = ATCA_KIT_I2C_IFACE; } else if (!strcmp(argv[1], "swi")) { - slot_ctx->interface_config.atcahid.dev_interface = ATCA_KIT_SWI_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcahid.dev_interface) = ATCA_KIT_SWI_IFACE; } else if (!strcmp(argv[1], "spi")) { - slot_ctx->interface_config.atcahid.dev_interface = ATCA_KIT_SPI_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcahid.dev_interface) = ATCA_KIT_SPI_IFACE; } } if (argc > 2) { - slot_ctx->interface_config.atcahid.dev_identity = (uint8_t)strtol(argv[2], NULL, 16); + ATCA_IFACECFG_VALUE(cfg, atcahid.dev_identity) = (uint8_t)strtol(argv[2], NULL, 16); } rv = CKR_OK; @@ -357,22 +364,39 @@ static CK_RV pkcs11_config_parse_interface(pkcs11_slot_ctx_ptr slot_ctx, char* c else if (!strcmp(argv[0], "spi")) { #ifdef ATCA_HAL_SPI - slot_ctx->interface_config.iface_type = ATCA_SPI_IFACE; + cfg->iface_type = ATCA_SPI_IFACE; if (argc > 1) { - slot_ctx->interface_config.atcaspi.bus = (uint8_t)strtol(argv[1], NULL, 16); + ATCA_IFACECFG_VALUE(cfg, atcaspi.bus) = (uint8_t)strtol(argv[1], NULL, 16); } if (argc > 2) { - slot_ctx->interface_config.atcaspi.select_pin = (uint8_t)strtol(argv[2], NULL, 16); + ATCA_IFACECFG_VALUE(cfg, atcaspi.select_pin) = (uint8_t)strtol(argv[2], NULL, 16); } if (argc > 3) { - slot_ctx->interface_config.atcaspi.baud = (uint32_t)strtol(argv[3], NULL, 10); + ATCA_IFACECFG_VALUE(cfg, atcaspi.baud) = (uint32_t)strtol(argv[3], NULL, 10); } rv = CKR_OK; #endif } +#if defined(ATCA_HAL_KIT_BRIDGE) && defined(PKCS11_TESTING_ENABLE) + else if (!strcmp(argv[0], "bridge")) + { + cfg->iface_type = ATCA_KIT_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcakit.dev_interface) = ATCA_KIT_AUTO_IFACE; + ATCA_IFACECFG_VALUE(cfg, atcakit.dev_identity) = 0; + + if(argc > 1) + { + strncpy((char*)slot_ctx->devpath, argv[1], sizeof(slot_ctx->devpath)-1); + } + if(argc > 2) + { + ATCA_IFACECFG_VALUE(cfg, atcakit.dev_identity) = (uint8_t)strtol(argv[2], NULL, 10); + } + } +#endif else { PKCS11_DEBUG("Unrecognized interface: %s", argv[0]); @@ -427,6 +451,10 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs CK_RV rv = CKR_GENERAL_ERROR; pkcs11_object_ptr pObject; +#if !ATCA_CA_SUPPORT + ((void)slot_ctx); +#endif + pkcs11_config_split_string(cfgstr, ',', &argc, argv); if (!strcmp(argv[0], "private") && argc == 3) @@ -434,7 +462,7 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs pkcs11_object_ptr pPubkey = NULL; uint16_t slot = (uint16_t)strtol(argv[2], NULL, 16); - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pObject); if (!rv && pObject) { pkcs11_config_init_private(pObject, argv[1], strlen(argv[1])); @@ -448,7 +476,7 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs /* Every private key object needs a cooresponding public key object */ if (!rv) { - rv = pkcs11_object_alloc(&pPubkey); + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pPubkey); } if (!rv) { @@ -466,7 +494,7 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs } else if (!strcmp(argv[0], "public") && argc == 3) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pObject); if (!rv && pObject) { pkcs11_config_init_public(pObject, argv[1], strlen(argv[1])); @@ -479,7 +507,7 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs } else if (!strcmp(argv[0], "secret") && argc >= 3) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pObject); if (!rv && pObject) { uint8_t keylen = 32; @@ -498,7 +526,7 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs else if (!strcmp(argv[0], "certificate") && argc >= 3) { - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pObject); if (!rv && pObject) { memmove(pObject->name, argv[1], strlen(argv[1])); @@ -527,7 +555,6 @@ static CK_RV pkcs11_config_parse_object(pkcs11_slot_ctx_ptr slot_ctx, char* cfgs return rv; } - static CK_RV pkcs11_config_parse_handle(uint16_t * handle, char* cfgstr) { int argc = 4; @@ -545,7 +572,6 @@ static CK_RV pkcs11_config_parse_handle(uint16_t * handle, char* cfgstr) return rv; } - static CK_RV pkcs11_config_parse_slot_file(pkcs11_slot_ctx_ptr slot_ctx, int argc, char * argv[]) { CK_RV rv = CKR_GENERAL_ERROR; @@ -596,7 +622,11 @@ static CK_RV pkcs11_config_parse_object_file(pkcs11_slot_ctx_ptr slot_ctx, CK_BY pkcs11_object_ptr pObject = NULL; bool privkey = FALSE; - rv = pkcs11_object_alloc(&pObject); +#if !ATCA_CA_SUPPORT + ((void)slot_ctx); +#endif + + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pObject); if (!rv && pObject) { pObject->slot = slot; @@ -629,7 +659,7 @@ static CK_RV pkcs11_config_parse_object_file(pkcs11_slot_ctx_ptr slot_ctx, CK_BY } else if (!strcmp(argv[i], "label")) { - strncpy(pObject->name, argv[i + 1], sizeof(pObject->name)); + strncpy((char*)pObject->name, argv[i + 1], sizeof(pObject->name)-1); } } } @@ -638,7 +668,7 @@ static CK_RV pkcs11_config_parse_object_file(pkcs11_slot_ctx_ptr slot_ctx, CK_BY { /* Have to create a public copy of private keys */ pkcs11_object_ptr pPubkey = NULL; - rv = pkcs11_object_alloc(&pPubkey); + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pPubkey); if (!rv && pPubkey) { pPubkey->slot = slot; @@ -646,7 +676,7 @@ static CK_RV pkcs11_config_parse_object_file(pkcs11_slot_ctx_ptr slot_ctx, CK_BY #if ATCA_CA_SUPPORT pPubkey->config = &slot_ctx->cfg_zone; #endif - pkcs11_config_init_public(pPubkey, pObject->name, strlen(pObject->name)); + pkcs11_config_init_public(pPubkey, (char*)pObject->name, strlen((char*)pObject->name)); } else { @@ -660,6 +690,11 @@ static CK_RV pkcs11_config_parse_object_file(pkcs11_slot_ctx_ptr slot_ctx, CK_BY CK_RV pkcs11_config_cert(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pLabel) { + ((void)pLibCtx); + ((void)pSlot); + ((void)pObject); + ((void)pLabel); + return CKR_OK; } @@ -668,10 +703,14 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p FILE* fp; char *objtype = ""; char filename[200]; - int i = 0; CK_RV rv = CKR_FUNCTION_FAILED; + uint16_t handle = UINT16_MAX; + if(atcab_is_ca_device(pSlot->interface_config.devtype)) + { #if ATCA_CA_SUPPORT + int i = 0; + /* Find a free slot that matches the object type */ for (i = 0; i < 16; i++) { @@ -684,10 +723,7 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p { if ((4 == keytype) && privkey) { - pObject->slot = i; - pObject->flags = PKCS11_OBJECT_FLAG_DESTROYABLE; - pkcs11_config_init_private(pObject, pLabel->pValue, pLabel->ulValueLen); - objtype = "private"; + handle = i; break; } } @@ -695,10 +731,7 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p { if ((4 == keytype) && !privkey) { - pObject->slot = i; - pObject->flags = PKCS11_OBJECT_FLAG_DESTROYABLE; - pkcs11_config_init_public(pObject, pLabel->pValue, pLabel->ulValueLen); - objtype = "public"; + handle = i; break; } } @@ -706,24 +739,54 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p { if ((6 == keytype) || (7 == keytype)) { - pObject->slot = i; - pObject->flags = PKCS11_OBJECT_FLAG_DESTROYABLE; - pObject->config = &pSlot->cfg_zone; - pkcs11_config_init_secret(pObject, pLabel->pValue, pLabel->ulValueLen, 32); - objtype = "secret"; + handle = i; break; } } } } #endif + } + else + { +#if ATCA_TA_SUPPORT + ATCA_STATUS status = talib_create_element(atcab_get_device(), &pObject->handle_info, &handle); + rv = pkcs11_util_convert_rv(status); +#endif + } - if (i < 16) + if (UINT16_MAX != handle) { - int ret = snprintf(filename, sizeof(filename), "%s%d.%d.conf", pLibCtx->config_path, - (int)pSlot->slot_id, (int)i); + pObject->slot = handle; + pObject->flags = PKCS11_OBJECT_FLAG_DESTROYABLE; - if (ret > 0 && ret < sizeof(filename)) +#if ATCA_CA_SUPPORT + if(atcab_is_ca_device(pSlot->interface_config.devtype)) + { + pObject->config = &pSlot->cfg_zone; + } +#endif + + if (CKO_PRIVATE_KEY == pObject->class_id) + { + pkcs11_config_init_private(pObject, pLabel->pValue, pLabel->ulValueLen); + objtype = "private"; + } + else if (CKO_PUBLIC_KEY == pObject->class_id) + { + pkcs11_config_init_public(pObject, pLabel->pValue, pLabel->ulValueLen); + objtype = "public"; + } + else if (CKO_SECRET_KEY == pObject->class_id) + { + pkcs11_config_init_secret(pObject, pLabel->pValue, pLabel->ulValueLen, 32); + objtype = "secret"; + } + + int ret = snprintf(filename, sizeof(filename), "%s%lu.%u.conf", pLibCtx->config_path, + pSlot->slot_id, pObject->slot); + + if (ret > 0 && ret < (int)sizeof(filename)) { fp = fopen(filename, "wb"); if (fp) @@ -743,10 +806,10 @@ CK_RV pkcs11_config_remove_object(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_pt { char filename[200]; - int ret = snprintf(filename, sizeof(filename), "%s%d.%d.conf", pLibCtx->config_path, - (int)pSlot->slot_id, (int)pObject->slot); + int ret = snprintf(filename, sizeof(filename), "%s%lu.%u.conf", pLibCtx->config_path, + pSlot->slot_id, pObject->slot); - if (ret > 0 && ret < sizeof(filename)) + if (ret > 0 && ret < (int)sizeof(filename)) { remove(filename); pSlot->flags |= (1 << pObject->slot); @@ -758,16 +821,16 @@ CK_RV pkcs11_config_remove_object(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_pt /* Load configuration from the filesystem */ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr slot_ctx) { + DIR * d; + struct dirent *de; FILE* fp; char* buffer; size_t buflen; - char* argv[PKCS11_MAX_OBJECTS_ALLOWED + 1]; + char* argv[2 * (PKCS11_MAX_OBJECTS_ALLOWED + PKCS11_MAX_CONFIG_ALLOWED)]; int argc = 0; - char filename[200]; - int i; - int j; + pkcs11_lib_ctx_ptr pLibCtx = pkcs11_get_context(); - CK_RV rv; + CK_RV rv = CKR_OK; /* Open the general library configuration */ fp = fopen(ATCA_LIBRARY_CONF, "rb"); @@ -795,41 +858,80 @@ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr slot_ctx) } else { - PKCS11_DEBUG("Failed to parse the configuration file: %s", ATCA_LIBRARY_CONF); + PKCS11_DEBUG("Failed to parse the configuration file: %s\n", ATCA_LIBRARY_CONF); } pkcs11_os_free(buffer); } } - rv = 0; - for (i = 0; i < PKCS11_MAX_SLOTS_ALLOWED && !rv; i++) + if (NULL != (d = opendir((char*)pLibCtx->config_path))) { - int ret = snprintf(filename, sizeof(filename), "%s%d.conf", pLibCtx->config_path, i); + while((CKR_OK == rv) && (NULL != (de = readdir(d)))) + { + if(DT_REG == de->d_type) + { + argc = sizeof(argv)/sizeof(argv[0]); + size_t fnlen = strlen((char*)pLibCtx->config_path) + strlen(de->d_name) + 1; + char* filename = pkcs11_os_malloc(fnlen); - if (ret > 0 && ret < sizeof(filename)) + if (!filename) { - fp = fopen(filename, "rb"); + rv = CKR_HOST_MEMORY; + PKCS11_DEBUG("Failed to allocated a filename buffer\n"); + break; } - else + snprintf(filename, fnlen, "%s%s", pLibCtx->config_path, de->d_name); + pkcs11_config_split_string(de->d_name, '.', &argc, argv); + + if (!strcmp(argv[argc-1], "conf")) { - fp = NULL; - } + CK_SLOT_ID slot_id = (CK_SLOT_ID)strtol(argv[0], NULL, 10 ); + PKCS11_DEBUG("Opening Configuration: %s\n", filename); + fp = fopen(filename, "rb"); + pkcs11_os_free(filename); if (fp) { buflen = pkcs11_config_load_file(fp, &buffer); - fclose(fp); - fp = NULL; if (0 < buflen) { + if (2 == argc) + { + if (!slot_ctx->label[0]) + { + slot_ctx->slot_id = slot_id; + } + else if (slot_ctx->slot_id == slot_id) + { + PKCS11_DEBUG("Tried to reload the same configuration file for the same slot\n"); + rv = CKR_GENERAL_ERROR; + } + else + { + /* Move to the next context */ + slot_ctx = pkcs11_slot_get_new_context(pLibCtx); + if(slot_ctx) + { + slot_ctx->slot_id = slot_id; + } + else + { + rv = CKR_GENERAL_ERROR; + } + } + + if (CKR_OK == rv) + { if (0 < (argc = pkcs11_config_parse_buffer(buffer, buflen, sizeof(argv) / sizeof(argv[0]), argv))) { rv = pkcs11_config_parse_slot_file(slot_ctx, argc, argv); } else { - PKCS11_DEBUG("Failed to parse the slot configuration file"); + rv = CKR_GENERAL_ERROR; + PKCS11_DEBUG("Failed to parse the slot configuration file\n"); + } } #ifndef PKCS11_LABEL_IS_SERNUM if (CKR_OK == rv) @@ -837,46 +939,54 @@ CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr slot_ctx) /* If a label wasn't set - configure a default */ if (!slot_ctx->label[0]) { - snprintf((char*)slot_ctx->label, sizeof(slot_ctx->label) - 1, "%02XABC", (uint8_t)i); + snprintf((char*)slot_ctx->label, sizeof(slot_ctx->label) - 1, "%02XABC", (uint8_t)slot_ctx->slot_id); } } #endif - pkcs11_os_free(buffer); } + else if (3 == argc) + { + uint16_t handle = (uint16_t)strtol(argv[1], NULL, 10); + + if (!slot_ctx->label[0] || (slot_ctx->slot_id != slot_id)) + { + rv = CKR_GENERAL_ERROR; + PKCS11_DEBUG("Trying to load an object configuration without a slot configuration file\n"); } - for (j = 0; j < 16; j++) + if (CKR_OK == rv) { - int ret = snprintf(filename, sizeof(filename), "%s%d.%d.conf", pLibCtx->config_path, i, j); - if (ret > 0 && ret < sizeof(filename)) + if (0 < (argc = pkcs11_config_parse_buffer(buffer, buflen, sizeof(argv) / sizeof(argv[0]), argv))) { - fp = fopen(filename, "rb"); + rv = pkcs11_config_parse_object_file(slot_ctx, handle, argc, argv); } else { - fp = NULL; + rv = CKR_GENERAL_ERROR; + PKCS11_DEBUG("Failed to parse the slot configuration file\n"); + } } - if (fp) + if (CKR_OK == rv) { - buflen = pkcs11_config_load_file(fp, &buffer); - fclose(fp); - fp = NULL; - + #if ATCA_CA_SUPPORT + if(atcab_is_ca_device(slot_ctx->interface_config.devtype)) + { /* Remove the slot from the free list*/ - slot_ctx->flags &= ~(1 << j); - - if (0 < buflen) - { - if (0 < (argc = pkcs11_config_parse_buffer(buffer, buflen, sizeof(argv) / sizeof(argv[0]), argv))) - { - rv = pkcs11_config_parse_object_file(slot_ctx, j, argc, argv); + slot_ctx->flags &= ~(1 << handle); + } + #endif + } + } + pkcs11_os_free(buffer); + } + fclose(fp); } else { - PKCS11_DEBUG("Failed to parse the slot configuration file"); + rv = CKR_GENERAL_ERROR; + PKCS11_DEBUG("Unable to open the configuration file\n"); } - pkcs11_os_free(buffer); } } } @@ -896,7 +1006,7 @@ CK_RV pkcs11_config_load(pkcs11_slot_ctx_ptr slot_ctx) if (CKR_OK == rv) { pkcs11_object_ptr pObject; - rv = pkcs11_object_alloc(&pObject); + rv = pkcs11_object_alloc(slot_ctx->slot_id, &pObject); if (pObject) { /* Hardware Feature */ diff --git a/lib/pkcs11/pkcs11_config.h.in b/lib/pkcs11/pkcs11_config.h.in index 71768c947..b215a35fc 100644 --- a/lib/pkcs11/pkcs11_config.h.in +++ b/lib/pkcs11/pkcs11_config.h.in @@ -70,16 +70,30 @@ #define PKCS11_MAX_OBJECTS_ALLOWED @PKCS11_MAX_OBJECTS_ALLOWED@ #endif +/** Maximum Config options - device, interface, label, freeslots, user_pin_handle, so_pin_handle, object */ +#ifndef PKCS11_MAX_CONFIG_ALLOWED +#define PKCS11_MAX_CONFIG_ALLOWED @PKCS11_MAX_CONFIG_ALLOWED@ +#endif + /** Maximum label size in characters */ #ifndef PKCS11_MAX_LABEL_SIZE #define PKCS11_MAX_LABEL_SIZE @PKCS11_MAX_LABEL_SIZE@ #endif +/** Enables some additional test functionality for pkcs11 */ +#ifndef PKCS11_TESTING_ENABLE +#cmakedefine PKCS11_TESTING_ENABLE +#endif + /** Define to always convert PIN using KDF */ +#ifndef PKCS11_PIN_KDF_ALWAYS #cmakedefine PKCS11_PIN_KDF_ALWAYS +#endif /** Define to use PBKDF2 for PIN KDF */ +#ifndef PKCS11_PIN_PBKDF2_EN #cmakedefine PKCS11_PIN_PBKDF2_EN +#endif /** Define how many iterations PBKDF2 will use for PIN KDF */ #if defined(PKCS11_PIN_PBKDF2_EN) && !defined(PKCS11_PIN_PBKDF2_ITERATIONS) @@ -129,6 +143,7 @@ typedef struct _pkcs11_object *pkcs11_object_ptr; #if PKCS11_USE_STATIC_CONFIG CK_RV pkcs11_config_interface(pkcs11_slot_ctx_ptr pSlot); #endif +void pkcs11_config_split_string(char* s, char splitter, int * argc, char* argv[]); CK_RV pkcs11_config_load_objects(pkcs11_slot_ctx_ptr pSlot); CK_RV pkcs11_config_load(pkcs11_slot_ctx_ptr slot_ctx); CK_RV pkcs11_config_cert(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR pcLabel); diff --git a/lib/pkcs11/pkcs11_digest.c b/lib/pkcs11/pkcs11_digest.c index 9250ae172..56bef914a 100644 --- a/lib/pkcs11/pkcs11_digest.c +++ b/lib/pkcs11/pkcs11_digest.c @@ -1,15 +1,11 @@ +#include "cryptoauthlib.h" #include "pkcs11_init.h" #include "pkcs11_digest.h" +#include "pkcs11_mech.h" #include "pkcs11_object.h" #include "pkcs11_session.h" #include "pkcs11_util.h" -#include "cryptoauthlib.h" -#if !PKCS11_HARDWARE_SHA256 -#include "crypto/atca_crypto_sw_sha2.h" -static atcac_sha2_256_ctx pkcs11_digest_ctx; -static bool pkcs11_digest_initalized; -#endif /** * \brief Initializes a message-digesting operation using the specified mechanism in the specified session @@ -34,6 +30,10 @@ CK_RV pkcs11_digest_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism { return CKR_MECHANISM_INVALID; } + else if (CKM_VENDOR_DEFINED != pSession->active_mech) + { + return CKR_OPERATION_ACTIVE; + } rv = pkcs11_session_check(&pSession, hSession); if (rv) @@ -43,11 +43,11 @@ CK_RV pkcs11_digest_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism #if PKCS11_HARDWARE_SHA256 return CKR_FUNCTION_NOT_SUPPORTED; #else - rv = atcac_sw_sha2_256_init(&pkcs11_digest_ctx); + rv = atcac_sw_sha2_256_init(&pSession->active_mech_data.sha256); if (ATCA_SUCCESS == rv) { - pkcs11_digest_initalized = TRUE; + pSession->active_mech = CKM_SHA256; } return pkcs11_util_convert_rv(rv); @@ -98,14 +98,14 @@ CK_RV pkcs11_digest(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulDa return CKR_FUNCTION_NOT_SUPPORTED; #else - if (!pkcs11_digest_initalized) + if (CKM_SHA256 != pSession->active_mech) { return CKR_OPERATION_NOT_INITIALIZED; } rv = atcac_sw_sha2_256(pData, ulDataLen, pDigest); - pkcs11_digest_initalized = FALSE; + pSession->active_mech = CKM_VENDOR_DEFINED; return pkcs11_util_convert_rv(rv); #endif @@ -143,12 +143,12 @@ CK_RV pkcs11_digest_update(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pPart, CK_ULO return CKR_FUNCTION_NOT_SUPPORTED; #else - if (!pkcs11_digest_initalized) + if (CKM_SHA256 != pSession->active_mech) { return CKR_OPERATION_NOT_INITIALIZED; } - rv = atcac_sw_sha2_256_update(&pkcs11_digest_ctx, pPart, ulPartLen); + rv = atcac_sw_sha2_256_update(&pSession->active_mech_data.sha256, pPart, ulPartLen); return pkcs11_util_convert_rv(rv); #endif @@ -197,14 +197,14 @@ CK_RV pkcs11_digest_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pDigest, CK_UL return CKR_FUNCTION_NOT_SUPPORTED; #else - if (!pkcs11_digest_initalized) + if (CKM_SHA256 != pSession->active_mech) { return CKR_OPERATION_NOT_INITIALIZED; } - rv = atcac_sw_sha2_256_finish(&pkcs11_digest_ctx, pDigest); + rv = atcac_sw_sha2_256_finish(&pSession->active_mech_data.sha256, pDigest); - pkcs11_digest_initalized = FALSE; + pSession->active_mech = CKM_VENDOR_DEFINED; return pkcs11_util_convert_rv(rv); #endif diff --git a/lib/pkcs11/pkcs11_encrypt.c b/lib/pkcs11/pkcs11_encrypt.c index bb70a97a4..6e7954ed9 100644 --- a/lib/pkcs11/pkcs11_encrypt.c +++ b/lib/pkcs11/pkcs11_encrypt.c @@ -42,11 +42,12 @@ CK_RV pkcs11_encrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hObject) { + pkcs11_lib_ctx_ptr pLibCtx; pkcs11_session_ctx_ptr pSession; pkcs11_object_ptr pObject; CK_RV rv; - rv = pkcs11_init_check(NULL_PTR, FALSE); + rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) { return rv; @@ -76,6 +77,11 @@ CK_RV pkcs11_encrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanis case CKM_AES_ECB: rv = CKR_OK; break; + case CKM_AES_CBC_PAD: + /* fallthrough */ + case CKM_AES_CBC: + rv = pkcs11_util_convert_rv(atcab_aes_cbc_init(&pSession->active_mech_data.cbc, pObject->slot, 0, pMechanism->pParameter)); + break; case CKM_AES_GCM: if (pMechanism->pParameter && sizeof(CK_GCM_PARAMS) == pMechanism->ulParameterLen) { @@ -83,11 +89,43 @@ CK_RV pkcs11_encrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanis if (pParams->ulTagBits % 8 == 0) { - pSession->active_mech_data.gcm.tag_len = pParams->ulTagBits / 8; - if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_aes_gcm_init(&pSession->active_mech_data.gcm.context, - pObject->slot, 0, pParams->pIv, pParams->ulIvLen)))) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - rv = pkcs11_util_convert_rv(atcab_aes_gcm_aad_update(&pSession->active_mech_data.gcm.context, pParams->pAAD, pParams->ulAADLen)); + if(atcab_is_ca_device(atcab_get_device_type())) + { +#ifdef ATCA_ATECC608_SUPPORT + pSession->active_mech_data.gcm.tag_len = pParams->ulTagBits / 8; + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_aes_gcm_init(&pSession->active_mech_data.gcm.context, + pObject->slot, 0, pParams->pIv, pParams->ulIvLen)))) + { + rv = pkcs11_util_convert_rv(atcab_aes_gcm_aad_update(&pSession->active_mech_data.gcm.context, pParams->pAAD, pParams->ulAADLen)); + } +#else + rv = CKR_MECHANISM_INVALID; +#endif + } +#ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + if (pParams->ulIvLen > sizeof(pSession->active_mech_data.gcm_single.iv)) + { + rv = CKR_ARGUMENTS_BAD; + } + else + { + memcpy(pSession->active_mech_data.gcm_single.iv, pParams->pIv, pParams->ulIvLen); + } + if (pParams->ulAADLen > sizeof(pSession->active_mech_data.gcm_single.aad)) + { + rv = CKR_ARGUMENTS_BAD; + } + else + { + memcpy(pSession->active_mech_data.gcm_single.aad, pParams->pAAD, pParams->ulAADLen); + } + } +#endif + (void)pkcs11_unlock_both(pLibCtx); } } else @@ -128,6 +166,7 @@ CK_RV pkcs11_encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulD pkcs11_object_ptr pKey; CK_RV rv; ATCA_STATUS status = ATCA_SUCCESS; + CK_BBOOL padding = FALSE; rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) @@ -152,30 +191,74 @@ CK_RV pkcs11_encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulD return rv; } - switch (pSession->active_mech) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - case CKM_AES_ECB: - if (ulDataLen == ATCA_AES128_BLOCK_SIZE && *pulEncryptedDataLen > ATCA_AES128_BLOCK_SIZE) - { - status = atcab_aes_encrypt(pKey->slot, 0, pData, pEncryptedData); - *pulEncryptedDataLen = ATCA_AES128_BLOCK_SIZE; - } - else + switch (pSession->active_mech) { - rv = CKR_ARGUMENTS_BAD; - } - break; - case CKM_AES_GCM: - if (ATCA_SUCCESS == (status = atcab_aes_gcm_encrypt_update(&pSession->active_mech_data.gcm.context, pData, ulDataLen, pEncryptedData))) - { - status = atcab_aes_gcm_encrypt_finish(&pSession->active_mech_data.gcm.context, &pEncryptedData[ulDataLen], - pSession->active_mech_data.gcm.tag_len); - *pulEncryptedDataLen = ulDataLen + pSession->active_mech_data.gcm.tag_len; + case CKM_AES_ECB: + if (ulDataLen == ATCA_AES128_BLOCK_SIZE && *pulEncryptedDataLen >= ATCA_AES128_BLOCK_SIZE) + { + status = atcab_aes_encrypt(pKey->slot, 0, pData, pEncryptedData); + *pulEncryptedDataLen = ATCA_AES128_BLOCK_SIZE; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_CBC_PAD: + padding = TRUE; + /* fallthrough */ + case CKM_AES_CBC: + { + size_t length = *pulEncryptedDataLen; + if (ATCA_SUCCESS == (status = atcab_aes_cbc_encrypt_update(&pSession->active_mech_data.cbc, pData, ulDataLen, pEncryptedData, &length))) + { + pEncryptedData += length; + length = *pulEncryptedDataLen - length; + status = atcab_aes_cbc_encrypt_finish(&pSession->active_mech_data.cbc, pEncryptedData, &length, padding); + } + *pulEncryptedDataLen = length; + } + break; + case CKM_AES_GCM: + if(atcab_is_ca_device(atcab_get_device_type())) + { + #ifdef ATCA_ATECC608_SUPPORT + if (ATCA_SUCCESS == (status = atcab_aes_gcm_encrypt_update(&pSession->active_mech_data.gcm.context, pData, ulDataLen, pEncryptedData))) + { + status = atcab_aes_gcm_encrypt_finish(&pSession->active_mech_data.gcm.context, &pEncryptedData[ulDataLen], + pSession->active_mech_data.gcm.tag_len); + *pulEncryptedDataLen = ulDataLen + pSession->active_mech_data.gcm.tag_len; + } + #else + rv = CKR_GENERAL_ERROR; + #endif + } + #ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + if(ATCA_SUCCESS == (status = talib_aes_gcm_keyload(atcab_get_device(), pKey->slot, 0))) + { + if (ATCA_SUCCESS == (status = talib_aes_gcm_encrypt(atcab_get_device(), pSession->active_mech_data.gcm_single.aad, + pSession->active_mech_data.gcm_single.aad_len, pSession->active_mech_data.gcm_single.iv, + pData, (uint16_t)ulDataLen, pEncryptedData, &pEncryptedData[ulDataLen]))) + { + *pulEncryptedDataLen = ulDataLen + TA_AES_GCM_TAG_LENGTH; + } + else + { + rv = CKR_DATA_LEN_RANGE; + } + } + } + #endif + break; + default: + rv = CKR_MECHANISM_INVALID; + break; } - break; - default: - rv = CKR_MECHANISM_INVALID; - break; + (void)pkcs11_unlock_both(pLibCtx); } pSession->active_mech = CKM_VENDOR_DEFINED; @@ -225,25 +308,49 @@ CK_RV pkcs11_encrypt_update return rv; } - switch (pSession->active_mech) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - case CKM_AES_ECB: - if (ulDataLen == ATCA_AES128_BLOCK_SIZE && *pulEncryptedDataLen > ATCA_AES128_BLOCK_SIZE) + switch (pSession->active_mech) { - status = atcab_aes_encrypt(pKey->slot, 0, pData, pEncryptedData); - *pulEncryptedDataLen = ATCA_AES128_BLOCK_SIZE; - } - else - { - rv = CKR_ARGUMENTS_BAD; + case CKM_AES_ECB: + if (ulDataLen == ATCA_AES128_BLOCK_SIZE && *pulEncryptedDataLen >= ATCA_AES128_BLOCK_SIZE) + { + status = atcab_aes_encrypt(pKey->slot, 0, pData, pEncryptedData); + *pulEncryptedDataLen = ATCA_AES128_BLOCK_SIZE; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_CBC_PAD: + /* fallthrough */ + case CKM_AES_CBC: + { + size_t length = *pulEncryptedDataLen; + status = atcab_aes_cbc_encrypt_update(&pSession->active_mech_data.cbc, pData, ulDataLen, pEncryptedData, &length); + *pulEncryptedDataLen = length; + } + break; + case CKM_AES_GCM: + if(atcab_is_ca_device(atcab_get_device_type())) + { + #ifdef ATCA_ATECC608_SUPPORT + status = atcab_aes_gcm_encrypt_update(&pSession->active_mech_data.gcm.context, pData, ulDataLen, pEncryptedData); + #endif + } + #ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + rv = CKR_FUNCTION_NOT_SUPPORTED; + } + #endif + break; + default: + rv = CKR_MECHANISM_INVALID; + break; } - break; - case CKM_AES_GCM: - status = atcab_aes_gcm_encrypt_update(&pSession->active_mech_data.gcm.context, pData, ulDataLen, pEncryptedData); - break; - default: - rv = CKR_MECHANISM_INVALID; - break; + (void)pkcs11_unlock_both(pLibCtx); } if (ATCA_SUCCESS != status && CKR_OK == rv) @@ -264,6 +371,7 @@ CK_RV pkcs11_encrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedDat pkcs11_object_ptr pKey; CK_RV rv; ATCA_STATUS status = ATCA_SUCCESS; + CK_BBOOL padding = FALSE; rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) @@ -288,18 +396,43 @@ CK_RV pkcs11_encrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedDat return rv; } - switch (pSession->active_mech) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - case CKM_AES_ECB: - break; - case CKM_AES_GCM: - status = atcab_aes_gcm_encrypt_finish(&pSession->active_mech_data.gcm.context, pEncryptedData, - pSession->active_mech_data.gcm.tag_len); - *pulEncryptedDataLen = pSession->active_mech_data.gcm.tag_len; - break; - default: - rv = CKR_MECHANISM_INVALID; - break; + switch (pSession->active_mech) + { + case CKM_AES_ECB: + break; + case CKM_AES_CBC_PAD: + padding = TRUE; + /* fallthrough */ + case CKM_AES_CBC: + { + size_t length = *pulEncryptedDataLen; + status = atcab_aes_cbc_encrypt_finish(&pSession->active_mech_data.cbc, pEncryptedData, &length, padding); + *pulEncryptedDataLen = length; + } + break; + case CKM_AES_GCM: + if(atcab_is_ca_device(atcab_get_device_type())) + { + #ifdef ATCA_ATECC608_SUPPORT + status = atcab_aes_gcm_encrypt_finish(&pSession->active_mech_data.gcm.context, pEncryptedData, + pSession->active_mech_data.gcm.tag_len); + *pulEncryptedDataLen = pSession->active_mech_data.gcm.tag_len; + #endif + } + #ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + rv = CKR_FUNCTION_NOT_SUPPORTED; + } + #endif + break; + default: + rv = CKR_MECHANISM_INVALID; + break; + } + (void)pkcs11_unlock_both(pLibCtx); } if (ATCA_SUCCESS != status && CKR_OK == rv) @@ -314,11 +447,12 @@ CK_RV pkcs11_encrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pEncryptedDat CK_RV pkcs11_decrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hObject) { + pkcs11_lib_ctx_ptr pLibCtx; pkcs11_session_ctx_ptr pSession; pkcs11_object_ptr pObject; CK_RV rv; - rv = pkcs11_init_check(NULL_PTR, FALSE); + rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) { return rv; @@ -348,6 +482,11 @@ CK_RV pkcs11_decrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanis case CKM_AES_ECB: rv = CKR_OK; break; + case CKM_AES_CBC_PAD: + /* fallthrough */ + case CKM_AES_CBC: + rv = pkcs11_util_convert_rv(atcab_aes_cbc_init(&pSession->active_mech_data.cbc, pObject->slot, 0, pMechanism->pParameter)); + break; case CKM_AES_GCM: if (pMechanism->pParameter && sizeof(CK_GCM_PARAMS) == pMechanism->ulParameterLen) { @@ -355,11 +494,43 @@ CK_RV pkcs11_decrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanis if (pParams->ulTagBits % 8 == 0) { - pSession->active_mech_data.gcm.tag_len = pParams->ulTagBits / 8; - if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_aes_gcm_init(&pSession->active_mech_data.gcm.context, - pObject->slot, 0, pParams->pIv, pParams->ulIvLen)))) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - rv = pkcs11_util_convert_rv(atcab_aes_gcm_aad_update(&pSession->active_mech_data.gcm.context, pParams->pAAD, pParams->ulAADLen)); + if(atcab_is_ca_device(atcab_get_device_type())) + { + #ifdef ATCA_ATECC608_SUPPORT + pSession->active_mech_data.gcm.tag_len = pParams->ulTagBits / 8; + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_aes_gcm_init(&pSession->active_mech_data.gcm.context, + pObject->slot, 0, pParams->pIv, pParams->ulIvLen)))) + { + rv = pkcs11_util_convert_rv(atcab_aes_gcm_aad_update(&pSession->active_mech_data.gcm.context, pParams->pAAD, pParams->ulAADLen)); + } + #else + rv = CKR_MECHANISM_INVALID; + #endif + } + #ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + if (pParams->ulIvLen > sizeof(pSession->active_mech_data.gcm_single.iv)) + { + rv = CKR_ARGUMENTS_BAD; + } + else + { + memcpy(pSession->active_mech_data.gcm_single.iv, pParams->pIv, pParams->ulIvLen); + } + if (pParams->ulAADLen > sizeof(pSession->active_mech_data.gcm_single.aad)) + { + rv = CKR_ARGUMENTS_BAD; + } + else + { + memcpy(pSession->active_mech_data.gcm_single.aad, pParams->pAAD, pParams->ulAADLen); + } + } + #endif + (void)pkcs11_unlock_both(pLibCtx); } } else @@ -406,6 +577,7 @@ CK_RV pkcs11_decrypt pkcs11_object_ptr pKey; CK_RV rv; ATCA_STATUS status = ATCA_SUCCESS; + CK_BBOOL padding = FALSE; rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) @@ -430,36 +602,75 @@ CK_RV pkcs11_decrypt return rv; } - switch (pSession->active_mech) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - case CKM_AES_ECB: - if (ulEncryptedDataLen == ATCA_AES128_BLOCK_SIZE && *pulDataLen >= ATCA_AES128_BLOCK_SIZE) + switch (pSession->active_mech) { - status = atcab_aes_decrypt(pKey->slot, 0, pEncryptedData, pData); - *pulDataLen = ATCA_AES128_BLOCK_SIZE; - } - else - { - rv = CKR_ARGUMENTS_BAD; - } - break; - case CKM_AES_GCM: - *pulDataLen = ulEncryptedDataLen - pSession->active_mech_data.gcm.tag_len; - if (ATCA_SUCCESS == (status = atcab_aes_gcm_decrypt_update(&pSession->active_mech_data.gcm.context, pEncryptedData, - *pulDataLen, pData))) - { - bool is_verified = FALSE; - status = atcab_aes_gcm_decrypt_finish(&pSession->active_mech_data.gcm.context, &pEncryptedData[*pulDataLen], - pSession->active_mech_data.gcm.tag_len, &is_verified); - if (!is_verified) + case CKM_AES_ECB: + if (ulEncryptedDataLen == ATCA_AES128_BLOCK_SIZE && *pulDataLen >= ATCA_AES128_BLOCK_SIZE) { - rv = CKR_ENCRYPTED_DATA_INVALID; + status = atcab_aes_decrypt(pKey->slot, 0, pEncryptedData, pData); + *pulDataLen = ATCA_AES128_BLOCK_SIZE; } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_CBC_PAD: + padding = TRUE; + /* fallthrough */ + case CKM_AES_CBC: + { + size_t length = *pulDataLen; + if (ATCA_SUCCESS == (status = atcab_aes_cbc_decrypt_update(&pSession->active_mech_data.cbc, pEncryptedData, ulEncryptedDataLen, pData, &length))) + { + pData += length; + length = *pulDataLen - length; + status = atcab_aes_cbc_decrypt_finish(&pSession->active_mech_data.cbc, pData, &length, padding); + } + *pulDataLen = length; + } + break; + case CKM_AES_GCM: + if(atcab_is_ca_device(atcab_get_device_type())) + { + #ifdef ATCA_ATECC608_SUPPORT + *pulDataLen = ulEncryptedDataLen - pSession->active_mech_data.gcm.tag_len; + if (ATCA_SUCCESS == (status = atcab_aes_gcm_decrypt_update(&pSession->active_mech_data.gcm.context, pEncryptedData, + *pulDataLen, pData))) + { + bool is_verified = FALSE; + status = atcab_aes_gcm_decrypt_finish(&pSession->active_mech_data.gcm.context, &pEncryptedData[*pulDataLen], + pSession->active_mech_data.gcm.tag_len, &is_verified); + if (!is_verified) + { + rv = CKR_ENCRYPTED_DATA_INVALID; + } + } + #endif + } + #ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + if(ATCA_SUCCESS == (status = talib_aes_gcm_keyload(atcab_get_device(), pKey->slot, 0))) + { + *pulDataLen = ulEncryptedDataLen - TA_AES_GCM_TAG_LENGTH; + if (ATCA_SUCCESS != (status = talib_aes_gcm_decrypt(atcab_get_device(), pSession->active_mech_data.gcm_single.aad, + pSession->active_mech_data.gcm_single.aad_len, pSession->active_mech_data.gcm_single.iv, + &pEncryptedData[*pulDataLen], pEncryptedData, *pulDataLen, pData))) + { + rv = CKR_ENCRYPTED_DATA_INVALID; + } + } + } + #endif + break; + default: + rv = CKR_MECHANISM_INVALID; + break; } - break; - default: - rv = CKR_MECHANISM_INVALID; - break; + (void)pkcs11_unlock_both(pLibCtx); } pSession->active_mech = CKM_VENDOR_DEFINED; @@ -510,26 +721,50 @@ CK_RV pkcs11_decrypt_update return rv; } - switch (pSession->active_mech) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - case CKM_AES_ECB: - if (ulEncryptedDataLen == ATCA_AES128_BLOCK_SIZE && *pulDataLen > ATCA_AES128_BLOCK_SIZE) + switch (pSession->active_mech) { - status = atcab_aes_decrypt(pKey->slot, 0, pData, pEncryptedData); - *pulDataLen = ATCA_AES128_BLOCK_SIZE; - } - else - { - rv = CKR_ARGUMENTS_BAD; + case CKM_AES_ECB: + if (ulEncryptedDataLen == ATCA_AES128_BLOCK_SIZE && *pulDataLen >= ATCA_AES128_BLOCK_SIZE) + { + status = atcab_aes_decrypt(pKey->slot, 0, pEncryptedData, pData); + *pulDataLen = ATCA_AES128_BLOCK_SIZE; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; + case CKM_AES_CBC_PAD: + /* fallthrough */ + case CKM_AES_CBC: + { + size_t length = *pulDataLen; + status = atcab_aes_cbc_decrypt_update(&pSession->active_mech_data.cbc, pEncryptedData, ulEncryptedDataLen, pData, &length); + *pulDataLen = length; + } + break; + case CKM_AES_GCM: + if(atcab_is_ca_device(atcab_get_device_type())) + { + #ifdef ATCA_ATECC608_SUPPORT + status = atcab_aes_gcm_decrypt_update(&pSession->active_mech_data.gcm.context, pEncryptedData, + *pulDataLen, pData); + #endif + } + #ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + rv = CKR_FUNCTION_NOT_SUPPORTED; + } + #endif + break; + default: + rv = CKR_MECHANISM_INVALID; + break; } - break; - case CKM_AES_GCM: - status = atcab_aes_gcm_decrypt_update(&pSession->active_mech_data.gcm.context, pEncryptedData, - *pulDataLen, pData); - break; - default: - rv = CKR_MECHANISM_INVALID; - break; + (void)pkcs11_unlock_both(pLibCtx); } if (ATCA_SUCCESS != status && CKR_OK == rv) @@ -550,6 +785,7 @@ CK_RV pkcs11_decrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULO pkcs11_object_ptr pKey; CK_RV rv; ATCA_STATUS status = ATCA_SUCCESS; + CK_BBOOL padding = FALSE; rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) @@ -578,16 +814,39 @@ CK_RV pkcs11_decrypt_final(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULO { case CKM_AES_ECB: break; + case CKM_AES_CBC_PAD: + padding = TRUE; + /* fallthrough */ + case CKM_AES_CBC: + { + size_t length = *pulDataLen; + status = atcab_aes_cbc_decrypt_finish(&pSession->active_mech_data.cbc, pData, &length, padding); + *pulDataLen = length; + } + break; case CKM_AES_GCM: - { - bool is_verified = FALSE; - status = atcab_aes_gcm_decrypt_finish(&pSession->active_mech_data.gcm.context, pData, - pSession->active_mech_data.gcm.tag_len, &is_verified); - if (!is_verified) + if(atcab_is_ca_device(atcab_get_device_type())) { - rv = CKR_ENCRYPTED_DATA_INVALID; +#ifdef ATCA_ATECC608_SUPPORT + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) + { + bool is_verified = FALSE; + status = atcab_aes_gcm_decrypt_finish(&pSession->active_mech_data.gcm.context, pData, + pSession->active_mech_data.gcm.tag_len, &is_verified); + if (!is_verified) + { + rv = CKR_ENCRYPTED_DATA_INVALID; + } + (void)pkcs11_unlock_both(pLibCtx); + } +#endif } - } +#ifdef ATCA_TA100_SUPPORT + if(atcab_is_ta_device(atcab_get_device_type())) + { + rv = CKR_FUNCTION_NOT_SUPPORTED; + } +#endif break; default: rv = CKR_MECHANISM_INVALID; diff --git a/lib/pkcs11/pkcs11_find.c b/lib/pkcs11/pkcs11_find.c index 5098d10b5..2264ea87d 100644 --- a/lib/pkcs11/pkcs11_find.c +++ b/lib/pkcs11/pkcs11_find.c @@ -197,7 +197,7 @@ static pkcs11_attrib_model_ptr pkcs11_find_attrib_match(pkcs11_object_ptr pObjec return NULL_PTR; } -static CK_OBJECT_HANDLE pkcs11_find_handle(const CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG_PTR index) +static CK_OBJECT_HANDLE pkcs11_find_handle(const CK_SLOT_ID slotid, const CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_ULONG_PTR index) { CK_ULONG i; CK_ULONG j; @@ -207,7 +207,7 @@ static CK_OBJECT_HANDLE pkcs11_find_handle(const CK_ATTRIBUTE_PTR pTemplate, CK_ for (i = (index) ? *index : 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) { pkcs11_object_ptr pObject = pkcs11_object_cache[i].object; - if (pObject) + if (pObject && slotid == pkcs11_object_cache[i].slotid) { /* Iterate through attribute list */ for (j = 0; j < ulCount; j++) @@ -248,11 +248,12 @@ static CK_OBJECT_HANDLE pkcs11_find_handle(const CK_ATTRIBUTE_PTR pTemplate, CK_ CK_RV pkcs11_find_init(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { + pkcs11_lib_ctx_ptr pLibCtx; pkcs11_session_ctx_ptr pSession; CK_ULONG index = 0; CK_RV rv; - rv = pkcs11_init_check(NULL, FALSE); + rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) { return rv; @@ -275,42 +276,48 @@ CK_RV pkcs11_find_init(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, C get private unless we're using a shared key system - and that will only be for secured data and not key info */ - if (pkcs11_find_handle(pTemplate, ulCount, &index)) + if (CKR_OK == (rv = (pkcs11_lock_both(pLibCtx)))) { - if (ulCount) + if (pkcs11_find_handle(pSession->slot->slot_id, pTemplate, ulCount, &index)) { - rv = pkcs11_find_copy_template(pkcs11_find_template_cache, PKCS11_SEARCH_CACHE_SIZE, pTemplate, ulCount); - if (rv) + if (ulCount) { - return rv; + if (CKR_OK == (rv = pkcs11_find_copy_template(pkcs11_find_template_cache, PKCS11_SEARCH_CACHE_SIZE, pTemplate, ulCount))) + { + pSession->attrib_list = (CK_ATTRIBUTE_PTR)pkcs11_find_template_cache; + } + } + else + { + pSession->attrib_list = NULL_PTR; + } + if (CKR_OK == rv) + { + pSession->attrib_count = ulCount; + pSession->object_index = index; + pSession->object_count = 1; + index++; + while (pkcs11_find_handle(pSession->slot->slot_id, pSession->attrib_list, ulCount, &index)) + { + pSession->object_count++; + index++; + } } - pSession->attrib_list = (CK_ATTRIBUTE_PTR)pkcs11_find_template_cache; - } - else - { - pSession->attrib_list = NULL_PTR; - } - pSession->attrib_count = ulCount; - pSession->object_index = index; - pSession->object_count = 1; - index++; - while (pkcs11_find_handle(pSession->attrib_list, ulCount, &index)) - { - pSession->object_count++; - index++; } + (void)pkcs11_unlock_both(pLibCtx); } - return CKR_OK; + return rv; } CK_RV pkcs11_find_continue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phObject, CK_ULONG ulMaxObjectCount, CK_ULONG_PTR pulObjectCount) { + pkcs11_lib_ctx_ptr pLibCtx; pkcs11_session_ctx_ptr pSession; CK_ULONG i; CK_RV rv; - rv = pkcs11_init_check(NULL, FALSE); + rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) { return rv; @@ -329,25 +336,30 @@ CK_RV pkcs11_find_continue(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE_PTR phOb *pulObjectCount = (pSession->object_count < ulMaxObjectCount) ? pSession->object_count : ulMaxObjectCount; - for (i = 0; i < *pulObjectCount; i++) + if (CKR_OK == (rv = (pkcs11_lock_both(pLibCtx)))) { - phObject[i] = pkcs11_find_handle(pSession->attrib_list, pSession->attrib_count, &pSession->object_index); - if (!phObject[i]) + for (i = 0; i < *pulObjectCount; i++) { - pSession->object_count = 0; - *pulObjectCount = i; - break; - } + phObject[i] = pkcs11_find_handle(pSession->slot->slot_id, pSession->attrib_list, + pSession->attrib_count, &pSession->object_index); + if (!phObject[i]) + { + pSession->object_count = 0; + *pulObjectCount = i; + break; + } - pSession->object_index++; + pSession->object_index++; - if (pSession->object_count) - { - pSession->object_count--; + if (pSession->object_count) + { + pSession->object_count--; + } } + (void)pkcs11_unlock_both(pLibCtx); } - return CKR_OK; + return rv; } CK_RV pkcs11_find_finish(CK_SESSION_HANDLE hSession) @@ -425,7 +437,7 @@ CK_RV pkcs11_find_get_attribute(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hOb } else if (pAttribute->func) { - if (CKR_OK == pkcs11_lock_context(pLibCtx)) + if (CKR_OK == pkcs11_lock_both(pLibCtx)) { /* Attribute function found so try to execute it */ CK_RV temp = pAttribute->func(pObject, &pTemplate[i]); @@ -433,7 +445,11 @@ CK_RV pkcs11_find_get_attribute(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hOb { rv = temp; } - pkcs11_unlock_context(pLibCtx); + (void)pkcs11_unlock_both(pLibCtx); + } + else if (!rv) + { + rv = CKR_GENERAL_ERROR; } } else diff --git a/lib/pkcs11/pkcs11_init.c b/lib/pkcs11/pkcs11_init.c index 8d216bf95..9b35c8226 100644 --- a/lib/pkcs11/pkcs11_init.c +++ b/lib/pkcs11/pkcs11_init.c @@ -46,12 +46,12 @@ /** Library intialization defaults if none were provided */ static const CK_C_INITIALIZE_ARGS pkcs11_init_defaults = { - NULL_PTR, /**< Callback to create a mutex */ - NULL_PTR, /**< Callback to destroy a mutex */ - NULL_PTR, /**< Callback to lock a mutex */ - NULL_PTR, /**< Callback to unlock a mutex */ - 0, /**< Initialization Flags */ - NULL_PTR, /**< Reserved - Must be NULL */ + NULL_PTR, /**< Callback to create a mutex */ + NULL_PTR, /**< Callback to destroy a mutex */ + NULL_PTR, /**< Callback to lock a mutex */ + NULL_PTR, /**< Callback to unlock a mutex */ + CKF_OS_LOCKING_OK, /**< Initialization Flags */ + NULL_PTR, /**< Reserved - Must be NULL */ }; /** @@ -69,19 +69,22 @@ pkcs11_lib_ctx_ptr pkcs11_get_context(void) CK_RV pkcs11_lock_context(pkcs11_lib_ctx_ptr pContext) { - CK_RV rv = CKR_ARGUMENTS_BAD; - -// PKCS11_DEBUG("%p\r\n", pkcs11_context.lock_mutex); + CK_RV rv = CKR_OK; if (pContext) { if (pContext->lock_mutex) { - rv = pContext->lock_mutex(pContext->mutex); + rv = pContext->lock_mutex(pContext->lib_lock); } else { - rv = CKR_CANT_LOCK; + rv = pkcs11_os_lock_mutex(pContext->lib_lock); + } + + if (CKR_OK == rv) + { + pContext->lib_locked = TRUE; } } return rv; @@ -91,8 +94,6 @@ CK_RV pkcs11_unlock_context(pkcs11_lib_ctx_ptr pContext) { CK_RV rv = CKR_CRYPTOKI_NOT_INITIALIZED; -// PKCS11_DEBUG("%p\r\n", pkcs11_context.unlock_mutex); - if (!pContext) { pContext = pkcs11_get_context(); @@ -100,19 +101,92 @@ CK_RV pkcs11_unlock_context(pkcs11_lib_ctx_ptr pContext) if (pContext) { + /* Assume that even if unlock fails it will still have unlocked the mutex */ + pContext->lib_locked = FALSE; + if (pContext->unlock_mutex) { - rv = pContext->unlock_mutex(pContext->mutex); + rv = pContext->unlock_mutex(pContext->lib_lock); } else { - rv = CKR_CANT_LOCK; + rv = pkcs11_os_unlock_mutex(pContext->lib_lock); } } return rv; } +CK_RV pkcs11_lock_device(pkcs11_lib_ctx_ptr pContext) +{ + CK_RV rv = CKR_OK; + + if (pContext) + { + if (pContext->lib_locked) + { + if (pContext->dev_lock) + { + rv = pkcs11_os_lock_mutex(pContext->dev_lock); + } + } + else + { + PKCS11_DEBUG("Library tried to lock out of order\n"); + rv = CKR_GENERAL_ERROR; + } + } + return rv; +} + +CK_RV pkcs11_unlock_device(pkcs11_lib_ctx_ptr pContext) +{ + if (!pContext) + { + pContext = pkcs11_get_context(); + } + + if (pContext && pContext->dev_lock) + { + return pkcs11_os_unlock_mutex(pContext->dev_lock); + } + else + { + return CKR_OK; + } +} + +CK_RV pkcs11_lock_both(pkcs11_lib_ctx_ptr pContext) +{ + CK_RV rv = CKR_OK; + + if (CKR_OK == (rv = pkcs11_lock_context(pContext))) + { + if(CKR_OK != (rv = pkcs11_lock_device(pContext))) + { + (void)pkcs11_unlock_context(pContext); + } + } + return rv; +} + +CK_RV pkcs11_unlock_both(pkcs11_lib_ctx_ptr pContext) +{ + CK_RV rv1 = CKR_OK; + CK_RV rv2 = CKR_OK; + + if (!pContext) + { + pContext = pkcs11_get_context(); + } + + rv1 = pkcs11_unlock_device(pContext); + rv2 = pkcs11_unlock_context(pContext); + + return rv1 ? rv1 : rv2; +} + + /** * \brief Check if the library is initialized properly */ @@ -184,83 +258,110 @@ CK_RV pkcs11_init(CK_C_INITIALIZE_ARGS_PTR pInitArgs) return CKR_ARGUMENTS_BAD; } - /* PKCS11 Sec 5.4 Rules 2 & 3 */ - if (allset || (CKF_OS_LOCKING_OK & pInitArgs->flags)) - { - /* Calling system plans to make calls to the library from multiple threads */ - if (allset) - { - /* Use the provided callbacks to perform locking operations */ - lib_ctx->create_mutex = pInitArgs->CreateMutex; - lib_ctx->destroy_mutex = pInitArgs->DestroyMutex; - lib_ctx->lock_mutex = pInitArgs->LockMutex; - lib_ctx->unlock_mutex = pInitArgs->UnlockMutex; - } - else - { - /* Means we need to use native calls */ - lib_ctx->create_mutex = pkcs11_os_create_mutex; - lib_ctx->destroy_mutex = pkcs11_os_destroy_mutex; - lib_ctx->lock_mutex = pkcs11_os_lock_mutex; - lib_ctx->unlock_mutex = pkcs11_os_unlock_mutex; - } - } - /* Only need to check if our library needs to create threads */ if (CKF_LIBRARY_CANT_CREATE_OS_THREADS & pInitArgs->flags) { /* If we can't operate successfully without creating threads we'd respond: */ // return CKR_NEED_TO_CREATE_THREADS; } - - /* Perform library initialization steps */ - if (lib_ctx->create_mutex) + + if (CKF_OS_LOCKING_OK & pInitArgs->flags) { - if (lib_ctx->create_mutex(&lib_ctx->mutex)) + /* 2. If the flag is set, and the function pointer fields aren’t supplied + (i.e., they all have the value NULL_PTR), that means that the application + will be performing multi-threaded Cryptoki access, and the library needs + to use the native operating system primitives to ensure safe multi-threaded + access. If the library is unable to do this, C_Initialize should return + with the value CKR_CANT_LOCK. */ + /* 4. If the flag is set, and the function pointer fields are supplied (i.e., they + all have non-NULL_PTR values), that means that the application will be performing + multi-threaded Cryptoki access, and the library needs to use either the native + operating system primitives or the supplied function pointers for mutex-handling + to ensure safe multi-threaded access. If the library is unable to do this, + C_Initialize should return with the value CKR_CANT_LOCK. */ + + /* Per the above PKCS11 rules we will use our own mutex. One mutex is always a better + choice to avoid deadlocks. */ + if (pkcs11_os_create_mutex(&lib_ctx->lib_lock)) { - PKCS11_DEBUG("Create Failed\r\n"); + PKCS11_DEBUG("Mutex Create Failed - Rule 2 or 4\n"); return CKR_CANT_LOCK; } } - - /* Lock the library mutex */ - if (lib_ctx->lock_mutex) + else { - if (lib_ctx->lock_mutex(lib_ctx->mutex)) + if (allset) { - PKCS11_DEBUG("Lock Failed\r\n"); - return CKR_CANT_LOCK; - } - } + /* 3. If the flag isn’t set, and the function pointer fields are supplied (i.e., + they all have non-NULL_PTR values), that means that the application will + be performing multi-threaded Cryptoki access, and the library needs to use + the supplied function pointers for mutex-handling to ensure safe multi-threaded + access. If the library is unable to do this, C_Initialize should return with + the value CKR_CANT_LOCK. */ + lib_ctx->create_mutex = pInitArgs->CreateMutex; + lib_ctx->destroy_mutex = pInitArgs->DestroyMutex; + lib_ctx->lock_mutex = pInitArgs->LockMutex; + lib_ctx->unlock_mutex = pInitArgs->UnlockMutex; - /* Initialize the Crypto device */ - lib_ctx->slots = pkcs11_slot_initslots(PKCS11_MAX_SLOTS_ALLOWED); - if (lib_ctx->slots) - { - lib_ctx->slot_cnt = PKCS11_MAX_SLOTS_ALLOWED; - } + /* Perform library initialization steps */ + if (lib_ctx->create_mutex(&lib_ctx->lib_lock)) + { + PKCS11_DEBUG("Mutex Create Failed - Rule 3\n"); + return CKR_CANT_LOCK; + } - /* Set up a slot with a configuration */ - rv = pkcs11_slot_config(0); + /* Regardless of the User's mutex arrangements the library has to protect the device */ + if (pkcs11_os_create_mutex(&lib_ctx->dev_lock)) + { + /* Clean up the best we can */ + if (lib_ctx->lib_lock && lib_ctx->destroy_mutex) + { + (void)lib_ctx->destroy_mutex(lib_ctx->lib_lock); + lib_ctx->lib_lock = NULL; + } + PKCS11_DEBUG("Device Mutex Create Failed - Rule 3\n"); + return CKR_GENERAL_ERROR; + } + } + else + { + /* 1. If the flag isn’t set, and the function pointer fields aren’t supplied (i.e., they all + have the value NULL_PTR), that means that the application won’t be accessing the + Cryptoki library from multiple threads simultaneously. */ - if (CKR_OK == rv) - { - /* Attempt to Initialize the slot */ - rv = pkcs11_slot_init(0); + /* Regardless of the user's mutex arrangements the library has to protect the device so + we always lock the context at the safest location. */ + if (pkcs11_os_create_mutex(&lib_ctx->lib_lock)) + { + PKCS11_DEBUG("Mutex Create Failed - Rule 1\n"); + return CKR_CANT_LOCK; + } + } } - if (CKR_OK == rv) + /* Lock the library context */ + if (CKR_OK == (rv = pkcs11_lock_both(lib_ctx))) { - lib_ctx->initialized = TRUE; - } + /* Initialize the Crypto device */ + lib_ctx->slots = pkcs11_slot_initslots(PKCS11_MAX_SLOTS_ALLOWED); + if (lib_ctx->slots) + { + lib_ctx->slot_cnt = PKCS11_MAX_SLOTS_ALLOWED; + } - /* UnLock the library mutex */ - if (lib_ctx->unlock_mutex) - { - if (lib_ctx->unlock_mutex(lib_ctx->mutex)) + /* Set up a slot with a configuration */ + if (CKR_OK == (rv = pkcs11_slot_config(0))) { - return CKR_CANT_LOCK; + /* Attempt to Initialize the slot */ + rv = pkcs11_slot_init(0); + } + + if (CKR_OK == rv) + { + lib_ctx->initialized = TRUE; } + + rv = pkcs11_unlock_both(lib_ctx); } return rv; @@ -269,48 +370,81 @@ CK_RV pkcs11_init(CK_C_INITIALIZE_ARGS_PTR pInitArgs) /* Close the library */ CK_RV pkcs11_deinit(CK_VOID_PTR pReserved) { + CK_RV rv = CKR_OK; uint32_t ulSlot = 0; + pkcs11_lib_ctx_ptr lib_ctx = pkcs11_get_context(); if (pReserved) { return CKR_ARGUMENTS_BAD; } - if (!pkcs11_context.initialized) + if (!lib_ctx || !lib_ctx->initialized) { return CKR_CRYPTOKI_NOT_INITIALIZED; } -#if ATCA_TA_SUPPORT - if (atcab_is_ta_device(atcab_get_device_type())) + /* Lock the library */ + if (CKR_OK == (rv == pkcs11_lock_context(lib_ctx))) { - (void)talib_auth_terminate(atcab_get_device()); - } -#endif + if (CKR_OK == pkcs11_lock_device(lib_ctx)) + { + #if ATCA_TA_SUPPORT + if (atcab_is_ta_device(atcab_get_device_type())) + { + (void)talib_auth_terminate(atcab_get_device()); + } + #endif - /* Release the crypto device */ - atcab_release(); + /* Release the crypto device */ + atcab_release(); - /* Close all the sessions that might be open */ - for (; ulSlot < pkcs11_context.slot_cnt; ulSlot++) - { - pkcs11_slot_ctx_ptr slot_ctx_ptr = &((pkcs11_slot_ctx_ptr)(pkcs11_context.slots))[ulSlot]; - if (slot_ctx_ptr) + /* No more device communciation will be occuring */ + (void)pkcs11_unlock_device(lib_ctx); + } + + /* Clean up the device specific mutex if it exists*/ + if (lib_ctx->dev_lock) { - (void)pkcs11_session_closeall(slot_ctx_ptr->slot_id); + (void)pkcs11_os_destroy_mutex(lib_ctx->dev_lock); + lib_ctx->dev_lock = NULL; } - } - /* Clear the object cache */ - (void)pkcs11_object_deinit(&pkcs11_context); + /* Close all the sessions that might be open */ + for (; ulSlot < pkcs11_context.slot_cnt; ulSlot++) + { + pkcs11_slot_ctx_ptr slot_ctx_ptr = &((pkcs11_slot_ctx_ptr)(pkcs11_context.slots))[ulSlot]; + if (slot_ctx_ptr) + { + (void)pkcs11_session_closeall(slot_ctx_ptr->slot_id); + } + } - /** \todo If other threads are waiting for something to happen this call should - cause those calls to unblock and return CKR_CRYPTOKI_NOT_INITIALIZED - How - that is done by this simplified mutex API is yet to be determined */ + /* Clear the object cache */ + (void)pkcs11_object_deinit(&pkcs11_context); - pkcs11_context.initialized = FALSE; + /** \todo If other threads are waiting for something to happen this call should + cause those calls to unblock and return CKR_CRYPTOKI_NOT_INITIALIZED - How + that is done by this simplified mutex API is yet to be determined */ - return CKR_OK; + /* the library is now closing */ + (void)pkcs11_unlock_context(lib_ctx); + + /* Clean up the library lock */ + if (lib_ctx->destroy_mutex(lib_ctx->lib_lock)) + { + (void)lib_ctx->destroy_mutex(lib_ctx->lib_lock); + } + else + { + (void)pkcs11_os_destroy_mutex(lib_ctx->lib_lock); + } + lib_ctx->lib_lock = NULL; + + pkcs11_context.initialized = FALSE; + } + + return rv; } /** @} */ diff --git a/lib/pkcs11/pkcs11_init.h b/lib/pkcs11/pkcs11_init.h index b689cc864..e8499d178 100644 --- a/lib/pkcs11/pkcs11_init.h +++ b/lib/pkcs11/pkcs11_init.h @@ -43,13 +43,15 @@ typedef struct _pkcs11_lib_ctx CK_DESTROYMUTEX destroy_mutex; CK_LOCKMUTEX lock_mutex; CK_UNLOCKMUTEX unlock_mutex; - CK_VOID_PTR mutex; + CK_VOID_PTR lib_lock; + CK_VOID_PTR dev_lock; + CK_BBOOL lib_locked; CK_VOID_PTR slots; CK_ULONG slot_cnt; #if !PKCS11_USE_STATIC_CONFIG CK_CHAR config_path[200]; #endif -} pkcs11_lib_ctx, *pkcs11_lib_ctx_ptr; +} pkcs11_lib_ctx; #ifdef __cplusplus } @@ -63,4 +65,10 @@ pkcs11_lib_ctx_ptr pkcs11_get_context(void); CK_RV pkcs11_lock_context(pkcs11_lib_ctx_ptr pContext); CK_RV pkcs11_unlock_context(pkcs11_lib_ctx_ptr pContext); +CK_RV pkcs11_lock_device(pkcs11_lib_ctx_ptr pContext); +CK_RV pkcs11_unlock_device(pkcs11_lib_ctx_ptr pContext); + +CK_RV pkcs11_lock_both(pkcs11_lib_ctx_ptr pContext); +CK_RV pkcs11_unlock_both(pkcs11_lib_ctx_ptr pContext); + #endif /* PKCS11_INIT_H_ */ diff --git a/lib/pkcs11/pkcs11_key.c b/lib/pkcs11/pkcs11_key.c index 8c1a48c4e..80f4a8414 100644 --- a/lib/pkcs11/pkcs11_key.c +++ b/lib/pkcs11/pkcs11_key.c @@ -48,6 +48,8 @@ static CK_RV pkcs11_key_get_derivekey_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR if (obj_ptr) { + if (atcab_is_ca_device(atcab_get_device_type())) + { #if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; @@ -65,6 +67,11 @@ static CK_RV pkcs11_key_get_derivekey_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR return pkcs11_attrib_false(NULL, pAttribute); } #endif + } + else + { + return pkcs11_attrib_false(NULL, pAttribute); + } } return CKR_ARGUMENTS_BAD; @@ -76,6 +83,8 @@ static CK_RV pkcs11_key_get_local_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAt if (obj_ptr) { + if (atcab_is_ca_device(atcab_get_device_type())) + { #if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; @@ -93,6 +102,11 @@ static CK_RV pkcs11_key_get_local_flag(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAt return pkcs11_attrib_false(NULL, pAttribute); } #endif + } + else + { + return pkcs11_attrib_false(NULL, pAttribute); + } } return CKR_ARGUMENTS_BAD; @@ -118,10 +132,12 @@ static const CK_MECHANISM_TYPE pkcs11_key_508_private_mech[] = { CKM_ECDSA_SHA256 }; +#if ATCA_CA_SUPPORT static const CK_MECHANISM_TYPE pkcs11_key_508_secret_mech[] = { CKM_SHA256_HMAC, // CKM_SHA256_HMAC_GENERAL }; +#endif static const CK_MECHANISM_TYPE pkcs11_key_608_secret_mech[] = { CKM_SHA256_HMAC, @@ -143,6 +159,8 @@ static CK_RV pkcs11_key_get_allowed_mechanisms(CK_VOID_PTR pObject, CK_ATTRIBUTE if (obj_ptr) { + if (atcab_is_ca_device(atcab_get_device_type())) + { #if ATCA_CA_SUPPORT atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; @@ -182,6 +200,25 @@ static CK_RV pkcs11_key_get_allowed_mechanisms(CK_VOID_PTR pObject, CK_ATTRIBUTE } #endif + } + else + { + if(CKO_PRIVATE_KEY == obj_ptr->class_id) + { + return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_508_private_mech, + sizeof(pkcs11_key_508_private_mech)); + } + else if (CKO_PUBLIC_KEY == obj_ptr->class_id) + { + return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_508_public_mech, + sizeof(pkcs11_key_508_public_mech)); + } + else if (CKO_SECRET_KEY == obj_ptr->class_id) + { + return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_608_secret_mech, + sizeof(pkcs11_key_608_secret_mech)); + } + } } return CKR_ARGUMENTS_BAD; @@ -246,6 +283,7 @@ static const uint8_t pkcs11_key_ec_params[] = { 0x06, 0x08, 0x2a, 0x86, 0x48, 0x static CK_RV pkcs11_key_get_ec_params(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { + ((void)pObject); return pkcs11_attrib_fill(pAttribute, (CK_VOID_PTR)pkcs11_key_ec_params, sizeof(pkcs11_key_ec_params)); } @@ -293,6 +331,7 @@ static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr static CK_RV pkcs11_key_get_secret(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { +#if ATCA_CA_SUPPORT pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; if (obj_ptr) @@ -303,6 +342,9 @@ static CK_RV pkcs11_key_get_secret(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttrib { return CKR_ARGUMENTS_BAD; } +#else + return pkcs11_attrib_empty(pObject, pAttribute); +#endif } static CK_RV pkcs11_key_get_secret_length(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) @@ -321,6 +363,7 @@ static CK_RV pkcs11_key_get_secret_length(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR static CK_RV pkcs11_key_get_check_value(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { + ((void)pObject); return pkcs11_attrib_empty(NULL, pAttribute); #if 0 pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; @@ -354,6 +397,7 @@ static CK_RV pkcs11_key_auth_required(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAtt if (atcab_is_ca_device(atcab_get_device_type())) { #if ATCA_CA_SUPPORT + ((void)pAttribute); #endif } else @@ -727,11 +771,14 @@ const CK_ULONG pkcs11_key_secret_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs1 static CK_RV pkcs11_key_privwrite_ca(CK_VOID_PTR pSession, pkcs11_object_ptr pObject, CK_VOID_PTR pValue, CK_ULONG ulValueLen) { -#if ATCA_CA_SUPPORT + CK_RV rv = CKR_ARGUMENTS_BAD; if (pSession && pObject && pValue && ulValueLen) { + if (atcab_is_ca_device(atcab_get_device_type())) + { +#if ATCA_CA_SUPPORT pkcs11_session_ctx_ptr session_ctx = (pkcs11_session_ctx_ptr)pSession; uint8_t key_buf[36] = { 0, 0, 0, 0 }; uint8_t num_in[32] = { 0, 1, 2, 3 }; @@ -747,12 +794,17 @@ static CK_RV pkcs11_key_privwrite_ca(CK_VOID_PTR pSession, pkcs11_object_ptr pOb configuration to support this - should only be enabled for testing purposes. Production devices should never have this feature enabled. */ rv = pkcs11_util_convert_rv(atcab_priv_write(pObject->slot, key_buf, write_key_id, session_ctx->slot->read_key, num_in)); +#endif + } + else + { +#if ATCA_TA_SUPPORT + rv = pkcs11_util_convert_rv(talib_write_element(atcab_get_device(), pObject->slot, ulValueLen, pValue)); +#endif + } } return rv; -#else - return CKR_GENERAL_ERROR; -#endif } @@ -827,8 +879,7 @@ CK_RV pkcs11_key_generate pkcs11_lib_ctx_ptr pLibCtx; pkcs11_session_ctx_ptr pSession; pkcs11_object_ptr pKey = NULL; - uint8_t buf[32]; - int i; + CK_ULONG i; CK_RV rv = CKR_OK; ATCA_STATUS status = ATCA_SUCCESS; @@ -876,7 +927,7 @@ CK_RV pkcs11_key_generate if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pKey); + rv = pkcs11_object_alloc(pSession->slot->slot_id, &pKey); } if (CKR_OK == rv) @@ -887,8 +938,12 @@ CK_RV pkcs11_key_generate if (CKR_OK == rv) { - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { + if(atcab_is_ca_device(atcab_get_device_type())) + { +#if ATCA_CA_SUPPORT + uint8_t buf[32]; atecc508a_config_t * pConfig = (atecc508a_config_t*)pKey->config; if (pConfig->KeyConfig[pKey->slot] & 0x0018) @@ -908,7 +963,15 @@ CK_RV pkcs11_key_generate } } } - (void)pkcs11_unlock_context(pLibCtx); +#endif + } + else + { +#if ATCA_TA_SUPPORT + status = talib_genkey_symmetric_key(atcab_get_device(), pKey->slot); +#endif + } + (void)pkcs11_unlock_both(pLibCtx); } } @@ -952,7 +1015,7 @@ CK_RV pkcs11_key_generate_pair pkcs11_session_ctx_ptr pSession; pkcs11_object_ptr pPublic = NULL; pkcs11_object_ptr pPrivate = NULL; - int i; + CK_ULONG i; CK_RV rv = CKR_OK; rv = pkcs11_init_check(&pLibCtx, FALSE); @@ -1000,12 +1063,12 @@ CK_RV pkcs11_key_generate_pair if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pPrivate); + rv = pkcs11_object_alloc(pSession->slot->slot_id, &pPrivate); } if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pPublic); + rv = pkcs11_object_alloc(pSession->slot->slot_id, &pPublic); } if (CKR_OK == rv) @@ -1019,6 +1082,12 @@ CK_RV pkcs11_key_generate_pair if (CKR_OK == rv) { pPrivate->class_id = CKO_PRIVATE_KEY; +#if ATCA_TA_SUPPORT + (void)talib_handle_init_private_key(&pPrivate->handle_info, TA_KEY_TYPE_ECCP256, + TA_ALG_MODE_ECC_ECDSA, TA_PROP_SIGN_INT_EXT_DIGEST, + TA_PROP_NO_KEY_AGREEMENT); +#endif + rv = pkcs11_config_key(pLibCtx, pSession->slot, pPrivate, pName); } @@ -1036,7 +1105,7 @@ CK_RV pkcs11_key_generate_pair pPublic->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; #endif - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { rv = pkcs11_util_convert_rv(atcab_genkey(pPrivate->slot, NULL)); if (rv) @@ -1045,7 +1114,7 @@ CK_RV pkcs11_key_generate_pair (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pPrivate); #endif } - (void)pkcs11_unlock_context(pLibCtx); + (void)pkcs11_unlock_both(pLibCtx); } } @@ -1090,19 +1159,13 @@ static uint8_t pkcs11_key_used(uint8_t * key, size_t keylen) static CK_RV pkcs11_key_derive_ca(pkcs11_session_ctx_ptr pSession, pkcs11_object_ptr pBaseKey, pkcs11_object_ptr pSecretKey, CK_ECDH1_DERIVE_PARAMS_PTR pEcdhParameters) { -#if ATCA_CA_SUPPORT CK_RV rv = CKR_ARGUMENTS_BAD; if (pSession && pBaseKey && pSecretKey && pEcdhParameters) { - pkcs11_lib_ctx_ptr pLibCtx = pkcs11_get_context(); - - /* Use the tempkey slot id */ - pSecretKey->slot = ATCA_TEMPKEY_KEYID; pSecretKey->attributes = pkcs11_key_secret_attributes; pSecretKey->count = pkcs11_key_secret_attributes_count; pSecretKey->size = 32; - pSecretKey->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; pSecretKey->flags = PKCS11_OBJECT_FLAG_DESTROYABLE | PKCS11_OBJECT_FLAG_SENSITIVE; #ifdef ATCA_NO_HEAP if (!pkcs11_key_used(pkcs11_key_cache, sizeof(pkcs11_key_cache))) @@ -1116,11 +1179,19 @@ static CK_RV pkcs11_key_derive_ca(pkcs11_session_ctx_ptr pSession, pkcs11_object { rv = CKR_HOST_MEMORY; } - - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + else { ATCA_STATUS status = ATCA_SUCCESS; + if(atcab_is_ca_device(atcab_get_device_type())) + { + #if ATCA_CA_SUPPORT + pkcs11_lib_ctx_ptr pLibCtx = pkcs11_get_context(); + + pSecretKey->slot = ATCA_TEMPKEY_KEYID; + pSecretKey->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) + { /* Because of the number of ECDH options this function unfortunately has a complex bit of logic to walk through to select the proper ECDH command. Normally this would be left up to the user to chose */ @@ -1161,17 +1232,22 @@ static CK_RV pkcs11_key_derive_ca(pkcs11_session_ctx_ptr pSession, pkcs11_object { status = ATCA_GEN_FAIL; } + (void)pkcs11_unlock_both(pLibCtx); - (void)pkcs11_unlock_context(pLibCtx); - + } + #endif + } + else + { + #if ATCA_TA_SUPPORT + status = atcab_ecdh(pBaseKey->slot, &pEcdhParameters->pPublicData[1], pSecretKey->data); + #endif + } rv = pkcs11_util_convert_rv(status); } } return rv; -#else - return CKR_GENERAL_ERROR; -#endif } CK_RV pkcs11_key_derive @@ -1189,6 +1265,7 @@ CK_RV pkcs11_key_derive pkcs11_object_ptr pBaseKey = NULL; pkcs11_object_ptr pSecretKey = NULL; CK_ECDH1_DERIVE_PARAMS_PTR pEcdhParameters = NULL; + CK_ULONG i; CK_RV rv = CKR_OK; rv = pkcs11_init_check(&pLibCtx, FALSE); @@ -1238,10 +1315,10 @@ CK_RV pkcs11_key_derive if (CKR_OK == rv) { - rv = pkcs11_object_alloc(&pSecretKey); + rv = pkcs11_object_alloc(pSession->slot->slot_id, &pSecretKey); } - for (int i = 0; (i < ulCount) && (CKR_OK == rv); i++) + for (i = 0; (i < ulCount) && (CKR_OK == rv); i++) { if (CKA_LABEL == pTemplate[i].type) { diff --git a/lib/pkcs11/pkcs11_mech.c b/lib/pkcs11/pkcs11_mech.c index 952e557e4..92202316b 100644 --- a/lib/pkcs11/pkcs11_mech.c +++ b/lib/pkcs11/pkcs11_mech.c @@ -44,29 +44,30 @@ typedef struct _pcks11_mech_table_e #define PCKS11_MECH_ECC508_EC_CAPABILITY (CKF_EC_F_P | CKF_EC_NAMEDCURVE | CKF_EC_UNCOMPRESS) +#ifdef ATCA_ATECC508A_SUPPORT /* CK_MECHANISM_TYPE, MinKeySize, MaxKeySize, Flags */ static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { //CKM_DH_PKCS_KEY_PAIR_GEN, //CKM_DH_PKCS_DERIVE, - { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, - { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, - { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, - { CKM_GENERIC_SECRET_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, - { CKM_CONCATENATE_BASE_AND_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_CONCATENATE_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_CONCATENATE_DATA_AND_BASE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_XOR_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_EXTRACT_KEY_FROM_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SSL3_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, - { CKM_SSL3_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SSL3_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SSL3_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, - { CKM_TLS_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_TLS_PRF, { 0, 0, CKF_HW | CKF_DERIVE } }, - { CKM_SHA256_KEY_DERIVATION, { 256, 256, CKF_HW | CKF_DERIVE } }, + { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, + { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_GENERIC_SECRET_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + { CKM_CONCATENATE_BASE_AND_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_CONCATENATE_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_CONCATENATE_DATA_AND_BASE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_XOR_BASE_AND_DATA, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_EXTRACT_KEY_FROM_KEY, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SSL3_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + { CKM_SSL3_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SSL3_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SSL3_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_PRE_MASTER_KEY_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + { CKM_TLS_MASTER_KEY_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_KEY_AND_MAC_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_MASTER_KEY_DERIVE_DH, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_TLS_PRF, { 0, 0, CKF_HW | CKF_DERIVE } }, + { CKM_SHA256_KEY_DERIVATION, { 256, 256, CKF_HW | CKF_DERIVE } }, //CKM_WTLS_PRE_MASTER_KEY_GEN, //CKM_WTLS_MASTER_KEY_DERIVE, //CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC, @@ -97,13 +98,13 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { //CKM_SEED_CBC_PAD, //CKM_SEED_ECB_ENCRYPT_DATA, //CKM_SEED_CBC_ENCRYPT_DATA, - { CKM_EC_KEY_PAIR_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDSA_SHA256, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDH1_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDH1_COFACTOR_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECMQV_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDH_AES_KEY_WRAP, { 0, 0, CKF_HW | CKF_WRAP | CKF_UNWRAP | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_EC_KEY_PAIR_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDSA_SHA256, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDH1_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDH1_COFACTOR_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECMQV_DERIVE, { 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDH_AES_KEY_WRAP, { 0, 0, CKF_HW | CKF_WRAP | CKF_UNWRAP | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //CKM_FASTHASH, //CKM_AES_KEY_GEN, //CKM_AES_ECB, @@ -122,7 +123,7 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { //{CKM_AES_GMAC, //CKM_AES_ECB_ENCRYPT_DATA, //CKM_AES_CBC_ENCRYPT_DATA, - { CKM_DH_PKCS_PARAMETER_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } } + { CKM_DH_PKCS_PARAMETER_GEN, { 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } } //CKM_AES_OFB, //CKM_AES_CFB64, //CKM_AES_CFB8, @@ -131,14 +132,16 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc508[] = { //CKM_AES_KEY_WRAP, //CKM_AES_KEY_WRAP_PAD, }; +#endif +#ifdef ATCA_ATECC608_SUPPORT /* CK_MECHANISM_TYPE, MinKeySize, MaxKeySize, Flags */ static pcks11_mech_table_e pkcs11_mech_list_ecc608[] = { //CKM_DH_PKCS_KEY_PAIR_GEN, //CKM_DH_PKCS_DERIVE, - { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, - { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, - { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, + { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, //{ CKM_GENERIC_SECRET_KEY_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, //{ CKM_CONCATENATE_BASE_AND_KEY,{ 0, 0, CKF_HW | CKF_DERIVE } }, //{ CKM_CONCATENATE_BASE_AND_DATA,{ 0, 0, CKF_HW | CKF_DERIVE } }, @@ -185,8 +188,8 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc608[] = { //CKM_SEED_CBC_PAD, //CKM_SEED_ECB_ENCRYPT_DATA, //CKM_SEED_CBC_ENCRYPT_DATA, - { CKM_EC_KEY_PAIR_GEN, { 256, 256, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, - { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_EC_KEY_PAIR_GEN, { 256, 256, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //{ CKM_ECDSA_SHA256,{ 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //{ CKM_ECDH1_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //{ CKM_ECDH1_COFACTOR_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, @@ -194,22 +197,112 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc608[] = { //{ CKM_ECDH_AES_KEY_WRAP,{ 0, 0, CKF_HW | CKF_WRAP | CKF_UNWRAP | PCKS11_MECH_ECC508_EC_CAPABILITY } }, //CKM_FASTHASH, //CKM_AES_KEY_GEN, - { CKM_AES_ECB, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, - { CKM_AES_CBC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_ECB, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CBC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, //{CKM_AES_MAC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT} }, //{CKM_AES_MAC_GENERAL, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT} }, - //CKM_AES_CBC_PAD, - { CKM_AES_CTR, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, - { CKM_AES_GCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, - { CKM_AES_CCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CBC_PAD, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CTR, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_GCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + //CKM_AES_CTS, + { CKM_AES_CMAC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CMAC_GENERAL, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + //CKM_AES_XCBC_MAC, + //CKM_AES_XCBC_MAC_96, + //{CKM_AES_GMAC, + { CKM_AES_ECB_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CBC_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + //{ CKM_DH_PKCS_PARAMETER_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } } + //CKM_AES_OFB, + //CKM_AES_CFB64, + //CKM_AES_CFB8, + //CKM_AES_CFB128, + //CKM_AES_CFB1, + //CKM_AES_KEY_WRAP, + //CKM_AES_KEY_WRAP_PAD, +}; +#endif + +#ifdef ATCA_TA100_SUPPORT +/* CK_MECHANISM_TYPE, MinKeySize, MaxKeySize, Flags */ +static pcks11_mech_table_e pkcs11_mech_list_ta100[] = { + //CKM_DH_PKCS_KEY_PAIR_GEN, + //CKM_DH_PKCS_DERIVE, + { CKM_SHA256, { 256, 256, CKF_HW | CKF_DIGEST } }, + { CKM_SHA256_HMAC, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_SHA256_HMAC_GENERAL, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + //{ CKM_GENERIC_SECRET_KEY_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + //{ CKM_CONCATENATE_BASE_AND_KEY,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_CONCATENATE_BASE_AND_DATA,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_CONCATENATE_DATA_AND_BASE,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_XOR_BASE_AND_DATA,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_EXTRACT_KEY_FROM_KEY,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_SSL3_PRE_MASTER_KEY_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + //{ CKM_SSL3_MASTER_KEY_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_SSL3_KEY_AND_MAC_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_SSL3_MASTER_KEY_DERIVE_DH,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_TLS_PRE_MASTER_KEY_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + //{ CKM_TLS_MASTER_KEY_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_TLS_KEY_AND_MAC_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_TLS_MASTER_KEY_DERIVE_DH,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_TLS_PRF,{ 0, 0, CKF_HW | CKF_DERIVE } }, + //{ CKM_SHA256_KEY_DERIVATION,{ 256, 256, CKF_HW | CKF_DERIVE } }, + //CKM_WTLS_PRE_MASTER_KEY_GEN, + //CKM_WTLS_MASTER_KEY_DERIVE, + //CKM_WTLS_MASTER_KEY_DERIVE_DH_ECC, + //CKM_WTLS_PRF, + //CKM_WTLS_SERVER_KEY_AND_MAC_DERIVE, + //CKM_WTLS_CLIENT_KEY_AND_MAC_DERIVE, + //CKM_TLS10_MAC_SERVER, + //CKM_TLS10_MAC_CLIENT, + //CKM_TLS12_MAC, + //CKM_TLS12_KDF, + //CKM_TLS12_MASTER_KEY_DERIVE, + //CKM_TLS12_KEY_AND_MAC_DERIVE, + //CKM_TLS12_MASTER_KEY_DERIVE_DH, + //CKM_TLS12_KEY_SAFE_DERIVE, + //CKM_TLS_MAC, + //CKM_TLS_KDF, + //CKM_KEY_WRAP_LYNKS, + //CKM_KEY_WRAP_SET_OAEP, + //CKM_CMS_SIG, + //CKM_KIP_DERIVE, + //CKM_KIP_WRAP, + //CKM_KIP_MAC, + //CKM_SEED_KEY_GEN, + //CKM_SEED_ECB, + //CKM_SEED_CBC, + //CKM_SEED_MAC, + //CKM_SEED_MAC_GENERAL, + //CKM_SEED_CBC_PAD, + //CKM_SEED_ECB_ENCRYPT_DATA, + //CKM_SEED_CBC_ENCRYPT_DATA, + { CKM_EC_KEY_PAIR_GEN, { 256, 256, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + { CKM_ECDSA, { 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + //{ CKM_ECDSA_SHA256,{ 256, 256, CKF_HW | CKF_SIGN | CKF_VERIFY | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + //{ CKM_ECDH1_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + //{ CKM_ECDH1_COFACTOR_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + //{ CKM_ECMQV_DERIVE,{ 0, 0, CKF_HW | CKF_DERIVE | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + //{ CKM_ECDH_AES_KEY_WRAP,{ 0, 0, CKF_HW | CKF_WRAP | CKF_UNWRAP | PCKS11_MECH_ECC508_EC_CAPABILITY } }, + //CKM_FASTHASH, + //CKM_AES_KEY_GEN, + { CKM_AES_ECB, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CBC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + //{CKM_AES_MAC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT} }, + //{CKM_AES_MAC_GENERAL, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT} }, + { CKM_AES_CBC_PAD, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CTR, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_GCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CCM, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, //CKM_AES_CTS, - { CKM_AES_CMAC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, - { CKM_AES_CMAC_GENERAL, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CMAC, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CMAC_GENERAL, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, //CKM_AES_XCBC_MAC, //CKM_AES_XCBC_MAC_96, //{CKM_AES_GMAC, - { CKM_AES_ECB_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, - { CKM_AES_CBC_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_ECB_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, + { CKM_AES_CBC_ENCRYPT_DATA, { 128, 128, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, //{ CKM_DH_PKCS_PARAMETER_GEN,{ 0, 0, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } } //CKM_AES_OFB, //CKM_AES_CFB64, @@ -219,6 +312,7 @@ static pcks11_mech_table_e pkcs11_mech_list_ecc608[] = { //CKM_AES_KEY_WRAP, //CKM_AES_KEY_WRAP_PAD, }; +#endif #define TABLE_SIZE(x) sizeof(x) / sizeof(x[0]) @@ -260,7 +354,7 @@ CK_RV pkcs11_mech_get_list(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismLi pcks11_mech_table_ptr mech_list_ptr = NULL_PTR; CK_ULONG mech_cnt = 0; - if (!lib_ctx) + if (!lib_ctx || !lib_ctx->initialized) { return CKR_CRYPTOKI_NOT_INITIALIZED; } @@ -281,14 +375,24 @@ CK_RV pkcs11_mech_get_list(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismLi switch (slot_ctx->interface_config.devtype) { +#ifdef ATCA_ATECC508A_SUPPORT case ATECC508A: mech_cnt = TABLE_SIZE(pkcs11_mech_list_ecc508); mech_list_ptr = pkcs11_mech_list_ecc508; break; +#endif +#ifdef ATCA_ATECC608_SUPPORT case ATECC608: mech_cnt = TABLE_SIZE(pkcs11_mech_list_ecc608); mech_list_ptr = pkcs11_mech_list_ecc608; break; +#endif +#ifdef ATCA_TA100_SUPPORT + case TA100: + mech_cnt = TABLE_SIZE(pkcs11_mech_list_ta100); + mech_list_ptr = pkcs11_mech_list_ta100; + break; +#endif default: break; } @@ -339,12 +443,21 @@ CK_RV pkcs_mech_get_info(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM switch (slot_ctx->interface_config.devtype) { +#ifdef ATCA_ATECC508A_SUPPORT case ATECC508A: mech_info_ptr = pkcs11_mech_find_info(pkcs11_mech_list_ecc508, TABLE_SIZE(pkcs11_mech_list_ecc508), type); break; +#endif +#ifdef ATCA_ATECC608_SUPPORT case ATECC608: mech_info_ptr = pkcs11_mech_find_info(pkcs11_mech_list_ecc608, TABLE_SIZE(pkcs11_mech_list_ecc608), type); break; +#endif +#ifdef ATCA_TA100_SUPPORT + case TA100: + mech_info_ptr = pkcs11_mech_find_info(pkcs11_mech_list_ta100, TABLE_SIZE(pkcs11_mech_list_ta100), type); + break; +#endif default: break; } diff --git a/lib/pkcs11/pkcs11_mech.h b/lib/pkcs11/pkcs11_mech.h index 46f9a64a4..b98ed3443 100644 --- a/lib/pkcs11/pkcs11_mech.h +++ b/lib/pkcs11/pkcs11_mech.h @@ -34,12 +34,14 @@ extern "C" { #endif +CK_RV pkcs11_mech_get_list(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount); +CK_RV pkcs_mech_get_info(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); + + #ifdef __cplusplus } #endif -CK_RV pkcs11_mech_get_list(CK_SLOT_ID slotID, CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pulCount); -CK_RV pkcs_mech_get_info(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type, CK_MECHANISM_INFO_PTR pInfo); #endif /* PKCS11_MECH_H_ */ diff --git a/lib/pkcs11/pkcs11_object.c b/lib/pkcs11/pkcs11_object.c index fdb66dfde..9d5bc3e36 100644 --- a/lib/pkcs11/pkcs11_object.c +++ b/lib/pkcs11/pkcs11_object.c @@ -30,6 +30,7 @@ #include "pkcs11_config.h" #include "pkcs11_debug.h" #include "pkcs11_init.h" +#include "pkcs11_slot.h" #include "pkcs11_session.h" #include "pkcs11_util.h" #include "pkcs11_object.h" @@ -68,16 +69,16 @@ static CK_OBJECT_HANDLE pkcs11_object_alloc_handle(void) */ const pkcs11_attrib_model pkcs11_object_monotonic_attributes[] = { /** Object Class - CK_OBJECT_CLASS */ - { CKA_CLASS, pkcs11_object_get_class }, + { CKA_CLASS, pkcs11_object_get_class }, /** Hardware Feature Type - CK_HW_FEATURE_TYPE */ - { CKA_HW_FEATURE_TYPE, pkcs11_object_get_type }, + { CKA_HW_FEATURE_TYPE, pkcs11_object_get_type }, /** Counter will reset to a previously returned value if the token is initialized using C_InitToken. */ - { CKA_RESET_ON_INIT, pkcs11_attrib_false }, + { CKA_RESET_ON_INIT, pkcs11_attrib_false }, /** Counter has been reset at least once at some point in time. */ - { CKA_HAS_RESET, pkcs11_attrib_false }, + { CKA_HAS_RESET, pkcs11_attrib_false }, /** Current value of the monotonic counter. Big endian order. */ - { CKA_VALUE, NULL_PTR }, + { CKA_VALUE, NULL_PTR }, }; const CK_ULONG pkcs11_object_monotonic_attributes_count = PKCS11_UTIL_ARRAY_SIZE(pkcs11_object_monotonic_attributes); @@ -117,7 +118,7 @@ const CK_ULONG pkcs11_object_monotonic_attributes_count = PKCS11_UTIL_ARRAY_SIZE // //}; -CK_RV pkcs11_object_alloc(pkcs11_object_ptr * ppObject) +CK_RV pkcs11_object_alloc(CK_SLOT_ID slotId, pkcs11_object_ptr * ppObject) { CK_ULONG i; CK_RV rv = CKR_OK; @@ -144,6 +145,7 @@ CK_RV pkcs11_object_alloc(pkcs11_object_ptr * ppObject) { memset(*ppObject, 0, sizeof(pkcs11_object)); pkcs11_object_cache[i].handle = pkcs11_object_alloc_handle(); + pkcs11_object_cache[i].slotid = slotId; pkcs11_object_cache[i].object = *ppObject; } else @@ -258,6 +260,35 @@ CK_RV pkcs11_object_get_handle(pkcs11_object_ptr pObject, CK_OBJECT_HANDLE_PTR p return CKR_OK; } +CK_RV pkcs11_object_get_owner(pkcs11_object_ptr pObject, CK_SLOT_ID_PTR pSlotId) +{ + CK_RV rv = CKR_ARGUMENTS_BAD; + + if (pObject && pSlotId) + { + CK_ULONG i; + for (i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) + { + if (pObject == pkcs11_object_cache[i].object) + { + *pSlotId = pkcs11_object_cache[i].slotid; + break; + } + } + + if (PKCS11_MAX_OBJECTS_ALLOWED == i) + { + rv = CKR_OBJECT_HANDLE_INVALID; + } + else + { + rv = CKR_OK; + } + } + + return rv; +} + CK_RV pkcs11_object_get_name(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { @@ -354,7 +385,7 @@ CK_RV pkcs11_object_get_size(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObjec return CKR_OK; } -CK_RV pkcs11_object_find(pkcs11_object_ptr * ppObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) +CK_RV pkcs11_object_find(CK_SLOT_ID slotId, pkcs11_object_ptr * ppObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount) { CK_ULONG i; CK_ATTRIBUTE_PTR pName = NULL; @@ -386,7 +417,7 @@ CK_RV pkcs11_object_find(pkcs11_object_ptr * ppObject, CK_ATTRIBUTE_PTR pTemplat for (i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) { pkcs11_object_ptr pObj = pkcs11_object_cache[i].object; - if (pObj) + if (pObj && (pkcs11_object_cache[i].slotid == slotId)) { if ((pObj->class_id == class) && (strlen((char*)pObj->name) == pName->ulValueLen)) { @@ -419,7 +450,7 @@ CK_RV pkcs11_object_create CK_ATTRIBUTE_PTR pLabel = NULL; CK_OBJECT_CLASS_PTR pClass = NULL; CK_ATTRIBUTE_PTR pData = NULL; - int i; + CK_ULONG i; pkcs11_lib_ctx_ptr pLibCtx = NULL; pkcs11_session_ctx_ptr pSession = NULL; @@ -456,75 +487,88 @@ CK_RV pkcs11_object_create } } - if (pLabel && pClass) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { - if (CKR_OK != (rv = pkcs11_object_find(&pObject, pTemplate, ulCount))) + if (pLabel && pClass) { - return rv; + if (CKR_OK != (rv = pkcs11_object_find(pSession->slot->slot_id, &pObject, pTemplate, ulCount))) + { + return rv; + } + } + else + { + return CKR_ARGUMENTS_BAD; } - } - else - { - return CKR_ARGUMENTS_BAD; - } - if (!pObject) - { - /* Allocate a new object */ - rv = pkcs11_object_alloc(&pObject); - } + if (!pObject) + { + /* Allocate a new object */ + rv = pkcs11_object_alloc(pSession->slot->slot_id, &pObject); + } - if (pObject) - { - switch (*pClass) + if (pObject) { - case CKO_CERTIFICATE: - rv = pkcs11_config_cert(pLibCtx, pSession->slot, pObject, pLabel); - if (CKR_OK == rv) - { - rv = pkcs11_cert_x509_write(pObject, pData); - } - break; - case CKO_PUBLIC_KEY: - pObject->class_id = CKO_PUBLIC_KEY; - if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) + switch (*pClass) { - rv = pkcs11_key_write(pSession, pObject, pData); - if (rv) + case CKO_CERTIFICATE: + rv = pkcs11_config_cert(pLibCtx, pSession->slot, pObject, pLabel); + if (CKR_OK == rv) { -#if !PKCS11_USE_STATIC_CONFIG - (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); -#endif + rv = pkcs11_cert_x509_write(pObject, pData); } - } - break; - case CKO_PRIVATE_KEY: - pObject->class_id = CKO_PRIVATE_KEY; - if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) - { - rv = pkcs11_key_write(pSession, pObject, pData); - if (rv) + break; + case CKO_PUBLIC_KEY: + pObject->class_id = CKO_PUBLIC_KEY; + if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) { -#if !PKCS11_USE_STATIC_CONFIG - (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); -#endif + rv = pkcs11_key_write(pSession, pObject, pData); + if (rv) + { + #if !PKCS11_USE_STATIC_CONFIG + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); + #endif + } } + break; + case CKO_PRIVATE_KEY: + pObject->class_id = CKO_PRIVATE_KEY; + + #if ATCA_TA_SUPPORT + (void)talib_handle_init_private_key(&pObject->handle_info, TA_KEY_TYPE_ECCP256, + TA_ALG_MODE_ECC_ECDSA, TA_PROP_SIGN_INT_EXT_DIGEST, + TA_PROP_NO_KEY_AGREEMENT); + pObject->handle_info.property &= ~TA_PROP_EXECUTE_ONLY_KEY_GEN_MASK; + #endif + + if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) + { + rv = pkcs11_key_write(pSession, pObject, pData); + if (rv) + { + #if !PKCS11_USE_STATIC_CONFIG + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); + #endif + } + } + break; + default: + break; } - break; - default: - break; - } - if (CKR_OK == rv) - { - rv = pkcs11_object_get_handle(pObject, phObject); - } - else - { - if (pObject) + + if (CKR_OK == rv) { - (void)pkcs11_object_free(pObject); + rv = pkcs11_object_get_handle(pObject, phObject); + } + else + { + if (pObject) + { + (void)pkcs11_object_free(pObject); + } } } + (void)pkcs11_unlock_both(pLibCtx); } return rv; @@ -540,35 +584,37 @@ CK_RV pkcs11_object_destroy(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject pkcs11_lib_ctx_ptr pLibCtx = NULL; pkcs11_session_ctx_ptr pSession = NULL; - rv = pkcs11_init_check(&pLibCtx, FALSE); - if (rv) + if (CKR_OK != (rv = pkcs11_init_check(&pLibCtx, FALSE))) { return rv; } - rv = pkcs11_session_check(&pSession, hSession); - if (rv) + if (CKR_OK != (rv = pkcs11_session_check(&pSession, hSession))) { return rv; } - rv = pkcs11_object_check(&pObject, hObject); - if (rv) + if (CKR_OK != (rv = pkcs11_object_check(&pObject, hObject))) { return rv; } if (pObject->flags & PKCS11_OBJECT_FLAG_DESTROYABLE) { + if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + { #if !PKCS11_USE_STATIC_CONFIG - pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); #endif - return pkcs11_object_free(pObject); + rv = pkcs11_object_free(pObject); + (void)pkcs11_unlock_context(pLibCtx); + } } else { - return CKR_ACTION_PROHIBITED; + rv = CKR_ACTION_PROHIBITED; } + return rv; } /* Interal function to clean up resources */ @@ -577,6 +623,8 @@ CK_RV pkcs11_object_deinit(pkcs11_lib_ctx_ptr pContext) CK_RV rv = CKR_OK; int i; + ((void)pContext); + for (i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) { pkcs11_object_ptr pObj = pkcs11_object_cache[i].object; @@ -593,11 +641,13 @@ CK_RV pkcs11_object_deinit(pkcs11_lib_ctx_ptr pContext) } #if ATCA_TA_SUPPORT -CK_RV pkcs11_object_load_handle_info(pkcs11_lib_ctx_ptr pContext) +ATCA_STATUS pkcs11_object_load_handle_info(pkcs11_lib_ctx_ptr pContext) { - CK_RV rv = CKR_OK; + ATCA_STATUS status = ATCA_SUCCESS; uint8_t handle_info[TA_HANDLE_INFO_SIZE]; + ((void)pContext); + for (int i = 0; i < PKCS11_MAX_OBJECTS_ALLOWED; i++) { pkcs11_object_ptr pObj = pkcs11_object_cache[i].object; @@ -610,12 +660,13 @@ CK_RV pkcs11_object_load_handle_info(pkcs11_lib_ctx_ptr pContext) } else { + status = ATCA_GEN_FAIL; memset(&pObj->handle_info, 0, sizeof(ta_element_attributes_t)); } } } - return rv; + return status; } #endif diff --git a/lib/pkcs11/pkcs11_object.h b/lib/pkcs11/pkcs11_object.h index 4433fd779..676b39ad5 100644 --- a/lib/pkcs11/pkcs11_object.h +++ b/lib/pkcs11/pkcs11_object.h @@ -54,17 +54,19 @@ typedef struct _pkcs11_object CK_UTF8CHAR name[PKCS11_MAX_LABEL_SIZE + 1]; #if ATCA_CA_SUPPORT CK_VOID_PTR config; - CK_VOID_PTR data; #endif + CK_VOID_PTR data; #if ATCA_TA_SUPPORT ta_element_attributes_t handle_info; #endif -} pkcs11_object, *pkcs11_object_ptr; +} pkcs11_object; typedef struct _pkcs11_object_cache_t { /** Arbitrary (but unique) non-null identifier for an object */ CK_OBJECT_HANDLE handle; + /* Owner of the object */ + CK_SLOT_ID slotid; /** The actual object */ pkcs11_object_ptr object; } pkcs11_object_cache_t; @@ -81,12 +83,20 @@ extern const CK_ULONG pkcs11_object_monotonic_attributes_count; #define PKCS11_OBJECT_FLAG_TA_TYPE 0x10 #define PKCS11_OBJECT_FLAG_TRUST_TYPE 0x20 -CK_RV pkcs11_object_alloc(pkcs11_object_ptr * ppObject); +/* Object System Access */ +CK_RV pkcs11_object_alloc(CK_SLOT_ID slotId, pkcs11_object_ptr * ppObject); CK_RV pkcs11_object_free(pkcs11_object_ptr pObject); CK_RV pkcs11_object_check(pkcs11_object_ptr * ppObject, CK_OBJECT_HANDLE handle); -CK_RV pkcs11_object_find(pkcs11_object_ptr * ppObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); +CK_RV pkcs11_object_find(CK_SLOT_ID slotId, pkcs11_object_ptr * ppObject, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount); CK_RV pkcs11_object_is_private(pkcs11_object_ptr pObject, CK_BBOOL* is_private); +CK_RV pkcs11_object_deinit(pkcs11_lib_ctx_ptr pContext); +CK_RV pkcs11_object_get_owner(pkcs11_object_ptr pObject, CK_SLOT_ID_PTR pSlotId); + +#if ATCA_TA_SUPPORT +ATCA_STATUS pkcs11_object_load_handle_info(pkcs11_lib_ctx_ptr pContext); +#endif +/* Object Attributes */ CK_RV pkcs11_object_get_class(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute); CK_RV pkcs11_object_get_name(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute); CK_RV pkcs11_object_get_type(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute); @@ -94,15 +104,10 @@ CK_RV pkcs11_object_get_destroyable(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttri CK_RV pkcs11_object_get_size(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject, CK_ULONG_PTR pulSize); CK_RV pkcs11_object_get_handle(pkcs11_object_ptr pObject, CK_OBJECT_HANDLE_PTR phObject); +/* PKCS11 API */ CK_RV pkcs11_object_create(CK_SESSION_HANDLE hSession, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phObject); CK_RV pkcs11_object_destroy(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObject); -CK_RV pkcs11_object_deinit(pkcs11_lib_ctx_ptr pContext); - -#if ATCA_TA_SUPPORT -CK_RV pkcs11_object_load_handle_info(pkcs11_lib_ctx_ptr pContext); -#endif - #ifdef __cplusplus } #endif diff --git a/lib/pkcs11/pkcs11_os.c b/lib/pkcs11/pkcs11_os.c index a8d10bd6a..80b7b1820 100644 --- a/lib/pkcs11/pkcs11_os.c +++ b/lib/pkcs11/pkcs11_os.c @@ -32,22 +32,13 @@ * \defgroup pkcs11 OS Abstraction (pkcs11_so_) @{ */ -/** - * \brief Convert HAL return codes to PKCS11 return values - * \param[IN] status Code returned by hal call - */ -static CK_RV pkcs11_os_convert_rv(ATCA_STATUS status) -{ - return (ATCA_FUNC_FAIL == status) ? CKR_CANT_LOCK : pkcs11_util_convert_rv(status); -} - /** * \brief Application callback for creating a mutex object * \param[in,out] ppMutex location to receive ptr to mutex */ CK_RV pkcs11_os_create_mutex(CK_VOID_PTR_PTR ppMutex) { - return pkcs11_os_convert_rv(hal_create_mutex(ppMutex, "atpkcs11")); + return pkcs11_util_convert_rv(hal_create_mutex(ppMutex, "atpkcs11")); } /* @@ -56,7 +47,7 @@ CK_RV pkcs11_os_create_mutex(CK_VOID_PTR_PTR ppMutex) */ CK_RV pkcs11_os_destroy_mutex(CK_VOID_PTR pMutex) { - return pkcs11_os_convert_rv(hal_destroy_mutex(pMutex)); + return pkcs11_util_convert_rv(hal_destroy_mutex(pMutex)); } /* @@ -65,7 +56,7 @@ CK_RV pkcs11_os_destroy_mutex(CK_VOID_PTR pMutex) */ CK_RV pkcs11_os_lock_mutex(CK_VOID_PTR pMutex) { - return pkcs11_os_convert_rv(hal_lock_mutex(pMutex)); + return pkcs11_util_convert_rv(hal_lock_mutex(pMutex)); } /* @@ -74,7 +65,7 @@ CK_RV pkcs11_os_lock_mutex(CK_VOID_PTR pMutex) */ CK_RV pkcs11_os_unlock_mutex(CK_VOID_PTR pMutex) { - return pkcs11_os_convert_rv(hal_unlock_mutex(pMutex)); + return pkcs11_util_convert_rv(hal_unlock_mutex(pMutex)); } /** @} */ diff --git a/lib/pkcs11/pkcs11_session.c b/lib/pkcs11/pkcs11_session.c index 16821a94d..5654bbe9c 100644 --- a/lib/pkcs11/pkcs11_session.c +++ b/lib/pkcs11/pkcs11_session.c @@ -26,7 +26,6 @@ */ #include "cryptoauthlib.h" -#include "crypto/atca_crypto_sw_rand.h" #include "host/atca_host.h" #include "pkcs11_config.h" @@ -371,6 +370,8 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK uint16_t key_len = is_ca_device ? 32 : 16; CK_RV rv; + ((void)userType); + #if ATCA_TA_SUPPORT ATCA_STATUS status; #endif @@ -401,7 +402,7 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK return CKR_USER_ALREADY_LOGGED_IN; } - if (CKR_OK == (rv = pkcs11_lock_context(pLibCtx))) + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { #ifndef PKCS11_PIN_KDF_ALWAYS if (2 * key_len == ulPinLen) @@ -419,7 +420,7 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK } } -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && ATCA_HOSTLIB_EN if (CKR_OK == rv && atcab_is_ta_device(atcab_get_device_type())) { uint8_t auth_i_nonce[16]; @@ -428,7 +429,7 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK (void)atcac_sw_random(auth_r_nonce, sizeof(auth_r_nonce)); status = talib_auth_generate_nonce(_gDevice, 0x4100, - TA_AUTH_GENERATE_OPT_NONCE_SRC_MASK | TA_AUTH_GENERATE_OPT_RANDOM_MASK, auth_i_nonce); + TA_AUTH_GENERATE_OPT_NONCE_SRC_MASK | TA_AUTH_GENERATE_OPT_RANDOM_MASK, auth_i_nonce); if (CKR_OK == (rv = pkcs11_util_convert_rv(status))) { @@ -443,8 +444,7 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK } } #endif - - (void)pkcs11_unlock_context(pLibCtx); + (void)pkcs11_unlock_both(pLibCtx); } if (CKR_OK == rv) @@ -457,6 +457,7 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK CK_RV pkcs11_session_logout(CK_SESSION_HANDLE hSession) { + CK_RV rv = CKR_OK; pkcs11_lib_ctx_ptr lib_ctx = pkcs11_get_context(); pkcs11_session_ctx_ptr session_ctx = pkcs11_get_session_context(hSession); @@ -478,16 +479,20 @@ CK_RV pkcs11_session_logout(CK_SESSION_HANDLE hSession) #if ATCA_TA_SUPPORT if (session_ctx->slot->logged_in && atcab_is_ta_device(atcab_get_device_type())) { - (void)talib_auth_terminate(atcab_get_device()); + if (CKR_OK == (rv = pkcs11_lock_both(lib_ctx))) + { + (void)talib_auth_terminate(atcab_get_device()); + (void)pkcs11_unlock_both(lib_ctx); + } } #endif - /* Wipe the io protection secret */ + /* Wipe the io protection secret regardless if the above operatios succeeded */ (void)pkcs11_util_memset(session_ctx->slot->read_key, sizeof(session_ctx->slot->read_key), 0, sizeof(session_ctx->slot->read_key)); session_ctx->slot->logged_in = FALSE; - return CKR_OK; + return rv; } #if 0 diff --git a/lib/pkcs11/pkcs11_session.h b/lib/pkcs11/pkcs11_session.h index cd0082168..f7698fb3e 100644 --- a/lib/pkcs11/pkcs11_session.h +++ b/lib/pkcs11/pkcs11_session.h @@ -37,21 +37,30 @@ extern "C" { /* Some mechanism require the context to be initialized first and it is done in a previous command than the target operation */ -typedef union _pkcs11_session_mech_ctx +typedef struct _pkcs11_session_mech_ctx { - struct - { - atca_hmac_sha256_ctx_t context; - } hmac; - struct - { - atca_aes_cmac_ctx_t context; - } cmac; - struct - { +#if PKCS11_HARDWARE_SHA256 + atca_hmac_sha256_ctx_t hmac; + atca_sha256_ctx_t sha256; +#else + atcac_hmac_sha256_ctx hmac; + atcac_sha2_256_ctx sha256; +#endif + atca_aes_cmac_ctx_t cmac; + atca_aes_cbc_ctx_t cbc; +#ifdef ATCA_ATECC608_SUPPORT + struct { atca_aes_gcm_ctx_t context; CK_BYTE tag_len; } gcm; +#endif +#ifdef ATCA_TA100_SUPPORT + struct { + uint8_t iv[TA_AES_GCM_IV_LENGTH]; + uint8_t aad[ATCA_AES128_BLOCK_SIZE]; + CK_BYTE aad_len; + } gcm_single; +#endif } pkcs11_session_mech_ctx, *pkcs11_session_mech_ctx_ptr; /** Session Context */ diff --git a/lib/pkcs11/pkcs11_signature.c b/lib/pkcs11/pkcs11_signature.c index 761fe1d56..34c79979a 100644 --- a/lib/pkcs11/pkcs11_signature.c +++ b/lib/pkcs11/pkcs11_signature.c @@ -96,7 +96,16 @@ CK_RV pkcs11_signature_sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_UL CK_RV rv; ATCA_STATUS status; - ((void)ulDataLen); + /* Check parameters */ + if (!pData || !pSignature || !pulSignatureLen) + { + return CKR_ARGUMENTS_BAD; + } + + if (!ulDataLen) + { + return CKR_DATA_LEN_RANGE; + } rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) @@ -116,57 +125,31 @@ CK_RV pkcs11_signature_sign(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_UL return rv; } - /* Check parameters */ - if (pulSignatureLen) + if (CKR_OK != (rv = pkcs11_lock_both(pLibCtx))) { - if (pSignature) - { - if (CKR_OK != (rv = pkcs11_lock_context(pLibCtx))) - { - return rv; - } - - switch (pSession->active_mech) - { - case CKM_SHA256_HMAC: - status = atcab_sha_hmac(pData, ulDataLen, pKey->slot, pSignature, SHA_MODE_TARGET_OUT_ONLY); - *pulSignatureLen = ATCA_SHA256_DIGEST_SIZE; - break; - case CKM_ECDSA: - status = atcab_sign(pKey->slot, pData, pSignature); - *pulSignatureLen = ATCA_SIG_SIZE; - break; - default: - status = ATCA_GEN_FAIL; - break; - } - pSession->active_mech = CKM_VENDOR_DEFINED; + return rv; + } - (void)pkcs11_unlock_context(pLibCtx); - if (CKR_OK == rv && ATCA_SUCCESS != status) - { - return pkcs11_util_convert_rv(status); - } - } - else - { - switch (pSession->active_mech) - { - case CKM_SHA256_HMAC: - *pulSignatureLen = ATCA_SHA256_DIGEST_SIZE; - break; - case CKM_ECDSA: - *pulSignatureLen = ATCA_SIG_SIZE; - break; - default: - status = ATCA_GEN_FAIL; - break; - } - } + switch (pSession->active_mech) + { + case CKM_SHA256_HMAC: + status = atcab_sha_hmac(pData, ulDataLen, pKey->slot, pSignature, SHA_MODE_TARGET_OUT_ONLY); + *pulSignatureLen = ATCA_SHA256_DIGEST_SIZE; + break; + case CKM_ECDSA: + status = atcab_sign(pKey->slot, pData, pSignature); + *pulSignatureLen = ATCA_ECCP256_SIG_SIZE; + break; + default: + status = ATCA_GEN_FAIL; + break; } - else + pSession->active_mech = CKM_VENDOR_DEFINED; + + (void)pkcs11_unlock_both(pLibCtx); + if (CKR_OK == rv && ATCA_SUCCESS != status) { - return CKR_ARGUMENTS_BAD; + return pkcs11_util_convert_rv(status); } return CKR_OK; @@ -274,12 +257,12 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ } /* Check parameters */ - if (!pData || ulDataLen != ATCA_SHA256_DIGEST_SIZE || !pSignature || ulSignatureLen != ATCA_ECCP256_SIG_SIZE) + if (!pData || !pSignature) { return CKR_ARGUMENTS_BAD; } - if (CKR_OK != (rv = pkcs11_lock_context(pLibCtx))) + if (CKR_OK != (rv = pkcs11_lock_both(pLibCtx))) { return rv; } @@ -289,6 +272,19 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ case CKM_SHA256_HMAC: { uint8_t buf[ATCA_SHA256_DIGEST_SIZE]; + + /* Checking Data length */ + if (!ulDataLen) + { + return CKR_DATA_LEN_RANGE; + } + + /* Checking Signature length */ + if (ulSignatureLen != ATCA_SHA256_DIGEST_SIZE) + { + return CKR_SIGNATURE_LEN_RANGE; + } + if (ATCA_SUCCESS == (status = atcab_sha_hmac(pData, ulDataLen, pKey->slot, buf, SHA_MODE_TARGET_OUT_ONLY))) { if (!memcmp(pSignature, buf, ATCA_SHA256_DIGEST_SIZE)) @@ -299,6 +295,18 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ } break; case CKM_ECDSA: + /* Checking data length */ + if (ulDataLen != ATCA_SHA256_DIGEST_SIZE) + { + return CKR_DATA_LEN_RANGE; + } + + /* Checking Signature length */ + if (ulSignatureLen != ATCA_ECCP256_SIG_SIZE) + { + return CKR_SIGNATURE_LEN_RANGE; + } + if (CKR_OK == (rv = pkcs11_object_is_private(pKey, &is_private))) { if (is_private) @@ -326,7 +334,7 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ } pSession->active_mech = CKM_VENDOR_DEFINED; - (void)pkcs11_unlock_context(pLibCtx); + (void)pkcs11_unlock_both(pLibCtx); if (ATCA_SUCCESS == status) { diff --git a/lib/pkcs11/pkcs11_slot.c b/lib/pkcs11/pkcs11_slot.c index 232d5a151..04ba37672 100644 --- a/lib/pkcs11/pkcs11_slot.c +++ b/lib/pkcs11/pkcs11_slot.c @@ -56,19 +56,46 @@ static pkcs11_slot_ctx pkcs11_slot_cache[PKCS11_MAX_SLOTS_ALLOWED]; */ pkcs11_slot_ctx_ptr pkcs11_slot_get_context(pkcs11_lib_ctx_ptr lib_ctx, CK_SLOT_ID slotID) { - pkcs11_slot_ctx_ptr rv = NULL_PTR; + if (!lib_ctx) + { + lib_ctx = pkcs11_get_context(); + } - if (lib_ctx) + if (lib_ctx && lib_ctx->slots) { - if (lib_ctx->slots) + pkcs11_slot_ctx_ptr rv = (pkcs11_slot_ctx_ptr)lib_ctx->slots; + CK_ULONG idx =0; + for (idx=0; idxslot_cnt; idx++, rv++) { - if (slotID < lib_ctx->slot_cnt) + if (rv->slot_id == slotID) { - rv = &((pkcs11_slot_ctx_ptr)lib_ctx->slots)[slotID]; + return rv; } } } - return rv; + return NULL; +} + +pkcs11_slot_ctx_ptr pkcs11_slot_get_new_context(pkcs11_lib_ctx_ptr lib_ctx) +{ + if (!lib_ctx) + { + lib_ctx = pkcs11_get_context(); + } + + if (lib_ctx && lib_ctx->slots) + { + pkcs11_slot_ctx_ptr rv = (pkcs11_slot_ctx_ptr)lib_ctx->slots; + CK_ULONG idx =0; + for (idx=0; idxslot_cnt; idx++, rv++) + { + if (!rv->label[0]) + { + return rv; + } + } + } + return NULL; } CK_VOID_PTR pkcs11_slot_initslots(CK_ULONG pulCount) @@ -119,6 +146,10 @@ CK_RV pkcs11_slot_config(CK_SLOT_ID slotID) return rv; } +#if defined(ATCA_HAL_KIT_BRIDGE) && defined(PKCS11_TESTING_ENABLE) +extern ATCA_STATUS hal_kit_bridge_connect(ATCAIfaceCfg *, int, char **); +#endif + #if PKCS11_508_SUPPORT && PKCS11_608_SUPPORT static ATCA_STATUS pkcs11_slot_check_device_type(ATCAIfaceCfg * ifacecfg) { @@ -155,6 +186,7 @@ static ATCA_STATUS pkcs11_slot_check_device_type(ATCAIfaceCfg * ifacecfg) } #endif +/** \brief This is an internal function that initializes a pkcs11 slot - it must already have the locks in place before being called. */ CK_RV pkcs11_slot_init(CK_SLOT_ID slotID) { pkcs11_lib_ctx_ptr lib_ctx = pkcs11_get_context(); @@ -188,27 +220,33 @@ CK_RV pkcs11_slot_init(CK_SLOT_ID slotID) retries = 2; do { +#if defined(ATCA_HAL_KIT_BRIDGE) && defined(PKCS11_TESTING_ENABLE) + if (ATCA_KIT_IFACE == ifacecfg->iface_type) + { + int argc = 3; + char * argv[3]; + pkcs11_config_split_string((char*)slot_ctx->devpath, ':', &argc, argv); + status = hal_kit_bridge_connect(ifacecfg, argc, argv); + } +#endif + /* If a PKCS11 was killed an left the device in the idle state then starting up again will require the device to go back to a known state that is accomplished here by retrying the initalization */ - status = atcab_init(ifacecfg); + if(ATCA_SUCCESS == status) + { + status = atcab_init(ifacecfg); + } } while (retries-- && status); #ifdef ATCA_HAL_I2C if (ATCA_SUCCESS != status) { -#ifdef ATCA_ENABLE_DEPRECATED - if (0xC0 != ifacecfg->atcai2c.slave_address) - { - /* Try the default address */ - ifacecfg->atcai2c.slave_address = 0xC0; -#else - if (0xC0 != ifacecfg->atcai2c.address) + if (0xC0 != ATCA_IFACECFG_VALUE(ifacecfg, atcai2c.address)) { /* Try the default address */ - ifacecfg->atcai2c.address = 0xC0; -#endif + ATCA_IFACECFG_VALUE(ifacecfg, atcai2c.address) = 0xC0; atcab_release(); atca_delay_ms(1); retries = 2; @@ -304,7 +342,7 @@ CK_RV pkcs11_slot_get_list(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_U pkcs11_lib_ctx_ptr lib_ctx = pkcs11_get_context(); CK_ULONG slot_cnt = 0; - if (!lib_ctx) + if (!lib_ctx || !lib_ctx->initialized) { return CKR_CRYPTOKI_NOT_INITIALIZED; } @@ -353,6 +391,7 @@ CK_RV pkcs11_slot_get_info(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) pkcs11_slot_ctx_ptr slot_ctx; ATCAIfaceCfg *if_cfg_ptr; CK_UTF8CHAR buf[8]; + CK_RV rv = CKR_OK; if (!lib_ctx || !lib_ctx->initialized) { @@ -409,16 +448,16 @@ CK_RV pkcs11_slot_get_info(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) if (slot_ctx->initialized) { - (void)pkcs11_lock_context(lib_ctx); - - if (!atcab_info(buf)) + if (CKR_OK == (rv = pkcs11_lock_both(lib_ctx))) { - /* SHA204 = 00 02 00 09, ECC508 = 00 00 50 00, AES132 = 0A 07*/ - pInfo->hardwareVersion.major = 0; - pInfo->hardwareVersion.minor = buf[3]; + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_info(buf)))) + { + /* SHA204 = 00 02 00 09, ECC508 = 00 00 50 00, AES132 = 0A 07*/ + pInfo->hardwareVersion.major = 0; + pInfo->hardwareVersion.minor = buf[3]; + } + (void)pkcs11_unlock_both(lib_ctx); } - - (void)pkcs11_unlock_context(lib_ctx); } /* Use the same manufacturer ID we use throughout */ @@ -428,7 +467,7 @@ CK_RV pkcs11_slot_get_info(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) pkcs11_util_escape_string(pInfo->manufacturerID, sizeof(pInfo->manufacturerID)); pkcs11_util_escape_string(pInfo->slotDescription, sizeof(pInfo->slotDescription)); - return CKR_OK; + return rv; } /** @} */ diff --git a/lib/pkcs11/pkcs11_slot.h b/lib/pkcs11/pkcs11_slot.h index 5069840e2..a3e5136e8 100644 --- a/lib/pkcs11/pkcs11_slot.h +++ b/lib/pkcs11/pkcs11_slot.h @@ -46,6 +46,10 @@ typedef struct _pkcs11_slot_ctx CK_SESSION_HANDLE session; #if ATCA_CA_SUPPORT atecc608_config_t cfg_zone; +#endif +#if ((defined(ATCA_HAL_KIT_BRIDGE) && defined(PKCS11_TESTING_ENABLE)) || \ + (defined(__linux__) && (defined(ATCA_HAL_SWI_UART) || defined(ATCA_HAL_KIT_UART)))) + uint8_t devpath[24]; #endif CK_FLAGS flags; uint16_t user_pin_handle; @@ -55,7 +59,7 @@ typedef struct _pkcs11_slot_ctx #endif CK_BBOOL logged_in; CK_BYTE read_key[32]; /**< Accepted through C_Login as the user pin */ -} pkcs11_slot_ctx, *pkcs11_slot_ctx_ptr; +} pkcs11_slot_ctx; #ifdef __cplusplus } @@ -65,6 +69,7 @@ CK_RV pkcs11_slot_init(CK_SLOT_ID slotID); CK_RV pkcs11_slot_config(CK_SLOT_ID slotID); CK_VOID_PTR pkcs11_slot_initslots(CK_ULONG pulCount); pkcs11_slot_ctx_ptr pkcs11_slot_get_context(pkcs11_lib_ctx_ptr lib_ctx, CK_SLOT_ID slotID); +pkcs11_slot_ctx_ptr pkcs11_slot_get_new_context(pkcs11_lib_ctx_ptr lib_ctx); CK_RV pkcs11_slot_get_list(CK_BBOOL tokenPresent, CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount); diff --git a/lib/pkcs11/pkcs11_token.c b/lib/pkcs11/pkcs11_token.c index 2fae57757..239f6bcc6 100644 --- a/lib/pkcs11/pkcs11_token.c +++ b/lib/pkcs11/pkcs11_token.c @@ -36,6 +36,7 @@ #include "pkcs11_key.h" #include "pkcs11_cert.h" #include "pkcs11_session.h" +#include "pkcs11_util.h" #ifndef ATCA_SERIAL_NUM_SIZE @@ -101,7 +102,7 @@ static char * pkcs11_token_device(ATCADeviceType dev_type, uint8_t info[4]) rv = "ATECC508A"; break; case 0x60: - if (info[3] >= 0x03) + if (0x02 < info[1]) { rv = "ATECC608B"; } @@ -125,7 +126,7 @@ static char * pkcs11_token_device(ATCADeviceType dev_type, uint8_t info[4]) CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinLen, CK_UTF8CHAR_PTR pLabel) { -#if PKCS11_TOKEN_INIT_SUPPORT +#if PKCS11_TOKEN_INIT_SUPPORT && defined(ATCA_ATECC608_SUPPORT) CK_RV rv; uint8_t buf[32]; uint8_t * pConfig = NULL; @@ -133,6 +134,8 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL pkcs11_lib_ctx_ptr pLibCtx; pkcs11_slot_ctx_ptr pSlotCtx; + ((void)pLabel); + rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) { @@ -302,6 +305,10 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL return CKR_OK; } #else + ((void)slotID); + ((void)pPin); + ((void)ulPinLen); + ((void)pLabel); return CKR_FUNCTION_NOT_SUPPORTED; #endif } @@ -349,25 +356,80 @@ CK_RV pkcs11_token_get_access_type(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttrib CK_RV pkcs11_token_get_writable(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; + CK_RV rv = CKR_ARGUMENTS_BAD; if (obj_ptr) { -#if ATCA_CA_SUPPORT - atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; - - if ((ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]) || - (ATCA_SLOT_CONFIG_IS_SECRET_MASK & pConfig->SlotConfig[obj_ptr->slot])) + if(atcab_is_ca_device(atcab_get_device_type())) { - return pkcs11_attrib_false(pObject, pAttribute); + #if ATCA_CA_SUPPORT + atecc508a_config_t * pConfig = (atecc508a_config_t*)obj_ptr->config; + + if ((ATCA_KEY_CONFIG_PRIVATE_MASK & pConfig->KeyConfig[obj_ptr->slot]) || + (ATCA_SLOT_CONFIG_IS_SECRET_MASK & pConfig->SlotConfig[obj_ptr->slot])) + { + rv = pkcs11_attrib_false(pObject, pAttribute); + } + else + { + rv = pkcs11_attrib_true(pObject, pAttribute); + } + #endif } else { - return pkcs11_attrib_true(pObject, pAttribute); + #if ATCA_TA_SUPPORT + uint8_t perm = (obj_ptr->handle_info.permission & TA_PERM_WRITE_MASK >> TA_PERM_WRITE_SHIFT); + + if (TA_PERM_ALWAYS == perm) + { + rv = pkcs11_attrib_true(pObject, pAttribute); + } + else if (TA_PERM_NEVER == perm) + { + rv = pkcs11_attrib_false(pObject, pAttribute); + } + else + { + CK_SLOT_ID slotid; + CK_RV rv = pkcs11_object_get_owner(pObject, &slotid); + if (CKR_OK == rv) + { + rv = CKR_ARGUMENTS_BAD; + pkcs11_slot_ctx_ptr slot_ctx = pkcs11_slot_get_context(NULL, slotid); + if(slot_ctx && slot_ctx->logged_in && (slot_ctx->so_pin_handle != 0xFFFF)) + { + if (TA_PERM_AUTH == perm) + { + if((slot_ctx->user_pin_handle & 0xFF) == obj_ptr->handle_info.write_key) + { + rv = pkcs11_attrib_true(pObject, pAttribute); + } + } + else + { + uint8_t user_pin_info[TA_HANDLE_INFO_SIZE]; + if (ATCA_SUCCESS == talib_info_get_handle_info(atcab_get_device(), obj_ptr->slot, user_pin_info)) + { + if(obj_ptr->handle_info.write_key == (user_pin_info[1] & obj_ptr->handle_info.write_key)) + { + rv = pkcs11_attrib_true(pObject, pAttribute); + } + } + } + } + } + } + + if(CKR_OK != rv) + { + rv = pkcs11_attrib_false(pObject, pAttribute); + } + #endif } -#endif } - return CKR_ARGUMENTS_BAD; + return rv; } CK_RV pkcs11_token_get_storage(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) @@ -392,6 +454,7 @@ CK_RV pkcs11_token_get_info(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) pkcs11_lib_ctx_ptr lib_ctx = pkcs11_get_context(); pkcs11_slot_ctx_ptr slot_ctx; CK_UTF8CHAR buf[16]; + CK_RV rv = CKR_OK; bool lock = FALSE; if (!lib_ctx || !lib_ctx->initialized) @@ -428,8 +491,8 @@ CK_RV pkcs11_token_get_info(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) pInfo->ulMinPinLen = 0; pInfo->flags = CKF_RNG;// | CKF_LOGIN_REQUIRED; - pInfo->ulMaxSessionCount = PKCS11_MAX_SESSIONS_ALLOWED; - pInfo->ulMaxRwSessionCount = PKCS11_MAX_SESSIONS_ALLOWED; + pInfo->ulMaxSessionCount = 1; + pInfo->ulMaxRwSessionCount = 1; pInfo->ulSessionCount = (slot_ctx->session) ? TRUE : FALSE; pInfo->ulRwSessionCount = (slot_ctx->session) ? TRUE : FALSE; @@ -438,71 +501,94 @@ CK_RV pkcs11_token_get_info(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) if (slot_ctx->initialized) { - (void)pkcs11_lock_context(lib_ctx); - - /* Read the serial number */ - if (!atcab_read_serial_number(buf)) + if (CKR_OK == (rv = pkcs11_lock_both(lib_ctx))) { + do + { + /* Read the serial number */ + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_read_serial_number(buf)))) + { #ifdef PKCS11_LABEL_IS_SERNUM - size_t len = sizeof(pInfo->label); - (void)atcab_bin2hex_(buf, 9, (char*)pInfo->label, &len, FALSE, FALSE, TRUE); - memcpy(pInfo->serialNumber, &pInfo->label[2], sizeof(pInfo->serialNumber)); + size_t len = sizeof(pInfo->label); + (void)atcab_bin2hex_(buf, 9, (char*)pInfo->label, &len, FALSE, FALSE, TRUE); + memcpy(pInfo->serialNumber, &pInfo->label[2], sizeof(pInfo->serialNumber)); #else - size_t len = sizeof(pInfo->serialNumber); - (void)atcab_bin2hex_(&buf[1], 8, (char*)pInfo->serialNumber, &len, FALSE, FALSE, TRUE); + size_t len = sizeof(pInfo->serialNumber); + (void)atcab_bin2hex_(&buf[1], 8, (char*)pInfo->serialNumber, &len, FALSE, FALSE, TRUE); #endif - } + } + else + { + break; + } #ifndef PKCS11_LABEL_IS_SERNUM - memcpy(pInfo->label, slot_ctx->label, strlen(slot_ctx->label)); + memcpy(pInfo->label, slot_ctx->label, strlen((char*)slot_ctx->label)); #endif - /* Read the hardware revision data */ - if (!atcab_info(buf)) - { - /* SHA204 = 00 02 00 09, ECC508 = 00 00 50 00, AES132 = 0A 07*/ - pInfo->hardwareVersion.major = 0; - pInfo->hardwareVersion.minor = buf[3]; - snprintf((char*)pInfo->model, sizeof(pInfo->model), "%s", pkcs11_token_device(slot_ctx->interface_config.devtype, buf)); - } + /* Read the hardware revision data */ + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_info(buf)))) + { + /* SHA204 = 00 02 00 09, ECC508 = 00 00 50 00, AES132 = 0A 07*/ + pInfo->hardwareVersion.major = 0; + pInfo->hardwareVersion.minor = buf[3]; + snprintf((char*)pInfo->model, sizeof(pInfo->model), "%s", pkcs11_token_device(slot_ctx->interface_config.devtype, buf)); + } + else + { + break; + } - /* Check if the device locks are set */ - if (ATCA_SUCCESS == atcab_is_data_locked(&lock)) - { - if (lock) - { - pInfo->flags |= CKF_TOKEN_INITIALIZED; - PKCS11_DEBUG("Token Locked\r\n"); - } - } + /* Check if the device locks are set */ + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_is_data_locked(&lock)))) + { + if (lock) + { + pInfo->flags |= CKF_TOKEN_INITIALIZED; + PKCS11_DEBUG("Token Locked\r\n"); + } + } + else + { + break; + } - /* Check if the device locks are set */ - if (slot_ctx->user_pin_handle != 0xFFFF) - { - if (ATCA_SUCCESS == atcab_is_slot_locked(slot_ctx->user_pin_handle, &lock)) - { - if (lock) + /* Check if the device locks are set */ + if (slot_ctx->user_pin_handle != 0xFFFF) { - pInfo->flags |= CKF_USER_PIN_INITIALIZED; - PKCS11_DEBUG("Pin Slot Locked\r\n"); + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_is_slot_locked(slot_ctx->user_pin_handle, &lock)))) + { + if (lock) + { + pInfo->flags |= CKF_USER_PIN_INITIALIZED; + PKCS11_DEBUG("Pin Slot Locked\r\n"); + } + } + else + { + break; + } + pInfo->flags |= CKF_LOGIN_REQUIRED; } - } - pInfo->flags |= CKF_LOGIN_REQUIRED; - } - if (slot_ctx->so_pin_handle != 0xFFFF) - { - if (ATCA_SUCCESS == atcab_is_slot_locked(slot_ctx->so_pin_handle, &lock)) - { - if (lock) + if (slot_ctx->so_pin_handle != 0xFFFF) { - pInfo->flags |= CKF_SO_PIN_LOCKED; - PKCS11_DEBUG("Pin Slot Locked\r\n"); + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_is_slot_locked(slot_ctx->so_pin_handle, &lock)))) + { + if (lock) + { + pInfo->flags |= CKF_SO_PIN_LOCKED; + PKCS11_DEBUG("Pin Slot Locked\r\n"); + } + } + else + { + break; + } } - } + } while (0); + (void)pkcs11_unlock_both(lib_ctx); } - - (void)pkcs11_unlock_context(lib_ctx); } /* Use the same manufacturer ID we use throughout */ @@ -514,7 +600,7 @@ CK_RV pkcs11_token_get_info(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) pkcs11_util_escape_string(pInfo->model, sizeof(pInfo->model)); pkcs11_util_escape_string(pInfo->serialNumber, sizeof(pInfo->serialNumber)); - return CKR_OK; + return rv; } /** @@ -524,7 +610,6 @@ CK_RV pkcs11_token_random(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, C { pkcs11_session_ctx_ptr pSession; pkcs11_lib_ctx_ptr lib_ctx; - ATCA_STATUS status; uint8_t buf[32]; CK_RV rv; @@ -545,32 +630,28 @@ CK_RV pkcs11_token_random(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pRandomData, C return rv; } - do + if (CKR_OK == (rv = pkcs11_lock_both(lib_ctx))) { - (void)pkcs11_lock_context(lib_ctx); - - status = atcab_random(buf); - - (void)pkcs11_unlock_context(lib_ctx); - - if (status) - { - return CKR_DEVICE_ERROR; - } - - if (32 < ulRandomLen) - { - memcpy(pRandomData, buf, 32); - pRandomData += 32; - ulRandomLen -= 32; - } - else + do { - memcpy(pRandomData, buf, ulRandomLen); - ulRandomLen = 0; + if (CKR_OK == (rv = pkcs11_util_convert_rv(atcab_random(buf)))) + { + if (32 < ulRandomLen) + { + memcpy(pRandomData, buf, 32); + pRandomData += 32; + ulRandomLen -= 32; + } + else + { + memcpy(pRandomData, buf, ulRandomLen); + ulRandomLen = 0; + } + } } + while (CKR_OK == rv && ulRandomLen); + (void)pkcs11_unlock_both(lib_ctx); } - while (ulRandomLen); return CKR_OK; } @@ -640,6 +721,9 @@ CK_RV pkcs11_token_set_pin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, bool is_ca_device = atcab_is_ca_device(atcab_get_device_type()); uint16_t key_len = is_ca_device ? 32 : 16; + ((void)pOldPin); + ((void)ulOldLen); + rv = pkcs11_init_check(&pLibCtx, FALSE); if (rv) { @@ -689,7 +773,11 @@ CK_RV pkcs11_token_set_pin(CK_SESSION_HANDLE hSession, CK_UTF8CHAR_PTR pOldPin, if (CKR_OK == rv) { - rv = atcab_write_zone(ATCA_ZONE_DATA, pin_slot, 0, 0, buf, sizeof(buf)); + if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + { + rv = atcab_write_zone(ATCA_ZONE_DATA, pin_slot, 0, 0, buf, sizeof(buf)); + (void)pkcs11_unlock_device(pLibCtx); + } } (void)pkcs11_unlock_context(pLibCtx); diff --git a/lib/pkcs11/pkcs11_util.c b/lib/pkcs11/pkcs11_util.c index f1444984c..d10e58892 100644 --- a/lib/pkcs11/pkcs11_util.c +++ b/lib/pkcs11/pkcs11_util.c @@ -64,8 +64,16 @@ CK_RV pkcs11_util_convert_rv(ATCA_STATUS status) { case ATCA_SUCCESS: return CKR_OK; - default: + case ATCA_FUNC_FAIL: + /* fallthrough */ + case ATCA_GEN_FAIL: + /* fallthrough */ + case ATCA_BAD_PARAM: + /* fallthrough */ + case ATCA_NOT_INITIALIZED: return CKR_FUNCTION_FAILED; + default: + return CKR_DEVICE_ERROR; } } diff --git a/lib/wolfssl/atca_wolfssl_interface.c b/lib/wolfssl/atca_wolfssl_interface.c index 49e607fa3..a623c544c 100644 --- a/lib/wolfssl/atca_wolfssl_interface.c +++ b/lib/wolfssl/atca_wolfssl_interface.c @@ -326,6 +326,8 @@ ATCA_STATUS atcac_sha256_hmac_finish( size_t* digest_len /**< [inout] length of hmac */ ) { + ((void)digest_len); + int ret = wc_HmacFinal(ctx, digest); wc_HmacFree(ctx); @@ -338,15 +340,17 @@ ATCA_STATUS atcac_sha256_hmac_finish( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_init( - atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ - uint8_t* buf, /**< [in] buffer containing a pem encoded key */ - size_t buflen, /**< [in] length of the input buffer */ - uint8_t key_type, - bool pubkey /**< [in] buffer is a public key */ + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + const uint8_t* buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + uint8_t key_type, + bool pubkey /**< [in] buffer is a public key */ ) { ATCA_STATUS status = ATCA_BAD_PARAM; + ((void)buflen); + if (ctx) { if (!key_type) @@ -362,7 +366,7 @@ ATCA_STATUS atcac_pk_init( if (pubkey) { /* Configure the public key */ - ret = wc_ecc_import_unsigned((ecc_key*)ctx->ptr, buf, &buf[32], NULL, ECC_SECP256R1); + ret = wc_ecc_import_unsigned((ecc_key*)ctx->ptr, (byte*)buf, (byte*)&buf[32], NULL, ECC_SECP256R1); } else { @@ -391,10 +395,10 @@ ATCA_STATUS atcac_pk_init( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_init_pem( - atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ - uint8_t * buf, /**< [in] buffer containing a pem encoded key */ - size_t buflen, /**< [in] length of the input buffer */ - bool pubkey /**< [in] buffer is a public key */ + atcac_pk_ctx* ctx, /**< [in] pointer to a pk context */ + const uint8_t * buf, /**< [in] buffer containing a pem encoded key */ + size_t buflen, /**< [in] length of the input buffer */ + bool pubkey /**< [in] buffer is a public key */ ) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -501,19 +505,18 @@ ATCA_STATUS atcac_pk_free( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_sign( - atcac_pk_ctx* ctx, - uint8_t * digest, - size_t dig_len, - uint8_t* signature, - size_t* sig_len + atcac_pk_ctx* ctx, + const uint8_t * digest, + size_t dig_len, + uint8_t* signature, + size_t* sig_len ) { ATCA_STATUS status = ATCA_BAD_PARAM; - int ret = 0; - WC_RNG rng; if (ctx && ctx->ptr && signature && digest && sig_len) { + WC_RNG rng; int ret = wc_InitRng(&rng); if (!ret) @@ -553,11 +556,11 @@ ATCA_STATUS atcac_pk_sign( * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_pk_verify( - atcac_pk_ctx* ctx, - uint8_t* digest, - size_t dig_len, - uint8_t* signature, - size_t sig_len + atcac_pk_ctx* ctx, + const uint8_t* digest, + size_t dig_len, + const uint8_t* signature, + size_t sig_len ) { ATCA_STATUS status = ATCA_BAD_PARAM; diff --git a/license.txt b/license.txt index 138dd90fd..7fbb6fe83 100644 --- a/license.txt +++ b/license.txt @@ -1,4 +1,4 @@ -(c) 2015-2021 Microchip Technology Inc. and its subsidiaries. +(c) 2015-2022 Microchip Technology Inc. and its subsidiaries. Subject to your compliance with these terms, you may use the Microchip Software and any derivatives exclusively with Microchip products. It is your diff --git a/python/cryptoauthlib/__init__.py b/python/cryptoauthlib/__init__.py index be60b4622..ec8254f47 100644 --- a/python/cryptoauthlib/__init__.py +++ b/python/cryptoauthlib/__init__.py @@ -94,5 +94,9 @@ def __update_signatures(lib, filename): _lib_definition_file = os.path.join(os.path.dirname(__file__), 'cryptoauth.json') -if os.path.exists(_lib_definition_file): - __update_signatures(get_cryptoauthlib(), _lib_definition_file) +def __reinitialize(): + global _lib_definition_file + if os.path.exists(_lib_definition_file): + __update_signatures(get_cryptoauthlib(), _lib_definition_file) + +__reinitialize() diff --git a/python/cryptoauthlib/atcacert.py b/python/cryptoauthlib/atcacert.py index c2a10e519..6e0837964 100644 --- a/python/cryptoauthlib/atcacert.py +++ b/python/cryptoauthlib/atcacert.py @@ -23,8 +23,8 @@ import binascii from datetime import datetime -from ctypes import Structure, c_int, c_uint8, c_uint16, c_char, POINTER, create_string_buffer, c_uint32, byref, c_size_t -from .library import get_cryptoauthlib, get_ctype_by_name, AtcaReference, AtcaStructure +from ctypes import Structure, c_int, c_uint8, c_uint16, c_char, c_uint32, c_uint64, POINTER, create_string_buffer, byref, c_size_t +from .library import get_cryptoauthlib, AtcaReference, AtcaStructure from .atcaenum import AtcaEnum from .status import Status @@ -175,104 +175,118 @@ def _atcacert_convert_enum(kwargs, name, enum): kwargs[name] = int(getattr(enum, k)) -class atcacert_device_loc_t(AtcaStructure): +class atcacert_comp_data_t(AtcaStructure): """ - CTypes mirror of atcacert_device_loc_t from atcacert_def.h + CTypes definition of certificate signature storage which includes other certificate metadata + which is why it's often identified as "compresessed cert" for the slot in configurators """ + _pack_ = 1 + _size_ = 72 _fields_ = [ - ('zone', get_ctype_by_name('atcacert_device_zone_t')), # Zone in the device. - ('slot', c_uint8), # Slot within the data zone. Only applies if zone is DEVZONE_DATA. - ('is_genkey', c_uint8), # If true, use GenKey command to get the contents instead of Read. - ('offset', c_uint16), # Byte offset in the zone. - ('count', c_uint16) # Byte count. + ('r', c_uint8*32), # P256 signature 'r' value - big endian + ('s', c_uint8*32), # P256 signature 's' value - big endian + ('year', c_uint64, 5), # Years after 2000 + ('month', c_uint64, 4), # Month (0 - 11), see atcacert_tm_utc_t + ('day', c_uint64, 5), # Day (1 - 31), see atcacert_tm_utc_t + ('hour', c_uint64, 5), # Hour (0 - 23), see atcacert_tm_utc_t + ('expire', c_uint64, 5), # Expire years (<=31) + ('signer_id', c_uint64, 16), # Value used in the siging cert subject name + ('chain_id', c_uint64, 4), # Revision identifier + ('template_id', c_uint64, 4), # Location in a chain + ('reserved_70_4', c_uint64, 4), # Reserved - lower four bits of byte 70 + ('sn_source', c_uint64, 4), # Serial number format, see atcacert_cert_sn_src_t + ('reserved_71_8', c_uint64, 8) # Reserved - byte 71 ] - _pack_ = 1 - - def __init__(self, *args, **kwargs): - if kwargs is not None: - _atcacert_convert_enum(kwargs, 'zone', atcacert_device_zone_t) +atcacert_comp_data_t.check_rationality() - super(atcacert_device_loc_t, self).__init__(*args, **kwargs) +class atcacert_device_loc_t(AtcaStructure): + """ + CTypes mirror of atcacert_device_loc_t from atcacert_def.h + """ + _pack_ = 1 + _def_ = { + 'zone': (atcacert_device_zone_t,), # Zone in the device. + 'slot': (c_uint8,), # Slot within the data zone. Only applies if zone is DEVZONE_DATA. + 'is_genkey': (c_uint8,), # If true, use GenKey command to get the contents instead of Read. + 'offset': (c_uint16,), # Byte offset in the zone. + 'count': (c_uint16,) # Byte count. + } +atcacert_device_loc_t.from_definition() class atcacert_cert_loc_t(AtcaStructure): """ CTypes mirror of atcacert_cert_loc_t from atcacert_def.h """ - _fields_ = [('offset', c_uint16), ('count', c_uint16)] _pack_ = 1 + _fields_ = [('offset', c_uint16), ('count', c_uint16)] class atcacert_cert_element_t(AtcaStructure): """ CTypes mirror of atcacert_cert_element_t from atcacert_def.h """ - _fields_ = [ - ('id', c_char * 25), # ID identifying this element. - ('device_loc', atcacert_device_loc_t), # Location in the device for the element. - ('cert_loc', atcacert_cert_loc_t), # Location in the certificate template for the element. - ('transforms', get_ctype_by_name('atcacert_transform_t') * 2) # Transforms for converting the device data. - - ] _pack_ = 1 + _def_ = { + 'id': (c_char, 25), # ID identifying this element. + 'device_loc': (atcacert_device_loc_t,), # Location in the device for the element. + 'cert_loc': (atcacert_cert_loc_t,), # Location in the certificate template for the element. + 'transforms': (atcacert_transform_t, 2) # Transforms for converting the device data. + } +atcacert_cert_element_t.from_definition() +atcacert_cert_element_t.check_rationality() class atcacert_def_t(AtcaStructure): """ CTypes mirror of atcacert_def_t from atcacert_def.h """ - def __init__(self, *args, **kwargs): - if kwargs is not None: - _atcacert_convert_enum(kwargs, 'type', atcacert_cert_type_t) - _atcacert_convert_enum(kwargs, 'sn_source', atcacert_cert_sn_src_t) - _atcacert_convert_enum(kwargs, 'issue_date_format', atcacert_date_format_t) - _atcacert_convert_enum(kwargs, 'expire_date_format', atcacert_date_format_t) - - _atcacert_convert_bytes(kwargs, 'cert_template', POINTER(c_uint8)) - - super(atcacert_def_t, self).__init__(*args, **kwargs) + _pack_ = 1 # Need to define fields outside the class due to ca_cert_def, which is a pointer # to the same class. -atcacert_def_t._fields_ = [ # pylint: disable=protected-access +atcacert_def_t._def_ = { # pylint: disable=protected-access # Certificate type. - ('type', get_ctype_by_name('atcacert_cert_type_t')), + 'type': (atcacert_cert_type_t,), # ID for the this certificate definition (4-bit value). - ('template_id', c_uint8), + 'template_id': (c_uint8,), # ID for the certificate chain this definition is a part of (4-bit value). - ('chain_id', c_uint8), + 'chain_id': (c_uint8,), # If this is a device certificate template, this is the device slot for the device private key. - ('private_key_slot', c_uint8), + 'private_key_slot': (c_uint8,), # Where the certificate serial number comes from (4-bit value). - ('sn_source', get_ctype_by_name('atcacert_cert_sn_src_t')), + 'sn_source': (atcacert_cert_sn_src_t,), # Only applies when sn_source is SNSRC_STORED or SNSRC_STORED_DYNAMIC. Describes where to get the # certificate serial number on the device. - ('cert_sn_dev_loc', atcacert_device_loc_t), + 'cert_sn_dev_loc': (atcacert_device_loc_t,), # Format of the issue date in the certificate. - ('issue_date_format', get_ctype_by_name('atcacert_date_format_t')), + 'issue_date_format': (atcacert_date_format_t,), # format of the expire date in the certificate. - ('expire_date_format', get_ctype_by_name('atcacert_date_format_t')), + 'expire_date_format': (atcacert_date_format_t,), # Location in the certificate for the TBS (to be signed) portion. - ('tbs_cert_loc', atcacert_cert_loc_t), + 'tbs_cert_loc': (atcacert_cert_loc_t,), # Number of years the certificate is valid for (5-bit value). 0 means no expiration. - ('expire_years', c_uint8), + 'expire_years': (c_uint8,), # Where on the device the public key can be found. - ('public_key_dev_loc', atcacert_device_loc_t), + 'public_key_dev_loc': (atcacert_device_loc_t,), # Where on the device the compressed cert can be found. - ('comp_cert_dev_loc', atcacert_device_loc_t), + 'comp_cert_dev_loc': (atcacert_device_loc_t,), # Where in the certificate template the standard cert elements are inserted. - ('std_cert_elements', atcacert_cert_loc_t * 8), + 'std_cert_elements': (atcacert_cert_loc_t, atcacert_std_cert_element_t), # Additional certificate elements outside of the standard certificate contents. - ('cert_elements', POINTER(atcacert_cert_element_t)), + 'cert_elements': (POINTER(atcacert_cert_element_t), 'cert_elements_count'), # Number of additional certificate elements in cert_elements. - ('cert_elements_count', c_uint8), + 'cert_elements_count': (c_uint8,), # Pointer to the actual certificate template data. - ('cert_template', POINTER(c_uint8)), + 'cert_template': (POINTER(c_uint8), 'cert_template_size'), # Size of the certificate template in cert_template in bytes. - ('cert_template_size', c_uint16), + 'cert_template_size': (c_uint16,), # Certificate definition of the CA certificate - ('ca_cert_def', POINTER(atcacert_def_t)) -] + 'ca_cert_def': (POINTER(atcacert_def_t),) +} +atcacert_def_t.from_definition() +atcacert_def_t.check_rationality() + class atcacert_tm_utc_t(Structure): """ diff --git a/python/cryptoauthlib/atcaenum.py b/python/cryptoauthlib/atcaenum.py index 8dbeceebd..bb7f33d88 100644 --- a/python/cryptoauthlib/atcaenum.py +++ b/python/cryptoauthlib/atcaenum.py @@ -32,6 +32,9 @@ def __ne__(self, other): def __int__(self): return int(self.value) + def __hash__(self): + return hash(int(self.value)) + # Make module import * safe - keep at the end of the file __all__ = ['AtcaEnum'] diff --git a/python/cryptoauthlib/iface.py b/python/cryptoauthlib/iface.py index 4474ac5c9..2d5d2cc7e 100644 --- a/python/cryptoauthlib/iface.py +++ b/python/cryptoauthlib/iface.py @@ -21,8 +21,8 @@ # THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR # THIS SOFTWARE. -from ctypes import Structure, Union, c_uint16, c_int, c_uint8, c_uint32, c_void_p -from .library import get_cryptoauthlib, get_ctype_by_name +from ctypes import c_uint16, c_int, c_uint8, c_uint32, c_void_p +from .library import get_cryptoauthlib, AtcaStructure, AtcaUnion from .atcaenum import AtcaEnum from .exceptions import UnsupportedInterface @@ -74,55 +74,71 @@ class ATCADeviceType(AtcaEnum): # The following must match atca_iface.h exactly -class _U_Address(Union): +class _U_Address(AtcaUnion): """Hidden union to provide backward compatibility with the api change""" _fields_ = [('slave_address', c_uint8), ('address', c_uint8)] -class _ATCAI2C(Structure): +class _ATCAI2C(AtcaStructure): """I2C/TWI HAL configuration""" - _anonymous_ = ('u') + _anonymous_ = ('u',) + _map_ = { + 'u': (1,) + } _fields_ = [('u', _U_Address), ('bus', c_uint8), ('baud', c_uint32)] -class _ATCASWI(Structure): +class _ATCASWI(AtcaStructure): """SWI (Atmel Single Wire Interface) HAL configuration""" _fields_ = [('address', c_uint8), ('bus', c_uint8)] -class _ATCASPI(Structure): +class _ATCASPI(AtcaStructure): """SPI HAL configuration""" _fields_ = [('bus', c_uint8), ('select_pin', c_uint8), ('baud', c_uint32)] -class _ATCAUART(Structure): +class _ATCAUART(AtcaStructure): """Generic UART HAL configuration""" - _fields_ = [('dev_interface', get_ctype_by_name('ATCAKitType')), - ('dev_identity', c_uint8), - ('port', c_uint8), - ('baud', c_uint32), - ('wordsize', c_uint8), - ('parity', c_uint8), - ('stopbits', c_uint8)] - - -class _ATCAHID(Structure): + _def_ = { + 'dev_interface': (ATCAKitType,), + 'dev_identity': (c_uint8,), + 'port': (c_uint8,), + 'baud': (c_uint32,), + 'wordsize': (c_uint8,), + 'parity': (c_uint8,), + 'stopbits': (c_uint8,) + } +_ATCAUART.from_definition() + +class _ATCAHID(AtcaStructure): """USB (HID) HAL configuration""" - _fields_ = [('idx', c_int), - ('dev_interface', get_ctype_by_name('ATCAKitType')), - ('dev_identity', c_uint8), - ('vid', c_uint32), - ('pid', c_uint32), - ('packetsize', c_uint32)] - - -class _ATCACUSTOM(Structure): + _def_ = { + 'idx': (c_int,), + 'dev_interface': (ATCAKitType,), + 'dev_identity': (c_uint8,), + 'vid': (c_uint32,), + 'pid': (c_uint32,), + 'packetsize': (c_uint32,) + } +_ATCAHID.from_definition() + +class _ATCAKIT(AtcaStructure): + """Kit (Bridge) HAL Configuration""" + _def_ = { + 'dev_interface': (ATCAKitType,), + 'dev_identity': (c_uint8,), + 'flags': (c_uint32,) + } +_ATCAKIT.from_definition() + +class _ATCACUSTOM(AtcaStructure): """Custom HAL configuration""" _fields_ = [('halinit', c_void_p), ('halpostinit', c_void_p), @@ -134,25 +150,41 @@ class _ATCACUSTOM(Structure): ('halrelease', c_void_p)] -class _ATCAIfaceParams(Union): +class _ATCAIfaceParams(AtcaUnion): """HAL Configurations supported by the library (this is a union)""" _fields_ = [('atcai2c', _ATCAI2C), ('atcaswi', _ATCASWI), ('atcaspi', _ATCASPI), ('atcauart', _ATCAUART), ('atcahid', _ATCAHID), + ('atcakit', _ATCAKIT), ('atcacustom', _ATCACUSTOM)] -class ATCAIfaceCfg(Structure): +class ATCAIfaceCfg(AtcaStructure): """Interface configuration structure used by atcab_init()""" - _fields_ = [('iface_type', get_ctype_by_name('ATCAIfaceType')), - ('devtype', get_ctype_by_name('ATCADeviceType')), - ('cfg', _ATCAIfaceParams), - ('wake_delay', c_uint16), - ('rx_retries', c_int), - ('cfg_data', c_void_p)] - + _anonymous_ = ('cfg',) + _map_ = { + 'cfg': ('iface_type', { + ATCAIfaceType.ATCA_I2C_IFACE: 'atcai2c', + ATCAIfaceType.ATCA_SWI_IFACE: 'atcaswi', + ATCAIfaceType.ATCA_UART_IFACE:'atcauart', + ATCAIfaceType.ATCA_SPI_IFACE: 'atcaspi', + ATCAIfaceType.ATCA_HID_IFACE: 'atcahid', + ATCAIfaceType.ATCA_KIT_IFACE: 'atcakit', + ATCAIfaceType.ATCA_CUSTOM_IFACE: 'atcacustom' + }) + } + _def_ = { + 'iface_type': (ATCAIfaceType,), + 'devtype': (ATCADeviceType,), + 'cfg': (_ATCAIfaceParams,), + 'wake_delay': (c_uint16,), + 'rx_retries': (c_int,), + 'cfg_data': (c_void_p,) + } +ATCAIfaceCfg.from_definition() +ATCAIfaceCfg.check_rationality() def _iface_load_default_config(name): """"Attempt to load the default configuration structure from the library by name""" diff --git a/python/cryptoauthlib/library.py b/python/cryptoauthlib/library.py index 0d3ba03be..0e77056f6 100644 --- a/python/cryptoauthlib/library.py +++ b/python/cryptoauthlib/library.py @@ -21,13 +21,26 @@ # THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR # THIS SOFTWARE. -import os.path +from fnmatch import fnmatch +import os +from pickle import OBJ import sys from ctypes import * from ctypes.util import find_library +from typing import Callable, Sequence, Any +from unittest.util import unorderable_list_difference from .exceptions import LibraryLoadError from .atcaenum import AtcaEnum +try: + from textwrap import indent +except ImportError: + # python2 compatability - we control the newlines in this module so no need + # to worry about platform differences here - rendering will change them + def indent(lines, insert): + return insert + '\n{}'.format(insert).join(lines.split('\n')) + + # Maps common name to the specific name used internally ATCA_NAMES = {'i2c': 'i2c', 'hid': 'kithid', 'sha': 'sha204', 'ecc': 'eccx08'} @@ -74,14 +87,22 @@ def _force_local_library(): In some environments loading seems to fail under all circumstances unless brute forcing it. """ - curr_path = os.path.dirname(__file__) + paths = [os.path.dirname(__file__)] if sys.platform.startswith('win'): - return os.path.join(curr_path, "cryptoauth.dll") + libname = 'cryptoauth.dll' elif sys.platform.startswith('darwin'): - return os.path.join(curr_path, "libcryptoauth.dylib") + libname = 'libcryptoauth.dylib' else: - return os.path.join(curr_path, "libcryptoauth.so") + if 'LD_LIBRARY_PATH' in os.environ: + paths += os.environ['LD_LIBRARY_PATH'].split(os.pathsep) + libname = 'libcryptoauth.so' + + for p in paths: + libpath = os.path.join(p, libname) + if os.path.exists(libpath): + return libpath + return libname def load_cryptoauthlib(lib=None): @@ -89,6 +110,7 @@ def load_cryptoauthlib(lib=None): Load CryptoAauthLib into Python environment raise LibraryLoadError if cryptoauthlib library can't be loaded """ + global _CRYPTO_LIB # pylint: disable=global-statement if lib is not None: _CRYPTO_LIB = lib @@ -200,11 +222,351 @@ def get_ctype_array_instance(array, value): a = array(*[get_ctype_structure_instance(t, e) for e in value]) return a +class _CtypeIterator: + """ + Used to iterate through a ctypes structure or union. This iterator + returns a tuple of three elements: + , , + Of course field_info is a tuple of varying size depending on how the + field was defined (arrays, bitfields, etc) + """ + def __init__(self, obj) -> None: + self._obj = obj + self._index = 0 + self._end = len(self._obj._fields_) + def __iter__(self): + return self + def __next__(self): + if self._index < self._end: + f = self._obj._fields_[self._index] + if d := getattr(self._obj, '_def_', {}).get(f[0], None): + f_info = tuple(d) + else: + f_info = tuple(list(f)[1:]) + self._index += 1 + return f[0], getattr(self._obj, f[0]), f_info + raise StopIteration + +def _get_field_definition(obj, name): + """ + Get meta information about the ctypes structure/union by accessing + the field description attributes of the class that were provided + as part of the ctype structure/union definition + """ + # Check for the _def_ attribute first which yields superior field + # information for our uses + if d := getattr(obj, '_def_', {}).get(name, None): + f = list(d) + if len(f) > 1 and isinstance(f[1], str): + f[1] = getattr(obj, f[1]) + return tuple(f) + # Fallback to the _fields_ list which is less verbose but contains + # type information which is suitable for a lot of operations + for f in obj._fields_: + if f[0] == name: + return tuple(list(f)[1:]) + # The field is not found so it's probably an anonymous union - we'll + # recurse once if we find the field rather than going overboard + # with recursion here. It would be a bit rediculous to have multple + # cascaded anonymous unions - in the context of cryptoauthlib its + # not possible + if anon := getattr(obj, '_anonymous_', None): + for anon_name in anon: + anon_obj = getattr(obj, anon_name) + for f in anon_obj._fields_: + if f[0] == name: + return _get_field_definition(anon_obj, name) + +def _def_to_field(f_type, f_size = None): + """ + Helper function to convert an entry in the _def_ dictionary to the + tuple required for a _field_ entry + """ + if type(f_type) == type(AtcaEnum): + f_type = get_ctype_by_name(f_type.__name__) + if type(f_size) == type(AtcaEnum): + f_size = len(f_size) + if isinstance(f_size, int): + return f_type*f_size + return f_type + +def _convert_pointer_to_list(p, length): + """ + Pointer types can be frustrating to interact with generally when processing data in python + so this converts them into types that are iterable and bounded + """ + if p._type_ in (c_ubyte, c_byte): + return string_at(p, length) + elif p._type_ == c_char: + return string_at(p, length).decode('ascii') + else: + return [p[i] for i in range(length)] + +def _get_attribute_from_ctypes(obj, obj_type, length = None, *args): + """ + Helper function that is used by AtcaStructure and AtcaUnion to intercept attribute access + to those objects and convert the resulting values into easier to use python objects based + on the configuration of the structure/union + """ + def _convert_value(e_type, value): + try: + return e_type(value) + except ValueError: + return value + + def _get_conversion_from_field(f_type): + if type(f_type) == type(AtcaEnum): + return lambda x: _convert_value(f_type, x) + return lambda x: x + + if obj_type == c_char: + # Convert character arrays to strings + return obj.decode('ascii') + elif getattr(obj_type, 'contents', None): + # Check pointers and convert if possible + if obj: + if length: + return _convert_pointer_to_list(obj, length) + else: + return obj.contents + else: + return None + elif l := getattr(obj, '_length_', None): + # Convert ctype arrays to bounded lists + e = _get_conversion_from_field(obj_type) + return [e(obj[i]) for i in range(l)] + elif isinstance(obj, int): + return _get_conversion_from_field(obj_type)(obj) + return obj + +def _check_type_rationality(cls): + """ + This checks the structure or union size against the constants that are stored in the library + during compilation. This is not an absolute guarentee that alignment is completely correct + but it will catch most cases of incompability between the compiled library that is installed + and the python module + """ + lib_size = getattr(cls, '_size_', get_size_by_name(cls.__name__)) + py_size = sizeof(cls) + if py_size != lib_size: + message = ('STRUCTURE RATIONALITY CHECK FAILED!' + + f'\nThe size of {cls.__name__} ({py_size}) in {cls.__module__} ' + + f'does not match the installed library\'s size ({lib_size}).' + + '\n\nThis can cause serious faults - you will need to reinstall') + raise LibraryLoadError(message) + +def _array_to_code(obj, name=None, parent = None, **kwargs): + """ + Convert an array like item from a ctypes structure into a C language formatted + string + """ + name_map = lambda x: None + array_type = None + if parent: + if name: + if d := parent.get_field_definition(name): + array_type = d[0] + if len(d) > 1 and type(d[1]) == type(AtcaEnum): + # Checks to see if the parent object has a name map for the array + # elements + name_map = d[1] + + append = _object_definition_code(obj, name, parent, **kwargs) + prepend = '' + + if isinstance(obj, str): + # Directly render + append += f'"{obj}"' + elif isinstance(obj, bytes) or getattr(array_type, '_type_', None) in (c_byte, c_ubyte): + append += '{' + for i, v in enumerate(obj): + if i % 16 == 0: + append += '\n ' + append += f'0x{v:02x}, ' + append = append[:-1] + '\n}' + else: + items = '' + for i, v in enumerate(obj): + i_append, i_prepend = _obj_to_code(v, name_map(i), parent=obj, anon=True, **kwargs) + items += '\n' + i_append + prepend = i_prepend + prepend + append += '{' + indent(items[:-1], ' ') + '\n}' + + append += ',' if parent else ';' + + return append, prepend + +def _object_definition_code(obj, name = None, parent = None, parent_name=None, anon=None, type_info = None, check_names={}): + """ + Emits the first half of the assignment of this object + """ + if name: + if parent is not None: + if anon: + return '\n' + return f'\n.{parent_name}.{name} = ' if parent_name else f'\n.{name} = ' + else: + if type_info: + type_name = type_info._type_.__name__ + else: + type_name = obj.__class__.__name__ + + if 'byte' in type_name: + type_name = 'uint8_t' + + is_array = f'[{len(obj)}]' if isinstance(obj, Sequence) else '' + + return f'\nconst {type_name} {name}{is_array} = ' + return '' + +def _union_to_code(obj, name = None, parent = None, anon = None, entry = None, parent_name=None, type_info=None, **kwargs): + if parent: + anon = name in getattr(parent, '_anonymous_', []) + else: + anon = False + + if entry is None and (info := getattr(parent, '_map_', {}).get(name, None)): + if len(info) == 1: + entry = info[0] + else: + entry = info[1].get(getattr(parent, info[0]), None) + + if isinstance(entry, int): + entry = obj._fields_[entry][0] + if entry: + parent = obj + obj = getattr(obj, entry) + name = entry + + append = '' if anon else _object_definition_code(obj, name, parent, **kwargs) + prepend = '' + + if entry: + if parent_name is None: + parent_name = name + f_append, f_prepend = _to_code(obj, name, parent=parent, anon=anon, parent_name=parent_name, **kwargs) + append += f_append + prepend = f_prepend + prepend + else: + fields = '' + for f_name, f_item, f_info in obj: + f_append, f_prepend = _to_code(f_item, f_name, parent=obj, type_info=f_info[0], **kwargs) + fields += f_append + prepend = f_prepend + prepend + append += '{' + indent(fields[:-1], ' ') + '\n}' + + append += ',' if parent else ';' + + return append, prepend + +def _structure_to_code(obj, name = None, parent = None, type_info=None, parent_name=None, **kwargs): + """ + Emits a string with a C language representation of the structure(s) following pointers the + best that is can + """ + append = _object_definition_code(obj, name, parent, **kwargs) + prepend = '' + + fields = f' //{name}' if name and isinstance(parent, Sequence) else '' + for f_name, f_item, f_info in obj: + f_append, f_prepend = _to_code(f_item, f_name, parent=obj, parent_name=name, type_info=f_info[0], **kwargs) + fields += f_append + prepend = f_prepend + prepend + append += '{' + indent(fields[:-1], ' ') + '\n}' + append += ',' if parent else ';' + + return append, prepend + +def _obj_to_code(obj, name, parent=None, anon=None, parent_name=None, **kwargs): + """ + Convert python/ctypes object into a C language representation + """ + if isinstance(obj, Union): + return _union_to_code(obj, name, parent=parent, anon=anon, parent_name=parent_name, **kwargs) + elif isinstance(obj, Structure): + return _structure_to_code(obj, name, parent=parent, anon=anon, **kwargs) + elif isinstance(obj, Sequence): + return _array_to_code(obj, name, parent=parent, **kwargs) + else: + append = _object_definition_code(obj, name, parent=parent, **kwargs) + append += str(obj) + append += ',' if parent else ';' + return append, '' + +def _pointer_to_code(obj, name = None, parent=None, parent_name=None, check_names={}, **kwargs): + """ + Convert the pointer into a representative object by creating a definition in the prepend + area + """ + append = _object_definition_code(obj, name, parent, **kwargs) + prepend = '' + if obj: + name = f'{parent_name}_{name}' + name = check_names.get(name, name) + prepend, more = _obj_to_code(obj, name, parent=None, check_names=check_names, **kwargs) + prepend = more + prepend + '\n' + append += f'&{name},' + else: + append += 'NULL,' + return append, prepend + +def _is_pointer(obj, type_info = None, **kwargs): + """ + Checks to see if object looks like a pointer + """ + return type_info and getattr(type_info, 'contents', None) + +def _to_code(obj, name = None, **kwargs): + """ + Map object types to the proper renderer function by catching pointer like objects first + + Returns: (append, prepend) + """ + if _is_pointer(obj, **kwargs): + return _pointer_to_code(obj, name, **kwargs) + return _obj_to_code(obj, name, **kwargs) + +def _structure_to_string(item, level: int = 0): + """ + Emits a readable string of the structure elements coverting types and following pointers and arrays + the best that is can + """ + if level == 0: + result = f'\n{item.__class__.__name__} = ' + level += 1 + else: + result = '' + if isinstance(item, (Structure, Union)): + for f in item._fields_: + result += indent(f'\n{f[0]} = ', ' '*level) + result += _structure_to_string(getattr(item, f[0]), level + 1) + elif isinstance(item, Sequence) and not (isinstance(item, (bytes, str)) or isinstance(item[0], int)): + items = '' + for i in item: + items += '\n' + _structure_to_string(i, level+1) + result += indent(items, ' '*level) + else: + result += f'{item}' + return result + +def _ctype_from_definition(cls): + """ + Extends the ctypes structure and union types to add a new attribute _def_ which is a dictionary + of field attributes. This extends functionality by quite a bit by supporting additional types + and field linkages + """ + if not getattr(cls, '_fields_', None): + if getattr(cls, '_def_', None): + cls._fields_ = [(k, _def_to_field(*d)) for k, d in cls._def_.items()] + else: + raise AttributeError(f'Trying to finalize the {cls} type without providing _fields_ or _def_ attributes') + class AtcaUnion(Union): """ An extended ctypes structure to accept complex inputs """ # pylint: disable-msg=invalid-name, too-few-public-methods def __init__(self, *args, **kwargs): + self._selected = '' if kwargs is not None: for f in self._fields_: if f[0] in kwargs: @@ -217,11 +579,52 @@ def __init__(self, *args, **kwargs): super(AtcaUnion, self).__init__(*args, **kwargs) + @classmethod + def from_definition(cls): + """ + Trigger _field_ creation from the values provided in _def_ - must be run before the class + is instantiated + """ + _ctype_from_definition(cls) + + @classmethod + def check_rationality(cls): + """ + Perform a rationality check on the structure definition against the expected definition by + checking structure sizes between the compiled library and the python library + """ + _check_type_rationality(cls) + + @classmethod + def get_field_definition(cls, name: str): + return _get_field_definition(cls, name) + + def __getattribute__(self, name: str) -> Any: + obj = super().__getattribute__(name) + if isinstance(obj, Callable) or name.startswith('_'): + return obj + return _get_attribute_from_ctypes(obj, *_get_field_definition(self, name)) + + def __iter__(self): + return _CtypeIterator(self) + + def __str__(self): + return _structure_to_string(self) + + def to_c_code(self, name = None, **kwargs): + append, prepend = _union_to_code(self, name, **kwargs) + return prepend + append + + def update_from_buffer(self, buffer): + if len(buffer) < sizeof(self): + raise ValueError + memmove(addressof(self), buffer, sizeof(self)) + class AtcaStructure(Structure): """ An extended ctypes structure to accept complex inputs """ # pylint: disable-msg=invalid-name, too-few-public-methods - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: if kwargs is not None: for f in self._fields_: if f[0] in kwargs: @@ -231,9 +634,47 @@ def __init__(self, *args, **kwargs): kwargs[f[0]] = get_ctype_structure_instance(f[1], kwargs[f[0]]) elif isinstance(f[1](), Array): kwargs[f[0]] = get_ctype_array_instance(f[1], kwargs[f[0]]) + elif isinstance(kwargs[f[0]], AtcaEnum): + kwargs[f[0]] = int(kwargs[f[0]]) super(AtcaStructure, self).__init__(*args, **kwargs) + @classmethod + def from_definition(cls): + """ + Trigger _field_ creation from the values provided in _def_ - must be run before the class + is instantiated + """ + _ctype_from_definition(cls) + + @classmethod + def check_rationality(cls): + """ + Perform a rationality check on the structure definition against the expected definition by + checking structure sizes between the compiled library and the python library + """ + _check_type_rationality(cls) + + @classmethod + def get_field_definition(cls, name: str): + return _get_field_definition(cls, name) + + def __getattribute__(self, name: str) -> Any: + obj = super().__getattribute__(name) + if isinstance(obj, Callable) or name.startswith('_'): + return obj + return _get_attribute_from_ctypes(obj, *_get_field_definition(self, name)) + + def __iter__(self): + return _CtypeIterator(self) + + def __str__(self): + return _structure_to_string(self) + + def to_c_code(self, name = None, **kwargs): + append, prepend = _structure_to_code(self, name, **kwargs) + return prepend + append + def update_from_buffer(self, buffer): if len(buffer) < sizeof(self): raise ValueError diff --git a/python/cryptoauthlib/talib.py b/python/cryptoauthlib/talib.py deleted file mode 100644 index 2882eb4fa..000000000 --- a/python/cryptoauthlib/talib.py +++ /dev/null @@ -1,333 +0,0 @@ -""" -Trust Anchor Interface -""" -# (c) 2015-2018 Microchip Technology Inc. and its subsidiaries. -# -# Subject to your compliance with these terms, you may use Microchip software -# and any derivatives exclusively with Microchip products. It is your -# responsibility to comply with third party license terms applicable to your -# use of third party software (including open source software) that may -# accompany Microchip software. -# -# THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER -# EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED -# WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A -# PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, -# SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE -# OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF -# MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE -# FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL -# LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED -# THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR -# THIS SOFTWARE. - -from ctypes import c_uint8, byref, create_string_buffer, c_uint16, c_size_t, POINTER, cast, Array -from .status import Status -from .library import get_cryptoauthlib, AtcaReference, AtcaStructure, AtcaUnion, create_byte_buffer - - -class ta_handle_properties_public_key(AtcaStructure): - """ - Class: 0 - """ - _fields_ = [ - ('Path_Length', c_uint8), - ('Secure_Boot', c_uint8, 1), - ('Root', c_uint8, 2), - ('CRL_Sign', c_uint8, 1), - ('Special_Only', c_uint8, 1), - ('Reserved', c_uint8, 3) - ] - _pack_ = 1 - - -class ta_handle_properties_private_key(AtcaStructure): - """ - Class 1: - """ - _fields_ = [ - ('Pub_Key', c_uint8), - ('Session', c_uint8, 1), - ('Key_Gen', c_uint8, 1), - ('Sign_Use', c_uint8, 2), - ('Agree_Use', c_uint8, 2), - ('Reserved', c_uint8, 2) - ] - _pack_ = 1 - - -class ta_handle_properties_symmetric_key(AtcaStructure): - """ - Class 2 - """ - _fields_ = [ - ('Granted_Rights', c_uint8), - ('Sym_Usage', c_uint8, 2), - ('Session_Use', c_uint8, 3), - ('Key_Group_OK', c_uint8, 1), - ('Reserved', c_uint8, 2) - ] - _pack_ = 1 - -class ta_handle_properties_data(AtcaStructure): - """ - Class 3 - """ - _fields_ = [ - ('Size', c_uint16, 12), - ('Template', c_uint16, 1), - ('Reserved', c_uint16, 3) - ] - _pack_ = 1 - - -class ta_handle_properties_certificate(AtcaStructure): - """ - Class 4 - """ - _fields_ = [ - ('Granted_Rights', c_uint8), - ('Secure_Boot', c_uint8, 1), - ('CA_OK', c_uint8, 1), - ('CA_Parent', c_uint8, 1), - ('CRL_Sign', c_uint8, 1), - ('Special_Only', c_uint8, 1), - ('Reserved', c_uint8, 3) - ] - _pack_ = 1 - - -class ta_handle_properties_key_group(AtcaStructure): - """ - Class 6 - """ - _fields_ = [ - ('Num_Keys', c_uint8, 5), - ('Handles', c_uint8, 1), - ('Reserved0', c_uint8, 2), - ('Reserved1', c_uint8) - ] - _pack_ = 1 - - -class ta_handle_properties_crl(AtcaStructure): - _fields_ = [ - ('Num_Digests', c_uint8), - ('Reserved', c_uint8) - ] - _pack_ = 1 - - -class ta_element_attributes_properties(AtcaUnion): - _fields_ = [ - ('public', ta_handle_properties_public_key), - ('private', ta_handle_properties_private_key), - ('symmetric', ta_handle_properties_symmetric_key), - ('data', ta_handle_properties_data), - ('certificate', ta_handle_properties_certificate), - ('key_group', ta_handle_properties_key_group), - ('crl', ta_handle_properties_crl) - ] - _pack_ = 1 - - -class ta_element_attributes_t(AtcaStructure): - _fields_ = [ - ('Class', c_uint8, 3), - ('Key_Type', c_uint8, 4), - ('Alg_Mode', c_uint8, 1), - ('Property', ta_element_attributes_properties), - ('Usage_Key', c_uint8), - ('Write_Key', c_uint8), - ('Read_Key', c_uint8), - ('Usage_Perm', c_uint8, 2), - ('Write_Perm', c_uint8, 2), - ('Read_Perm', c_uint8, 2), - ('Delete_Perm', c_uint8, 2), - ('Use_Count', c_uint8, 2), - ('Reserved0', c_uint8, 1), - ('Exportable', c_uint8, 1), - ('Lockable', c_uint8, 1), - ('Access_Limit', c_uint8, 2), - ('Reserved1', c_uint8, 1) - ] - _pack_ = 1 - - -def talib_handle_init_public_key(attributes, key_type, alg_mode, secure_boot_enable, root_key_enable): - return get_cryptoauthlib().talib_handle_init_public_key(byref(attributes), key_type, alg_mode, secure_boot_enable, - root_key_enable) - -def talib_handle_init_private_key(attributes, key_type, alg_mode, sign_use, key_agreement_use): - return get_cryptoauthlib().talib_handle_init_private_key(byref(attributes), key_type, alg_mode, sign_use, - key_agreement_use) - - -def talib_handle_init_symmetric_key(attributes, key_type, sym_usage): - return get_cryptoauthlib().talib_handle_init_symmetric_key(byref(attributes), key_type, sym_usage) - - -def talib_handle_init_data(attributes, data_size): - return get_cryptoauthlib().talib_handle_init_data(byref(attributes), data_size) - - -def talib_handle_init_extracated_certificate(attributes, key_type, alg_mode, secure_boot_use, intermediate_ca_enable): - return get_cryptoauthlib().talib_handle_init_extracated_certificate(byref(attributes), key_type, alg_mode, - secure_boot_use, intermediate_ca_enable) - - -def talib_handle_init_fast_crypto_key_group(attributes, key_type, num_keys, handles): - return get_cryptoauthlib().talib_handle_init_fast_crypto_key_group(byref(attributes), key_type, num_keys, handles) - - -def talib_handle_set_permissions(attributes, usage_perm, write_perm, read_perm, delete_perm): - return get_cryptoauthlib().talib_handle_set_permissions(byref(attributes), usage_perm, write_perm, read_perm, - delete_perm) - -def talib_handle_set_usage_permission(attributes, usage_perm): - return get_cryptoauthlib().talib_handle_set_usage_permission(byref(attributes), usage_perm) - - -def talib_handle_set_write_permission(attributes, write_perm): - return get_cryptoauthlib().talib_handle_set_write_permission(byref(attributes), write_perm) - - -def talib_handle_set_read_permission(attributes, read_perm): - return get_cryptoauthlib().talib_handle_set_read_permission(byref(attributes), read_perm) - - -def talib_handle_set_delete_permission(attributes, delete_perm): - return get_cryptoauthlib().talib_handle_set_delete_permission(byref(attributes), delete_perm) - - -def talib_create(device, mode, details, handle_in, handle_config, handle_out): - if not isinstance(handle_out, AtcaReference): - status = Status.ATCA_BAD_PARAM - else: - c_handle_out = c_uint16(handle_out.value) - status = get_cryptoauthlib().talib_create(device, details, handle_in, byref(handle_config), byref(c_handle_out)) - handle_out.value = c_handle_out.value - return status - - -def talib_create_element(device, handle_config, handle_out): - if not isinstance(handle_out, AtcaReference): - status = Status.ATCA_BAD_PARAM - else: - c_handle_out = c_uint16(handle_out.value) - status = get_cryptoauthlib().talib_create_element(device, handle_config, byref(c_handle_out)) - handle_out.value = c_handle_out.value - return status - - -def talib_create_element_with_handle(device, handle_in, handle_config): - return get_cryptoauthlib().talib_create_element_with_handle(device, handle_in, byref(handle_config)) - - -def talib_create_ephemeral_element_with_handle(device, details, handle_in, handle_config): - return get_cryptoauthlib().talib_create_ephemeral_element_with_handle(device, details, handle_in, - byref(handle_config)) - - -def talib_create_hmac_element(device, key_size, handle_config, handle_out): - if not isinstance(handle_out, AtcaReference): - status = Status.ATCA_BAD_PARAM - else: - c_handle_out = c_uint16(handle_out.value) - status = get_cryptoauthlib().talib_create_hmac_element(device, key_size, byref(handle_config), - byref(c_handle_out)) - handle_out.value = c_handle_out.value - return status - - -def talib_create_hmac_element_with_handle(device, key_size, handle_in, handle_config): - return get_cryptoauthlib().talib_create_hmac_element_with_handle(device, key_size, handle_in, byref(handle_config)) - - -def talib_delete_handle(device, handle): - return get_cryptoauthlib().talib_delete_handle(device, handle) - - -def talib_is_handle_valid(device, target_handle, is_valid): - if not isinstance(is_valid, AtcaReference): - status = Status.ATCA_BAD_PARAM - else: - c_is_valid = c_uint8(is_valid.value) - status = get_cryptoauthlib().talib_is_handle_valid(device, target_handle, byref(c_is_valid)) - is_valid.value = c_is_valid.value - return status - - -def talib_info(device, revision): - """ - Used to get the device revision number. (DevRev) - - Args: - revision 8-byte bytearray receiving the revision number - from the device. (Expects bytearray) - - Returns: - Status code - """ - c_revision = create_string_buffer(8) - if not isinstance(revision, bytearray): - status = Status.ATCA_BAD_PARAM - else: - status = get_cryptoauthlib().talib_info(device, c_revision) - revision[0:] = bytes(c_revision.raw) - return status - - -def talib_info_get_handle_info(device, target_handle, handle_info): - if not isinstance(handle_info, ta_element_attributes_t): - status = Status.ATCA_BAD_PARAM - else: - info_array = create_string_buffer(9) - status = get_cryptoauthlib().talib_info_get_handle_info(device, target_handle, info_array) - handle_info.update_from_buffer(info_array) - return status - - -#ATCA_STATUS talib_info_get_handle_info(ATCADevice device, uint32_t target_handle, uint8_t handle_info[STATIC_ARRAY TA_HANDLE_INFO_SIZE]); - - -def talib_info_get_handles_array(device, handles): - if not isinstance(handles, list): - status = Status.ATCA_BAD_PARAM - else: - results = (c_uint16*100)() - count = c_size_t(100) - status = get_cryptoauthlib().talib_info_get_handles_array(device, cast(results, POINTER(c_uint16)), byref(count)) - handles[0:] = results[:count.value] - return status - - -#ATCA_STATUS talib_info_get_handle_size(ATCADevice device, uint32_t target_handle, size_t* out_size); - - -def talib_write_element(device, handle, length, data): - status = get_cryptoauthlib().talib_write_element(device, handle, length, bytes(data)) - - return status - - -def talib_auth_generate_nonce(device, handle, options, i_nonce): - cbuf = create_string_buffer(16) - cbuf[0:] = i_nonce[0:16] - status = get_cryptoauthlib().talib_auth_generate_nonce(device, handle, options, cbuf) - i_nonce[0:] = cbuf[:len(cbuf)] - return status - - -def talib_auth_startup(device, handle, alg_id, max_cmd, key_len, key, i_nonce, r_nonce): - status = get_cryptoauthlib().talib_auth_startup(device, handle, alg_id, max_cmd, key_len, key, - create_byte_buffer(i_nonce), create_byte_buffer(r_nonce)) - return status - - -def talib_auth_terminate(device): - return get_cryptoauthlib().talib_auth_terminate(device) - -# Make module import * safe - keep at the end of the file -__all__ = ['ta_element_attributes_t'] -__all__ += [x for x in dir() if x.startswith(__name__.split('.')[-1])] diff --git a/release_notes.md b/release_notes.md index 472c5985b..1f9cbaa70 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,6 +1,34 @@ # Microchip Cryptoauthlib Release Notes +## Release v3.4.0 (10/27/2022) + +### New Features + - Added framework for fine grain library configuration including configuration check + header files `_config_check.h` see lib/atca_config_check.h for the top level + header + - Added WPC application files with reference message generation/parsing and library + configuration file to optimize to the smallest footprint + - TA100 read/write apis updated to segment incoming buffer into partial read/write + operations if it exceeds the maximum supported packet size + - Added PKCS7 padding algorithm for use with AES-CBC + - Expose PKCS11 configuration options to CMake configuration + + +### Fixes + - Improve ECC204 apis to match cryptoauthlib apis and abstract the device differences + - Support for strict C99 compliance and clean up warnings from -Wall and pedantic levels + - Add rsa2048 key size support to talib_rsaenc command + - Fix for ta100 devupdate to set the proper auth session exit flags so the library will + properly reconnect when the ta100 reboots + - Fix ECC608 verify failure when ReqRandom bit is set for a stored public key by using + tempkey in this situation rather than the message digest buffer. See the ECC608 + datasheet for more details of this special condition + - Improve ta100 auth session handling of long messages by reporting the message size + exceeds the wrapped message limit earlier in the packet creation process + - Fixes and Improvements for PKCS11 interface based on compliance testing + + ## Release v3.3.3 (10/06/2021) ### New features @@ -373,4 +401,4 @@ - Certificate I/O and reconstruction - New SHA2 implementation - Major update to API docs, Doxygen files found in cryptoauthlib/docs - - load cryptoauthlib/docs/index.html with your browser \ No newline at end of file + - load cryptoauthlib/docs/index.html with your browser diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index efaade1d4..d13733249 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,12 +6,13 @@ option (ATCA_TEST_LOCK_ENABLE "Enable device locking functions and tests" OFF) file(GLOB TEST_ATCACERT_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "atcacert/*.c") file(GLOB TEST_JWT_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "jwt/*.c") file(GLOB TEST_TNG_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "tng/*.c") +file(GLOB TEST_WPC_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "wpc/*.c") file(GLOB TEST_API_ATCAB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_atcab/*.c") file(GLOB TEST_API_CALIB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_calib/*.c") file(GLOB TEST_API_CRYPTO RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_crypto/*.c") file(GLOB TEST_API_TALIB RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "api_talib/*.c") file(GLOB TEST_VECTORS_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "vectors/*.c") -file(GLOB TEST_MBEDTLDS_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "mbedtls/*.c") +file(GLOB TEST_INTEGRATION_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "integration/*.c") file(GLOB TEST_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.c") file(GLOB UNITY_SRC RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "../third_party/unity/*.c") @@ -28,6 +29,10 @@ if(ATCA_TA100_SUPPORT) set(CRYPTOAUTH_TEST_SRC ${CRYPTOAUTH_TEST_SRC} ${TEST_API_TALIB}) endif(ATCA_TA100_SUPPORT) +if(ATCA_WPC_SUPPORT) +set(CRYPTOAUTH_TEST_SRC ${CRYPTOAUTH_TEST_SRC} ${TEST_WPC_SRC}) +endif(ATCA_WPC_SUPPORT) + source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${CRYPTOAUTH_TEST_SRC}) source_group("Unity" FILES ${UNITY_SRC}) @@ -38,7 +43,7 @@ source_group("External Files" FILES ${TEST_CUSTOM_CMD_SRC}) endif() if(ATCA_MBEDTLS) -set(CRYPTOAUTH_TEST_SRC ${CRYPTOAUTH_TEST_SRC} ${TEST_MBEDTLDS_SRC}) +set(CRYPTOAUTH_TEST_SRC ${CRYPTOAUTH_TEST_SRC} ${TEST_INTEGRATION_SRC}) endif() add_executable(cryptoauth_test ${CRYPTOAUTH_TEST_SRC} ${UNITY_SRC}) @@ -49,6 +54,7 @@ include_directories(cryptoauth_test ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/api_calib ${CMAKE_CURRENT_SOURCE_DIR}/api_crypto ${CMAKE_CURRENT_SOURCE_DIR}/api_talib + ${CMAKE_CURRENT_SOURCE_DIR}/integration ${CMAKE_CURRENT_SOURCE_DIR}/../lib ${CMAKE_CURRENT_SOURCE_DIR}/../third_party ${CMAKE_CURRENT_SOURCE_DIR}/../third_party/mbedtls/include @@ -61,6 +67,19 @@ if(UNIX) target_link_libraries(cryptoauth_test pthread) endif() +if(NOT MSVC) +target_compile_options(cryptoauth_test PRIVATE -ffile-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=./test + -fmacro-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=./test) +target_compile_options(cryptoauth_test PRIVATE -Wall -Wextra) +endif() + +if(ATCA_STRICT_C99) +set_property(TARGET cryptoauth_test PROPERTY C_STANDARD 99) +if(NOT MSVC) +target_compile_options(cryptoauth_test PRIVATE -Wpedantic) +endif() +endif() + if(ATCA_BUILD_SHARED_LIBS) target_compile_definitions(cryptoauth_test PUBLIC -DATCA_BUILD_SHARED_LIBS) endif(ATCA_BUILD_SHARED_LIBS) diff --git a/test/api_atcab/atca_tests_aes.c b/test/api_atcab/atca_tests_aes.c index b3252385d..432027910 100644 --- a/test/api_atcab/atca_tests_aes.c +++ b/test/api_atcab/atca_tests_aes.c @@ -28,9 +28,15 @@ #ifdef _WIN32 #include #endif -#include "atca_test.h" -#include "atca_basic.h" -#include "cryptoauthlib.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_AES_EN +#define TEST_ATCAB_AES_EN CALIB_AES_EN || TALIB_AES_EN +#endif + +#ifndef TEST_ATCAB_AES_GCM_EN +#define TEST_ATCAB_AES_GCM_EN CALIB_AES_GCM_EN || TALIB_AES_GCM_EN +#endif extern const uint8_t g_aes_keys[4][16]; extern const uint8_t g_plaintext[64]; @@ -65,7 +71,7 @@ const uint8_t g_ciphertext_ecb[4][64] = { } }; -#ifdef ATCA_ATECC608_SUPPORT +#if TEST_ATCAB_AES_EN && defined(ATCA_ATECC608_SUPPORT) TEST(atca_cmd_basic_test, aes_encrypt_key_tempkey) { @@ -121,6 +127,7 @@ TEST(atca_cmd_basic_test, aes_decrypt_key_tempkey) #endif +#if TEST_ATCAB_AES_EN TEST(atca_cmd_basic_test, aes_encrypt_key_slot) { ATCA_STATUS status; @@ -243,10 +250,10 @@ TEST(atca_cmd_basic_test, aes_decrypt_key_slot_simple) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL_MEMORY(&g_plaintext[data_block * ATCA_AES128_BLOCK_SIZE], decrypted_data_out, ATCA_AES128_BLOCK_SIZE); } - } +#endif -#ifdef ATCA_ATECC608_SUPPORT +#if TEST_ATCAB_AES_GCM_EN && defined(ATCA_ATECC608_SUPPORT) TEST(atca_cmd_basic_test, aes_gfm) { ATCA_STATUS status; @@ -268,7 +275,7 @@ TEST(atca_cmd_basic_test, aes_gfm) } #endif -#ifdef ATCA_ATECC608_SUPPORT +#if TEST_ATCAB_AES_EN && defined(ATCA_ATECC608_SUPPORT) TEST(atca_cmd_basic_test, volatile_key_permit) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -361,8 +368,6 @@ TEST(atca_cmd_basic_test, volatile_key_permit) status = atcab_info_set_latch(true); //persistent latch is set TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - status = atcab_aes_encrypt(key_slot, 0, data_in, encrypted_data_out); //Encrypting data with first 16 bytes in slot 10 as key TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); //Encryption should pass as persistent latch is set @@ -380,8 +385,10 @@ t_test_case_info aes_basic_test_info[] = { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_encrypt_key_slot), DEVICE_MASK(ATECC608) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_decrypt_key_slot), DEVICE_MASK(ATECC608) }, #endif +#if TEST_ATCAB_AES_EN { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_encrypt_key_slot_simple), DEVICE_MASK(TA100) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_decrypt_key_slot_simple), DEVICE_MASK(TA100) }, +#endif /* Array Termination element*/ { (fp_test_case)NULL, (uint8_t)0 }, }; diff --git a/test/api_atcab/atca_tests_aes_cbc.c b/test/api_atcab/atca_tests_aes_cbc.c index 3892b74c0..5a25ec1c0 100644 --- a/test/api_atcab/atca_tests_aes_cbc.c +++ b/test/api_atcab/atca_tests_aes_cbc.c @@ -28,10 +28,17 @@ #ifdef _WIN32 #include #endif -#include "atca_test.h" -#include "atca_basic.h" -#include "cryptoauthlib.h" +#include "test_atcab.h" +#ifndef TEST_ATCAB_AES_CBC_EN +#define TEST_ATCAB_AES_CBC_EN (ATCAB_AES_CBC_ENCRYPT_EN || ATCAB_AES_CBC_DECRYPT_EN) +#endif + +#ifndef TEST_ATCAB_AES_CBC_UPDATE_EN +#define TEST_ATCAB_AES_CBC_UPDATE_EN ATCAB_AES_CBC_UPDATE_EN +#endif + +#if TEST_ATCAB_AES_CBC_EN extern const uint8_t g_aes_keys[4][16]; extern const uint8_t g_plaintext[64]; @@ -175,15 +182,198 @@ TEST(atca_cmd_basic_test, aes_cbc_decrypt_block_simple) TEST_ASSERT_EQUAL_MEMORY(&g_plaintext[data_block * ATCA_AES128_BLOCK_SIZE], plaintext, ATCA_AES128_BLOCK_SIZE); } } + +#if TEST_ATCAB_AES_CBC_UPDATE_EN +TEST(atca_cmd_basic_test, aes_cbc_encrypt_update_simple) +{ + uint8_t ciphertext[sizeof(g_plaintext)]; + size_t length = sizeof(ciphertext); + atca_aes_cbc_ctx_t ctx; + ATCA_STATUS status; + uint16_t key_slot; + + // Skip test if data zone isn't locked + test_assert_data_is_locked(); + + // Skip test if AES is not enabled + check_config_aes_enable(); + + status = atca_test_config_get_id(TEST_TYPE_AES, &key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Load AES keys into slot + status = atcab_write_bytes_zone(ATCA_ZONE_DATA, key_slot, 0, g_aes_keys[0], 16); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Init CBC mode context using key in slot + status = atcab_aes_cbc_init(&ctx, key_slot, 0, g_iv); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Encrypt the entire plaintext + status = atcab_aes_cbc_encrypt_update(&ctx, (uint8_t*)g_plaintext, sizeof(g_plaintext), ciphertext, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Finalize without padding + status = atcab_aes_cbc_encrypt_finish(&ctx, ciphertext, &length, 0); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(&g_ciphertext_cbc[0][0], ciphertext, sizeof(ciphertext)); +} + +TEST(atca_cmd_basic_test, aes_cbc_encrypt_update_chunks) +{ + uint8_t ciphertext[sizeof(g_plaintext)]; + uint8_t * cPtr = ciphertext; + size_t length = sizeof(ciphertext); + atca_aes_cbc_ctx_t ctx; + ATCA_STATUS status; + uint16_t key_slot; + + // Skip test if data zone isn't locked + test_assert_data_is_locked(); + + // Skip test if AES is not enabled + check_config_aes_enable(); + + status = atca_test_config_get_id(TEST_TYPE_AES, &key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Load AES keys into slot + status = atcab_write_bytes_zone(ATCA_ZONE_DATA, key_slot, 0, g_aes_keys[0], 16); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Init CBC mode context using key in slot + status = atcab_aes_cbc_init(&ctx, key_slot, 0, g_iv); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Encrypt the a small chunk + status = atcab_aes_cbc_encrypt_update(&ctx, (uint8_t*)g_plaintext, 8, cPtr, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + cPtr += length; + + // Encrypt a large chunk + length = sizeof(g_plaintext) - (cPtr - ciphertext); + status = atcab_aes_cbc_encrypt_update(&ctx, (uint8_t*)&g_plaintext[8], 24, cPtr, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + cPtr += length; + + // Finish it up + length = sizeof(g_plaintext) - (cPtr - ciphertext); + status = atcab_aes_cbc_encrypt_update(&ctx, (uint8_t*)&g_plaintext[32], sizeof(g_plaintext)-32, cPtr, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Finalize without padding + status = atcab_aes_cbc_encrypt_finish(&ctx, ciphertext, &length, 0); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(&g_ciphertext_cbc[0][0], ciphertext, sizeof(ciphertext)); +} + +TEST(atca_cmd_basic_test, aes_cbc_decrypt_update_simple) +{ + uint8_t plaintext[sizeof(g_plaintext)]; + size_t length = sizeof(plaintext); + atca_aes_cbc_ctx_t ctx; + ATCA_STATUS status; + uint16_t key_slot; + + // Skip test if data zone isn't locked + test_assert_data_is_locked(); + + // Skip test if AES is not enabled + check_config_aes_enable(); + + status = atca_test_config_get_id(TEST_TYPE_AES, &key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Load AES keys into slot + status = atcab_write_bytes_zone(ATCA_ZONE_DATA, key_slot, 0, g_aes_keys[0], 16); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Init CBC mode context using key in slot + status = atcab_aes_cbc_init(&ctx, key_slot, 0, g_iv); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Encrypt the entire plaintext + status = atcab_aes_cbc_decrypt_update(&ctx, (uint8_t*)&g_ciphertext_cbc[0][0], sizeof(g_plaintext), plaintext, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Finalize without padding + status = atcab_aes_cbc_decrypt_finish(&ctx, plaintext, &length, 0); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(&g_plaintext, plaintext, sizeof(plaintext)); +} + +TEST(atca_cmd_basic_test, aes_cbc_decrypt_update_chunks) +{ + uint8_t plaintext[sizeof(g_plaintext)]; + uint8_t * pPtr = plaintext; + size_t length = sizeof(plaintext); + atca_aes_cbc_ctx_t ctx; + ATCA_STATUS status; + uint16_t key_slot; + + // Skip test if data zone isn't locked + test_assert_data_is_locked(); + + // Skip test if AES is not enabled + check_config_aes_enable(); + + status = atca_test_config_get_id(TEST_TYPE_AES, &key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Load AES keys into slot + status = atcab_write_bytes_zone(ATCA_ZONE_DATA, key_slot, 0, g_aes_keys[0], 16); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Init CBC mode context using key in slot + status = atcab_aes_cbc_init(&ctx, key_slot, 0, g_iv); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Encrypt the a small chunk + status = atcab_aes_cbc_decrypt_update(&ctx, (uint8_t*)&g_ciphertext_cbc[0][0], 8, pPtr, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + pPtr += length; + + // Encrypt a large chunk + length = sizeof(plaintext) - (pPtr - plaintext); + status = atcab_aes_cbc_decrypt_update(&ctx, (uint8_t*)&g_ciphertext_cbc[0][8], 24, pPtr, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + pPtr += length; + + // Finish it up + length = sizeof(plaintext) - (pPtr - plaintext); + status = atcab_aes_cbc_decrypt_update(&ctx, (uint8_t*)&g_ciphertext_cbc[0][32], sizeof(plaintext)-32, pPtr, &length); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + pPtr += length; + + // Finalize without padding + length = sizeof(plaintext) - (pPtr - plaintext); + status = atcab_aes_cbc_decrypt_finish(&ctx, plaintext, &length, 0); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(g_plaintext, plaintext, sizeof(plaintext)); +} +#endif + + +#endif /* TEST_ATCAB_AES_CBC_EN */ + // *INDENT-OFF* - Preserve formatting t_test_case_info aes_cbc_basic_test_info[] = { +#if TEST_ATCAB_AES_CBC_EN #ifdef ATCA_ATECC608_SUPPORT { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_encrypt_block), DEVICE_MASK(ATECC608) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_decrypt_block), DEVICE_MASK(ATECC608) }, #endif { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_encrypt_block_simple), DEVICE_MASK(TA100) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_decrypt_block_simple), DEVICE_MASK(TA100) }, +#ifdef TEST_ATCAB_AES_CBC_UPDATE_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_encrypt_update_simple), DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_encrypt_update_chunks), DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_decrypt_update_simple), DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cbc_decrypt_update_chunks), DEVICE_MASK(TA100) }, + +#endif /* TEST_ATCAB_AES_CBC_UPDATE_EN */ +#endif /* TEST_ATCAB_AES_CBC_EN */ { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; diff --git a/test/api_atcab/atca_tests_aes_cbcmac.c b/test/api_atcab/atca_tests_aes_cbcmac.c index 57da12652..8b7971e94 100644 --- a/test/api_atcab/atca_tests_aes_cbcmac.c +++ b/test/api_atcab/atca_tests_aes_cbcmac.c @@ -28,7 +28,7 @@ #ifdef _WIN32 #include #endif -#include "atca_test.h" +#include "test_atcab.h" extern const uint8_t g_aes_keys[4][16]; extern const uint8_t g_plaintext[64]; diff --git a/test/api_atcab/atca_tests_aes_ccm.c b/test/api_atcab/atca_tests_aes_ccm.c index 38ba671bf..fa163a1ca 100644 --- a/test/api_atcab/atca_tests_aes_ccm.c +++ b/test/api_atcab/atca_tests_aes_ccm.c @@ -28,7 +28,7 @@ #ifdef _WIN32 #include #endif -#include "atca_test.h" +#include "test_atcab.h" #ifdef ATCA_ATECC608_SUPPORT typedef struct @@ -341,10 +341,10 @@ TEST(atca_cmd_basic_test, aes_ccm_auth_decrypt_partial) t_test_case_info aes_ccm_basic_test_info[] = { #ifdef ATCA_ATECC608_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt), DEVICE_MASK(ATECC608A) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt_partial), DEVICE_MASK(ATECC608A) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt), DEVICE_MASK(ATECC608A) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt_partial), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_encrypt_partial), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt), DEVICE_MASK(ATECC608A) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ccm_auth_decrypt_partial), DEVICE_MASK(ATECC608A) }, #endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; diff --git a/test/api_atcab/atca_tests_aes_cmac.c b/test/api_atcab/atca_tests_aes_cmac.c index 498383faa..2242816d5 100644 --- a/test/api_atcab/atca_tests_aes_cmac.c +++ b/test/api_atcab/atca_tests_aes_cmac.c @@ -28,8 +28,13 @@ #ifdef _WIN32 #include #endif -#include "atca_test.h" -#include "atca_basic.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_AES_CMAC_EN +#define TEST_ATCAB_AES_CMAC_EN ATCAB_AES_CMAC_EN +#endif + +#if TEST_ATCAB_AES_CMAC_EN #include "vectors/aes_cmac_nist_vectors.h" @@ -105,14 +110,17 @@ TEST(atca_cmd_basic_test, aes_cmac_simple) } } } +#endif /* TEST_ATCAB_AES_CMAC_EN */ + // *INDENT-OFF* - Preserve formatting t_test_case_info aes_cmac_basic_test_info[] = { +#if TEST_ATCAB_AES_CMAC_EN #ifdef ATCA_ATECC608_SUPPORT { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cmac), DEVICE_MASK(ATECC608) }, #endif { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_cmac_simple), DEVICE_MASK(TA100) }, +#endif /* TEST_ATCAB_AES_CMAC_EN */ { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; - // *INDENT-ON* diff --git a/test/api_atcab/atca_tests_aes_ctr.c b/test/api_atcab/atca_tests_aes_ctr.c index c4806d4a7..f6cae566f 100644 --- a/test/api_atcab/atca_tests_aes_ctr.c +++ b/test/api_atcab/atca_tests_aes_ctr.c @@ -28,8 +28,13 @@ #ifdef _WIN32 #include #endif -#include "atca_test.h" -#include "atca_basic.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_AES_CTR_EN +#define TEST_ATCAB_AES_CTR_EN ATCAB_AES_CTR_EN +#endif + +#if TEST_ATCAB_AES_CTR_EN extern const uint8_t g_aes_keys[4][16]; extern const uint8_t g_plaintext[64]; @@ -303,10 +308,12 @@ TEST(atca_cmd_basic_test, aes_ctr_increment_simple) status = atcab_aes_ctr_encrypt_block(&ctx, &g_plaintext[0], ciphertext); TEST_ASSERT_EQUAL(ATCA_BAD_PARAM, status); } +#endif /* TEST_ATCAB_AES_CTR_EN */ // *INDENT-OFF* - Preserve formatting t_test_case_info aes_ctr_basic_test_info[] = { +#if TEST_ATCAB_AES_CTR_EN #ifdef ATCA_ATECC608_SUPPORT { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ctr_encrypt_block), DEVICE_MASK(ATECC608) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ctr_decrypt_block), DEVICE_MASK(ATECC608) }, @@ -315,6 +322,7 @@ t_test_case_info aes_ctr_basic_test_info[] = { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ctr_encrypt_block_simple), DEVICE_MASK(TA100) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ctr_decrypt_block_simple), DEVICE_MASK(TA100) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, aes_ctr_increment_simple), DEVICE_MASK(TA100) }, +#endif /* TEST_ATCAB_AES_CTR_EN */ { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; diff --git a/test/api_atcab/atca_tests_aes_gcm.c b/test/api_atcab/atca_tests_aes_gcm.c index 35ce91c3d..2f99d18c8 100644 --- a/test/api_atcab/atca_tests_aes_gcm.c +++ b/test/api_atcab/atca_tests_aes_gcm.c @@ -28,8 +28,7 @@ #ifdef _WIN32 #include #endif -#include "atca_test.h" -#include "atca_basic.h" +#include "test_atcab.h" #ifdef ATCA_ATECC608_SUPPORT diff --git a/test/api_atcab/atca_tests_counter.c b/test/api_atcab/atca_tests_counter.c index eb2f37e2c..c7fe410d3 100644 --- a/test/api_atcab/atca_tests_counter.c +++ b/test/api_atcab/atca_tests_counter.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" #ifdef ATCA_ECC_SUPPORT @@ -87,7 +87,9 @@ TEST(atca_cmd_basic_test, counter_match) // Read the current counter 0 value status = atcab_counter_read(0, &counter0_value); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#ifdef ATCA_PRINTF printf("Starting counter 0: %u\r\n", (unsigned int)counter0_value); +#endif // Increase the counter 0 value so that it is aligned to multiple of 32-counter_limit while ((uint8_t)(counter0_value % 32) < (32 - 1)) @@ -95,7 +97,9 @@ TEST(atca_cmd_basic_test, counter_match) status = atcab_counter_increment(0, &counter0_value); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#ifdef ATCA_PRINTF printf("Incrementing counter 0 to 32-byte boundary: %u\r\n", (unsigned int)counter0_value); +#endif // Update the counter match value counter_match = counter0_value + 1; // Calculate the counter match value to be written in slot @@ -103,7 +107,9 @@ TEST(atca_cmd_basic_test, counter_match) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); status = atcab_write_bytes_zone(ATCA_ZONE_DATA, 10, 0, counter_match_slot_data, sizeof(counter_match_slot_data)); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#ifdef ATCA_PRINTF printf("Setting counter match to: %u\r\n", (unsigned int)counter_match); +#endif // Generate random message status = atcab_random(msg); @@ -120,7 +126,9 @@ TEST(atca_cmd_basic_test, counter_match) // Validate counter change status = atcab_counter_read(0, &counter0_value); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#ifdef ATCA_PRINTF printf("Counter 0 after successful sign: %u\r\n", (unsigned int)counter0_value); +#endif TEST_ASSERT_EQUAL(counter_match, counter0_value); // Counter should now equal the counter match value // Verify signature @@ -135,7 +143,9 @@ TEST(atca_cmd_basic_test, counter_match) // Validate counter doesn't change status = atcab_counter_read(0, &counter0_value); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#ifdef ATCA_PRINTF printf("Counter 0 after failed sign: %u\r\n", (unsigned int)counter0_value); +#endif TEST_ASSERT_EQUAL(counter_match, counter0_value); // Counter should not increment after reaching counter match // Set counter match value to high limit so the slot can be used for other tests diff --git a/test/api_atcab/atca_tests_derivekey.c b/test/api_atcab/atca_tests_derivekey.c index 46add2f1d..e20fc388f 100644 --- a/test/api_atcab/atca_tests_derivekey.c +++ b/test/api_atcab/atca_tests_derivekey.c @@ -25,10 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" -#if ATCA_CA_SUPPORT +#ifndef TEST_ATCAB_DERIVEKEY_EN +#define TEST_ATCAB_DERIVEKEY_EN CALIB_DERIVEKEY_EN +#endif +#if TEST_ATCAB_DERIVEKEY_EN TEST(atca_cmd_basic_test, derivekey) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -224,19 +227,15 @@ TEST(atca_cmd_basic_test, derivekey_mac) status = atcab_checkmac(checkmac_params.mode, checkmac_params.key_id, checkmac_params.client_chal, checkmac_params.client_resp, checkmac_params.other_data); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info derivekey_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, derivekey), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, derivekey_mac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, +#if TEST_ATCAB_DERIVEKEY_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, derivekey), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, derivekey_mac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, +#endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* - -#else -t_test_case_info derivekey_basic_test_info[] = -{ - { (fp_test_case)NULL, (uint8_t)0 }, -}; -#endif diff --git a/test/api_atcab/atca_tests_ecdh.c b/test/api_atcab/atca_tests_ecdh.c index 523e77c98..5be59a6bb 100644 --- a/test/api_atcab/atca_tests_ecdh.c +++ b/test/api_atcab/atca_tests_ecdh.c @@ -25,9 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" -#ifdef ATCA_ECC_SUPPORT +#ifndef TEST_ATCAB_ECDH_EN +#define TEST_ATCAB_ECDH_EN CALIB_ECDH_EN || TALIB_ECDH_EN +#endif + +#if TEST_ATCAB_ECDH_EN && CALIB_ECDH_EN TEST(atca_cmd_basic_test, ecdh) { ATCA_STATUS status; @@ -58,7 +62,7 @@ TEST(atca_cmd_basic_test, ecdh) memset(pub_alice, 0x44, ATCA_PUB_KEY_SIZE); memset(pub_bob, 0x44, ATCA_PUB_KEY_SIZE); - status = atcab_genkey(key_id_alice, pub_alice); + status = atca_test_genkey(key_id_alice, pub_alice); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); #ifdef ATCA_PRINTF @@ -70,7 +74,7 @@ TEST(atca_cmd_basic_test, ecdh) TEST_ASSERT_NOT_EQUAL_MESSAGE(0, memcmp(pub_alice, frag, sizeof(frag)), "Alice key not initialized"); - status = atcab_genkey(key_id_bob, pub_bob); + status = atca_test_genkey(key_id_bob, pub_bob); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_NOT_EQUAL_MESSAGE(0, memcmp(pub_bob, frag, sizeof(frag)), "Bob key not initialized"); @@ -117,6 +121,7 @@ TEST(atca_cmd_basic_test, ecdh) } #endif +#if TEST_ATCAB_ECDH_EN TEST(atca_cmd_basic_test, ecdh_simple) { ATCA_STATUS status; @@ -142,7 +147,7 @@ TEST(atca_cmd_basic_test, ecdh_simple) memset(pub_alice, 0x44, ATCA_ECCP256_PUBKEY_SIZE); memset(pub_bob, 0x44, ATCA_ECCP256_PUBKEY_SIZE); - status = atcab_genkey(key_id_alice, pub_alice); + status = atca_test_genkey(key_id_alice, pub_alice); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); #ifdef ATCA_PRINTF @@ -154,7 +159,7 @@ TEST(atca_cmd_basic_test, ecdh_simple) TEST_ASSERT_NOT_EQUAL_MESSAGE(0, memcmp(pub_alice, frag, sizeof(frag)), "Alice key not initialized"); - status = atcab_genkey(key_id_bob, pub_bob); + status = atca_test_genkey(key_id_bob, pub_bob); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_NOT_EQUAL_MESSAGE(0, memcmp(pub_bob, frag, sizeof(frag)), "Bob key not initialized"); @@ -189,8 +194,9 @@ TEST(atca_cmd_basic_test, ecdh_simple) TEST_ASSERT_EQUAL_MEMORY(pms_alice, pms_bob, sizeof(pms_alice)); } +#endif -#ifdef ATCA_ATECC608_SUPPORT +#if TEST_ATCAB_ECDH_EN && defined(ATCA_ATECC608_SUPPORT) TEST(atca_cmd_basic_test, ecdh_protection_key) { ATCA_STATUS status; @@ -212,7 +218,7 @@ TEST(atca_cmd_basic_test, ecdh_protection_key) memset(pub_bob, 0x44, ATCA_PUB_KEY_SIZE); //Generating Alice private key in tempkey and public key from tempkey. - status = atcab_genkey(tempkey_alice, pub_alice); + status = atca_test_genkey(tempkey_alice, pub_alice); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_NOT_EQUAL_MESSAGE(0, memcmp(pub_alice, frag, sizeof(frag)), "Alice key not initialized"); @@ -224,7 +230,7 @@ TEST(atca_cmd_basic_test, ecdh_protection_key) #endif //Generating Bob public key from private key in slot - status = atcab_genkey(key_id_bob, pub_bob); + status = atca_test_genkey(key_id_bob, pub_bob); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_NOT_EQUAL_MESSAGE(0, memcmp(pub_bob, frag, sizeof(frag)), "Bob key not initialized"); @@ -266,14 +272,14 @@ TEST(atca_cmd_basic_test, ecdh_protection_key) // *INDENT-OFF* - Preserve formatting t_test_case_info ecdh_basic_test_info[] = { -#ifdef ATCA_ECC_SUPPORT +#if TEST_ATCAB_ECDH_EN +#if CALIB_ECDH_EN { REGISTER_TEST_CASE(atca_cmd_basic_test, ecdh), DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, #endif -#if defined(ATCA_ECC_SUPPORT) || defined(ATCA_TA100_SUPPORT) - { REGISTER_TEST_CASE(atca_cmd_basic_test, ecdh_simple), DEVICE_MASK(TA100) }, -#endif + { REGISTER_TEST_CASE(atca_cmd_basic_test, ecdh_simple), DEVICE_MASK(TA100) }, #ifdef ATCA_ATECC608_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, ecdh_protection_key), DEVICE_MASK(ATECC608) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, ecdh_protection_key), DEVICE_MASK(ATECC608) }, +#endif #endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; diff --git a/test/api_atcab/atca_tests_gendig.c b/test/api_atcab/atca_tests_gendig.c index 46f28d576..7cbf5df5c 100644 --- a/test/api_atcab/atca_tests_gendig.c +++ b/test/api_atcab/atca_tests_gendig.c @@ -25,8 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" -#include "atca_basic.h" +#include "test_atcab.h" #ifdef ATCA_ECC_SUPPORT @@ -360,10 +359,10 @@ TEST(atca_cmd_basic_test, gendig_config_otp_data) // *INDENT-OFF* - Preserve formatting t_test_case_info gendig_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_config_otp_data), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_counter), DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_keyconfig), DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_shared_nonce), DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_config_otp_data), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_counter), DEVICE_MASK(ATECC608) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_keyconfig), DEVICE_MASK(ATECC608) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, gendig_shared_nonce), DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* diff --git a/test/api_atcab/atca_tests_genkey.c b/test/api_atcab/atca_tests_genkey.c index f59bfedbc..2520866d5 100644 --- a/test/api_atcab/atca_tests_genkey.c +++ b/test/api_atcab/atca_tests_genkey.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" /** \brief this test assumes a specific configuration and locked config zone * test will generate a private key if data zone is unlocked and return a public key @@ -43,10 +43,15 @@ TEST(atca_cmd_basic_test, genkey) test_assert_config_is_locked(); + if (ECC204 == gCfg->devtype) + { + test_assert_data_is_unlocked(); + } + status = atca_test_config_get_id(TEST_TYPE_ECC_GENKEY, &private_key_id); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atcab_genkey(private_key_id, public_key); + status = atca_test_genkey(private_key_id, public_key); TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, status, "Key generation failed"); // spot check public key for bogus data, there should be none @@ -83,3 +88,4 @@ t_test_case_info genkey_basic_test_info[] = { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_helper.c b/test/api_atcab/atca_tests_helper.c index 56591cad3..89f0993c3 100644 --- a/test/api_atcab/atca_tests_helper.c +++ b/test/api_atcab/atca_tests_helper.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" #define ATCA_TESTS_HELPER_DEVICES ( DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) ) @@ -660,4 +660,4 @@ t_test_case_info helper_basic_test_info[] = { REGISTER_TEST_CASE(atca_helper, transform_reversal), ATCA_TESTS_HELPER_DEVICES}, { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; -// *INDENT-ON* \ No newline at end of file +// *INDENT-ON* diff --git a/test/api_atcab/atca_tests_hmac.c b/test/api_atcab/atca_tests_hmac.c index 31faf5801..c898bcae0 100644 --- a/test/api_atcab/atca_tests_hmac.c +++ b/test/api_atcab/atca_tests_hmac.c @@ -25,9 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" -#if ATCA_CA_SUPPORT +#ifndef TEST_ATCAB_HMAC_EN +#define TEST_ATCAB_HMAC_EN CALIB_HMAC_EN +#endif + +#if TEST_ATCAB_HMAC_EN TEST(atca_cmd_basic_test, hmac) { @@ -106,18 +110,14 @@ TEST(atca_cmd_basic_test, hmac) TEST_ASSERT_EQUAL_MEMORY(hmac_digest, hmac_params.response, sizeof(hmac_digest)); } } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info hmac_basic_test_info[] = { +#if TEST_ATCAB_HMAC_EN { REGISTER_TEST_CASE(atca_cmd_basic_test, hmac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) }, +#endif { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; // *INDENT-ON* - -#else -t_test_case_info hmac_basic_test_info[] = -{ - { (fp_test_case)NULL, (uint8_t)0 }, -}; -#endif diff --git a/test/api_atcab/atca_tests_info.c b/test/api_atcab/atca_tests_info.c index 094ca79ef..85b5432ad 100644 --- a/test/api_atcab/atca_tests_info.c +++ b/test/api_atcab/atca_tests_info.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" TEST(atca_cmd_basic_test, info) { @@ -33,14 +33,25 @@ TEST(atca_cmd_basic_test, info) uint8_t revision[4]; status = atcab_info(revision); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_SUCCESS(status); + if (atcab_is_ca_device(gCfg->devtype)) + { +#if ATCA_CA_SUPPORT + ATCADeviceType devtype = calib_get_devicetype(revision); + if (gCfg->devtype != devtype) + { + g_test_abort = true; + } + TEST_ASSERT_EQUAL_MESSAGE(gCfg->devtype, devtype, "Device Type Mismatch"); +#endif + } } - // *INDENT-OFF* - Preserve formatting t_test_case_info info_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, info), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, info), DEVICE_MASK_SHA | DEVICE_MASK_ECC }, { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_kdf.c b/test/api_atcab/atca_tests_kdf.c index 196d62719..53b582f95 100644 --- a/test/api_atcab/atca_tests_kdf.c +++ b/test/api_atcab/atca_tests_kdf.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" #define AES_CONFIG_ENABLE_BIT_MASK (uint8_t)0x01 diff --git a/test/api_atcab/atca_tests_lock.c b/test/api_atcab/atca_tests_lock.c index 81a33e37f..eb36ae33d 100644 --- a/test/api_atcab/atca_tests_lock.c +++ b/test/api_atcab/atca_tests_lock.c @@ -25,7 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_LOCK_EN +#define TEST_ATCAB_LOCK_EN CALIB_LOCK_EN || TALIB_LOCK_EN +#endif + +#if TEST_ATCAB_LOCK_EN TEST(atca_cmd_basic_test, lock_config_zone) { @@ -83,13 +89,17 @@ TEST(atca_cmd_basic_test, lock_data_slot) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL(true, is_locked); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info lock_basic_test_info[] = { +#if TEST_ATCAB_LOCK_EN //{ REGISTER_TEST_CASE(atca_cmd_basic_test, lock_config_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, //{ REGISTER_TEST_CASE(atca_cmd_basic_test, lock_data_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, { REGISTER_TEST_CASE(atca_cmd_basic_test, lock_data_slot), DEVICE_MASK_ECC }, +#endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_mac.c b/test/api_atcab/atca_tests_mac.c index cc70ca6b7..0c7ba2325 100644 --- a/test/api_atcab/atca_tests_mac.c +++ b/test/api_atcab/atca_tests_mac.c @@ -25,9 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" -#if ATCA_CA_SUPPORT +#ifndef TEST_ATCAB_MAC_EN +#define TEST_ATCAB_MAC_EN CALIB_MAC_EN +#endif + +#if TEST_ATCAB_MAC_EN TEST(atca_cmd_basic_test, mac_key_challenge) { @@ -326,21 +330,18 @@ TEST(atca_cmd_basic_test, checkmac) checkmac_params.other_data); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info mac_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_key_challenge), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_key_tempkey), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_tempkey_challenge), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_tempkey_tempkey), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, checkmac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, +#if TEST_ATCAB_MAC_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_key_challenge), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_key_tempkey), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_tempkey_challenge), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, mac_tempkey_tempkey), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, checkmac), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, +#endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* -#else -t_test_case_info mac_basic_test_info[] = -{ - { (fp_test_case)NULL, (uint8_t)0 }, -}; -#endif diff --git a/test/api_atcab/atca_tests_nonce.c b/test/api_atcab/atca_tests_nonce.c index cbe964bc0..1ea0ef1a7 100644 --- a/test/api_atcab/atca_tests_nonce.c +++ b/test/api_atcab/atca_tests_nonce.c @@ -25,25 +25,37 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_NONCE_EN +#define TEST_ATCAB_NONCE_EN CALIB_NONCE_EN +#endif + +#if TEST_ATCAB_NONCE_EN TEST(atca_cmd_basic_test, challenge) { ATCA_STATUS status = ATCA_GEN_FAIL; uint8_t random_number[32]; +#if CALIB_RANDOM_EN status = atcab_random(random_number); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif status = atcab_nonce(random_number); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#endif /* TEST_ATCAB_NONCE_EN */ // *INDENT-OFF* - Preserve formatting t_test_case_info nonce_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, challenge), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, +#if TEST_ATCAB_NONCE_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, challenge), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, +#endif { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_otpzero.c b/test/api_atcab/atca_tests_otpzero.c index 36041420e..428b0a288 100644 --- a/test/api_atcab/atca_tests_otpzero.c +++ b/test/api_atcab/atca_tests_otpzero.c @@ -25,9 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" -#if ATCA_CA_SUPPORT +#ifndef TEST_ATCAB_OTP_EN +#define TEST_ATCAB_OTP_EN (CALIB_READ_EN && CALIB_WRITE_EN) +#endif + +#if TEST_ATCAB_OTP_EN TEST(atca_cmd_basic_test, otp_zero) { @@ -75,18 +79,15 @@ TEST(atca_cmd_basic_test, otp_zero) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL_MEMORY(zero_otp, read_otp, sizeof(zero_otp)); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info otpzero_basic_test_info[] = { +#if TEST_ATCAB_OTP_EN { REGISTER_TEST_CASE(atca_cmd_basic_test, otp_zero), DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) }, +#endif { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; // *INDENT-ON* -#else -t_test_case_info otpzero_basic_test_info[] = -{ - { (fp_test_case)NULL, (uint8_t)0 }, -}; -#endif diff --git a/test/api_atcab/atca_tests_privwrite.c b/test/api_atcab/atca_tests_privwrite.c index 111805492..afe41ead2 100644 --- a/test/api_atcab/atca_tests_privwrite.c +++ b/test/api_atcab/atca_tests_privwrite.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" #ifdef ATCA_ECC_SUPPORT @@ -101,9 +101,10 @@ TEST(atca_cmd_basic_test, priv_write_encrypted) t_test_case_info privwrite_basic_test_info[] = { #ifdef ATCA_ECC_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, priv_write_unencrypted), DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, priv_write_encrypted), DEVICE_MASK_ECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, priv_write_unencrypted), DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, priv_write_encrypted), DEVICE_MASK_ATECC }, #endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_random.c b/test/api_atcab/atca_tests_random.c index 5b5830fef..d0bfa6d2d 100644 --- a/test/api_atcab/atca_tests_random.c +++ b/test/api_atcab/atca_tests_random.c @@ -25,8 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" +#ifndef TEST_ATCAB_RANDOM_EN +#define TEST_ATCAB_RANDOM_EN CALIB_RANDOM_EN || TALIB_RANDOM_EN +#endif + +#if TEST_ATCAB_RANDOM_EN TEST(atca_cmd_basic_test, random) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -35,11 +40,15 @@ TEST(atca_cmd_basic_test, random) status = atcab_random(randomnum); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info random_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, random), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#if TEST_ATCAB_RANDOM_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, random), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, +#endif { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_read.c b/test/api_atcab/atca_tests_read.c index cbaf45218..7ba6404b3 100644 --- a/test/api_atcab/atca_tests_read.c +++ b/test/api_atcab/atca_tests_read.c @@ -25,9 +25,15 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" -#if ATCA_CA_SUPPORT +#ifndef TEST_ATCAB_READ_EN +#define TEST_ATCAB_READ_EN (CALIB_READ_EN || CALIB_READ_ECC204_EN || TALIB_READ_EN) +#endif + +#if TEST_ATCAB_READ_EN + +#if CALIB_READ_EN TEST(atca_cmd_basic_test, read_zone) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -122,7 +128,7 @@ TEST(atca_cmd_basic_test, read_config_zone) } } -#if ATCA_CA_SUPPORT +#if CALIB_READ_EN TEST(atca_cmd_basic_test, read_otp_zone) { ATCA_STATUS status = ATCA_SUCCESS; @@ -153,18 +159,20 @@ TEST(atca_cmd_basic_test, read_data_zone) status = atcab_read_bytes_zone(ATCA_ZONE_DATA, slot, 0, read_data, sizeof(read_data)); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info read_basic_test_info[] = { -#if ATCA_CA_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, read_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, -#endif - { REGISTER_TEST_CASE(atca_cmd_basic_test, read_config_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, -#if ATCA_CA_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, read_otp_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, -#endif +#if TEST_ATCAB_READ_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, read_config_zone), DEVICE_MASK_SHA | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, read_data_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#if CALIB_READ_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, read_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, read_otp_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, +#endif +#endif /* TEST_ATCAB_READ_EN */ { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_secureboot.c b/test/api_atcab/atca_tests_secureboot.c index 22bca876f..0f26b4bc4 100644 --- a/test/api_atcab/atca_tests_secureboot.c +++ b/test/api_atcab/atca_tests_secureboot.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" #ifdef ATCA_ATECC608_SUPPORT const uint8_t sboot_dummy_image[] = @@ -59,7 +59,7 @@ TEST(atca_cmd_basic_test, sboot_digest) test_assert_data_is_locked(); // Generate new key pair - status = atcab_genkey(private_key_id, public_key); + status = atca_test_genkey(private_key_id, public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Reformat public key into padded format @@ -185,3 +185,4 @@ t_test_case_info sboot_basic_test_info[] = { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_selftest.c b/test/api_atcab/atca_tests_selftest.c index 5b4e3367d..b942c19de 100644 --- a/test/api_atcab/atca_tests_selftest.c +++ b/test/api_atcab/atca_tests_selftest.c @@ -25,7 +25,13 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_SELFEST_EN +#define TEST_ATCAB_SELFTEST_EN CALIB_SELFTEST_EN +#endif + +#if TEST_ATCAB_SELFTEST_EN TEST(atca_cmd_basic_test, selftest_individual) { @@ -62,12 +68,17 @@ TEST(atca_cmd_basic_test, selftest_all) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL(0, result); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info selftest_basic_test_info[] = { +#if TEST_ATCAB_SELFTEST_EN { REGISTER_TEST_CASE(atca_cmd_basic_test, selftest_individual), DEVICE_MASK(ATECC608) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, selftest_all), DEVICE_MASK(ATECC608) }, +#endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + + diff --git a/test/api_atcab/atca_tests_sha.c b/test/api_atcab/atca_tests_sha.c index d5eeeff09..2d0c44f56 100644 --- a/test/api_atcab/atca_tests_sha.c +++ b/test/api_atcab/atca_tests_sha.c @@ -25,7 +25,17 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_SHA_EN +#define TEST_ATCAB_SHA_EN (CALIB_SHA_EN || TALIB_SHA_EN) +#endif + +#ifndef TEST_ATCAB_SHA_HMAC_EN +#define TEST_ATCAB_SHA_HMAC_EN (CALIB_SHA_HMAC_EN || TALIB_SHA_HMAC_EN) +#endif + +#if TEST_ATCAB_SHA_EN static const uint8_t nist_hash_msg1[] = "abc"; static const uint8_t nist_hash_msg2[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; @@ -356,8 +366,7 @@ TEST(atca_cmd_basic_test, sha2_256_nist_monte) #endif } -#if ATCA_CA_SUPPORT - +#if CALIB_SHA_CONTEXT_EN TEST(atca_cmd_basic_test, sha_context) { ATCA_STATUS status; @@ -437,9 +446,10 @@ TEST(atca_cmd_basic_test, sha_context) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL_MEMORY(digest1, digest2, ATCA_SHA256_DIGEST_SIZE); - } +#endif /* CALIB_SHA_CONTEXT_EN */ +#if TALIB_SHA_CONTEXT_EN TEST(atca_cmd_basic_test, sha_context_simple) { ATCA_STATUS status; @@ -524,8 +534,11 @@ TEST(atca_cmd_basic_test, sha_context_simple) TEST_ASSERT_EQUAL_MEMORY(digest1, digest2, ATCA_SHA256_DIGEST_SIZE); } -#endif +#endif /* TALIB_SHA_CONTEXT_EN */ + +#endif /* TEST_ATCAB_SHA_EN */ +#if TEST_ATCAB_SHA_HMAC_EN TEST(atca_cmd_basic_test, sha_hmac) { ATCA_STATUS status = ATCA_GEN_FAIL; @@ -598,11 +611,14 @@ TEST(atca_cmd_basic_test, sha_hmac_tempkey) TEST_ASSERT_EQUAL_MEMORY(hmac_ref, hmac, ATCA_SHA256_DIGEST_SIZE); } -#endif +#endif /* ATCA_ATECC608_SUPPORT */ + +#endif /* TEST_ATCAB_SHA_HMAC_EN */ // *INDENT-OFF* - Preserve formatting t_test_case_info sha_basic_test_info[] = { +#if TEST_ATCAB_SHA_EN { REGISTER_TEST_CASE(atca_cmd_basic_test, sha), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_long), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_short), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, @@ -611,14 +627,21 @@ t_test_case_info sha_basic_test_info[] = { REGISTER_TEST_CASE(atca_cmd_basic_test, sha2_256_nist_short), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, //{ REGISTER_TEST_CASE(atca_cmd_basic_test, sha2_256_nist_long), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, //{ REGISTER_TEST_CASE(atca_cmd_basic_test, sha2_256_nist_monte), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, -#if ATCA_CA_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_context), DEVICE_MASK(ATECC608) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_context_simple), DEVICE_MASK(TA100) }, +#if CALIB_SHA_CONTEXT_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_context), DEVICE_MASK(ATECC608) }, #endif - { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_hmac), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#if TALIB_SHA_CONTEXT_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_context_simple), DEVICE_MASK(TA100) }, +#endif +#endif /* TEST_ATCAB_SHA_EN */ + +#if TEST_ATCAB_SHA_HMAC_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_hmac), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, #ifdef ATCA_ATECC608_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_hmac_tempkey), DEVICE_MASK(ATECC608) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, sha_hmac_tempkey), DEVICE_MASK(ATECC608) }, #endif +#endif /* TEST_ATCAB_SHA_HMAC_EN */ { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_sign.c b/test/api_atcab/atca_tests_sign.c index d917491e8..1a2578a7f 100644 --- a/test/api_atcab/atca_tests_sign.c +++ b/test/api_atcab/atca_tests_sign.c @@ -25,9 +25,68 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" TEST(atca_cmd_basic_test, sign) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t msg[ATCA_SHA256_DIGEST_SIZE]; + uint8_t signature[ATCA_ECCP256_SIG_SIZE]; + uint16_t private_key_id = 0; + + test_assert_config_is_locked(); + test_assert_data_is_locked(); + + status = atca_test_config_get_id(TEST_TYPE_ECC_SIGN, &private_key_id); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Sign message + status = atcab_sign(private_key_id, msg, signature); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +} + +#if defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) +#include "crypto/atca_crypto_sw.h" + +TEST(atca_cmd_basic_test, sign_sw_verify) +{ + ATCA_STATUS status = ATCA_SUCCESS; + uint8_t msg[ATCA_SHA256_DIGEST_SIZE]; + uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; + uint8_t signature[ATCA_ECCP256_SIG_SIZE]; + atcac_pk_ctx pkey; + uint16_t private_key_id = 0; + + test_assert_config_is_locked(); + test_assert_data_is_locked(); + + /* Create a message digest */ + status = atcac_sw_sha2_256((uint8_t*)"abcd", 4, msg); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atca_test_config_get_id(TEST_TYPE_ECC_SIGN, &private_key_id); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Load the public key */ + status = atcab_get_pubkey(private_key_id, public_key); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Initialize a software public key context */ + status = atcac_pk_init(&pkey, public_key, ATCA_ECCP256_PUBKEY_SIZE, 0, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Sign message */ + status = atcab_sign(private_key_id, msg, signature); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Verify the signature */ + status = atcac_pk_verify(&pkey, msg, sizeof(msg), signature, sizeof(signature)); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +} +#endif + +#if defined(ATCA_ECC_SUPPORT) || defined(ATCA_TA100_SUPPORT) +TEST(atca_cmd_basic_test, sign_hw_verify) { ATCA_STATUS status = ATCA_SUCCESS; uint8_t msg[ATCA_SHA256_DIGEST_SIZE]; @@ -47,7 +106,7 @@ TEST(atca_cmd_basic_test, sign) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Generate key pair - status = atcab_genkey(private_key_id, public_key); + status = atca_test_genkey(private_key_id, public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Sign message @@ -59,9 +118,9 @@ TEST(atca_cmd_basic_test, sign) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL(true, is_verified); } +#endif #ifdef ATCA_ECC_SUPPORT - TEST(atca_cmd_basic_test, sign_internal) { uint8_t internal_key_id = 4; // Which slot to sign digest of (via GenDig) @@ -91,7 +150,7 @@ TEST(atca_cmd_basic_test, sign_internal) memcpy(&sn[4], &config[8], 5); // Generate key pair and get public key - status = atcab_genkey(private_key_id, public_key); + status = atca_test_genkey(private_key_id, public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Start with random nonce @@ -145,19 +204,29 @@ TEST(atca_cmd_basic_test, sign_internal) } #endif +#if 0 TEST(atca_cmd_basic_test, read_sig) { TEST_IGNORE_MESSAGE("Pending"); } +#endif // *INDENT-OFF* - Preserve formatting t_test_case_info sign_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, sign), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, sign), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#if ATCA_HOSTLIB_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, sign_sw_verify), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#endif +#if !ATCA_HOSTLIB_EN && (defined(ATCA_ECC_SUPPORT) || defined(ATCA_TA100_SUPPORT)) + { REGISTER_TEST_CASE(atca_cmd_basic_test, sign_hw_verify), DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, +#endif #ifdef ATCA_ECC_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, sign_internal), DEVICE_MASK_ECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, sign_internal), DEVICE_MASK_ATECC }, +#endif +#if 0 + { REGISTER_TEST_CASE(atca_cmd_basic_test, read_sig), DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, #endif - { REGISTER_TEST_CASE(atca_cmd_basic_test, read_sig), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-OFN* diff --git a/test/api_atcab/atca_tests_startup.c b/test/api_atcab/atca_tests_startup.c index d643921ee..6c83c2926 100644 --- a/test/api_atcab/atca_tests_startup.c +++ b/test/api_atcab/atca_tests_startup.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" TEST(atca_cmd_basic_test, version) { @@ -35,7 +35,7 @@ TEST(atca_cmd_basic_test, version) ver_str[0] = '\0'; status = atcab_version(ver_str); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_SUCCESS(status); TEST_ASSERT_EQUAL(8, strlen(ver_str)); } @@ -54,17 +54,17 @@ TEST(atca_cmd_basic_test, doubleinit) // Make sure communication works initially status = atcab_info(rev); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_SUCCESS(status); // a double init should be benign status = atcab_init(gCfg); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_SUCCESS(status); TEST_ASSERT_NOT_EQUAL(NULL, _gDevice); // Make sure communication still works status = atcab_info(rev); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_SUCCESS(status); } // *INDENT-OFF* - Preserve formatting @@ -76,3 +76,4 @@ t_test_case_info startup_basic_test_info[] = { (fp_test_case)NULL, (uint8_t)0 },/* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_updateextra.c b/test/api_atcab/atca_tests_updateextra.c index 8bdcbd814..fe327ddea 100644 --- a/test/api_atcab/atca_tests_updateextra.c +++ b/test/api_atcab/atca_tests_updateextra.c @@ -25,7 +25,7 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" TEST(atca_cmd_basic_test, updateextra) @@ -39,3 +39,4 @@ t_test_case_info updateextra_basic_test_info[] = { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/atca_tests_verify.c b/test/api_atcab/atca_tests_verify.c index 9c7298bd9..66e7df7ee 100644 --- a/test/api_atcab/atca_tests_verify.c +++ b/test/api_atcab/atca_tests_verify.c @@ -25,7 +25,88 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_VERIFY_STORED_EN +#define TEST_ATCAB_VERIFY_STORED_EN (CALIB_VERIFY_STORED_EN || TALIB_VERIFY_STORED_EN) +#endif + +#ifndef TEST_ATCAB_VERIFY_EXTERN_EN +#define TEST_ATCAB_VERIFY_EXTERN_EN (CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN) +#endif + +#ifndef TEST_ATCAB_VERIFY_MAC_EN +#define TEST_ATCAB_VERIFY_MAC_EN CALIB_VERIFY_MAC_EN +#endif + +#ifndef TEST_ATCAB_VERIFY_VALIDATE_EN +#define TEST_ATCAB_VERIFY_VALIDATE_EN CALIB_VERIFY_VALIDATE_EN +#endif + +#ifndef TEST_ATCAB_VERIFY_REQRANDOM_EN +#define TEST_ATCAB_VERIFY_REQRANDOM_EN defined(ATCA_ATECC608_SUPPORT) || defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) +#endif + +#include "vectors/ecdsa_nist_vectors.h" +#include "vectors/ecdh_nist_vectors.h" + + +void print_buffer(uint8_t *buf, int len) +{ + for (int i=0; ivalue, ATCA_SHA256_DIGEST_SIZE, signature, &sig_size); +#else + // Only the 608 has the message digest buffer - other devices will invalidate tempkey + status = atcab_sign(private_key_id, nonce_params.temp_key->value, signature); +#endif + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + // Verify the signature (Message is already loaded into tempkey) + is_verified = false; + status = atcab_verify_stored_with_tempkey(signature, public_key_id, &is_verified); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT(is_verified); + + // Verify with bad message, should fail + message[0]++; + status = atcab_verify_stored_with_tempkey(signature, public_key_id, &is_verified); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT(!is_verified); +} +#endif /* TEST_ATCAB_VERIFY_REQRANDOM_EN */ + +#if TEST_ATCAB_VERIFY_MAC_EN TEST(atca_cmd_basic_test, verify_stored_mac) { ATCA_STATUS status; @@ -167,7 +344,7 @@ TEST(atca_cmd_basic_test, verify_stored_mac) test_assert_data_is_locked(); // Generate new key pair - status = atcab_genkey(private_key_id, public_key); + status = atca_test_genkey(private_key_id, public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Write public key to slot @@ -196,9 +373,11 @@ TEST(atca_cmd_basic_test, verify_stored_mac) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT(!is_verified); } -#endif +#endif /* TEST_ATCAB_VERIFY_MAC_EN */ + +#endif /* TEST_ATCAB_VERIFY_STORED_EN */ -#ifdef ATCA_ECC_SUPPORT +#if TEST_ATCAB_VERIFY_VALIDATE_EN static void test_basic_verify_validate(void) { const uint16_t public_key_id = 14; @@ -239,7 +418,7 @@ static void test_basic_verify_validate(void) // Generate key pair for validation // Typically, the validation private key wouldn't be on the same device as its public key - status = atcab_genkey(validation_private_key_id, validation_public_key); + status = atca_test_genkey(validation_private_key_id, validation_public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Write validation public key @@ -254,7 +433,7 @@ static void test_basic_verify_validate(void) // key) is required to validate the new public key before it can be used. // Validation Authority: Generate new key pair. - status = atcab_genkey(private_key_id, public_key); + status = atca_test_genkey(private_key_id, public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); // Create and sign some data for testing the new key pair @@ -490,21 +669,29 @@ TEST(atca_cmd_basic_test, verify_invalidate) status = atcab_verify_stored(test_msg, test_signature, public_key_id, &is_verified); TEST_ASSERT_EQUAL(ATCA_EXECUTION_ERROR, status); } -#endif +#endif /* TEST_ATCAB_VERIFY_VALIDATE_EN */ // *INDENT-OFF* - Preserve formatting t_test_case_info verify_basic_test_info[] = { - { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_extern), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, -#ifdef ATCA_ATECC608_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_extern_mac), DEVICE_MASK(ATECC608) }, +#if TEST_ATCAB_VERIFY_EXTERN_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_extern_nist), DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_extern), DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, +#if TEST_ATCAB_VERIFY_MAC_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_extern_mac), DEVICE_MASK(ATECC608) }, +#endif +#endif /* TEST_ATCAB_VERIFY_EXTERN_EN */ +#if TEST_ATCAB_VERIFY_STORED_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_stored), DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, +#if TEST_ATCAB_VERIFY_REQRANDOM_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_stored_on_reqrandom_set), DEVICE_MASK_ATECC }, #endif - { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_stored), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, -#ifdef ATCA_ATECC608_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_stored_mac), DEVICE_MASK(ATECC608) }, +#if TEST_ATCAB_VERIFY_MAC_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_stored_mac), DEVICE_MASK(ATECC608) }, #endif -#ifdef ATCA_ECC_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_validate), DEVICE_MASK_ECC }, +#endif /* TEST_ATCAB_VERIFY_STORED_EN */ +#if TEST_ATCAB_VERIFY_VALIDATE_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_validate), DEVICE_MASK_ATECC }, { REGISTER_TEST_CASE(atca_cmd_basic_test, verify_invalidate), DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) }, #endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ diff --git a/test/api_atcab/atca_tests_write.c b/test/api_atcab/atca_tests_write.c index 189ef85f8..c0c8c92c9 100644 --- a/test/api_atcab/atca_tests_write.c +++ b/test/api_atcab/atca_tests_write.c @@ -25,13 +25,23 @@ * THIS SOFTWARE. */ #include -#include "atca_test.h" +#include "test_atcab.h" + +#ifndef TEST_ATCAB_WRITE_EN +#define TEST_ATCAB_WRITE_EN (CALIB_WRITE_EN || CALIB_WRITE_ECC204_EN || TALIB_WRITE_EN) +#endif + +#ifndef TEST_ATCAB_WRITE_ENC_EN +#define TEST_ATCAB_WRITE_ENC_EN CALIB_WRITE_ENC_EN +#endif + +#if TEST_ATCAB_WRITE_EN #ifndef ATCA_BLOCK_SIZE #define ATCA_BLOCK_SIZE (32) #endif -#if ATCA_CA_SUPPORT +#if CALIB_WRITE_EN TEST(atca_cmd_basic_test, write_boundary_conditions) { ATCA_STATUS status = ATCA_SUCCESS; @@ -390,17 +400,36 @@ TEST(atca_cmd_basic_test, write_data_zone_blocks) uint8_t read_data[sizeof(write_data)]; uint16_t slot; - // Test assumes ECC slot sizes - test_assert_data_is_locked(); + /* Note - This test assumes ECC slot sizes */ + if (ECC204 == gCfg->devtype) + { + /* This test for the ECC204 needs to be run when the device data is unlocked */ + test_assert_config_is_locked(); + test_assert_data_is_unlocked(); + } + else + { + /* For all other devices it has to be run when data zone is locked */ + test_assert_data_is_locked(); + } status = atca_test_config_get_id(TEST_TYPE_DATA, &slot); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - // Generate random data to be written - status = atcab_random(&write_data[0]); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atcab_random(&write_data[ATCA_BLOCK_SIZE]); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + if (ECC204 != gCfg->devtype) + { +#if CALIB_RANDOM_EN + // Generate random data to be written + status = atcab_random(&write_data[0]); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + status = atcab_random(&write_data[ATCA_BLOCK_SIZE]); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif + } + else + { + memset(write_data, 0x5A, sizeof(write_data)); + } // Test cross-block writes status = atcab_write_bytes_zone(ATCA_ZONE_DATA, slot, 4, write_data, sizeof(write_data)); @@ -411,17 +440,20 @@ TEST(atca_cmd_basic_test, write_data_zone_blocks) TEST_ASSERT_EQUAL_MEMORY(write_data, read_data, sizeof(write_data)); - // Test mid-block word writes - status = atcab_write_zone(ATCA_ZONE_DATA, slot, 1, 6, write_data, 4); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + if (ECC204 != gCfg->devtype) + { + // Test mid-block word writes + status = atcab_write_zone(ATCA_ZONE_DATA, slot, 1, 6, write_data, 4); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atcab_read_bytes_zone(ATCA_ZONE_DATA, slot, 56, read_data, 4); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + status = atcab_read_bytes_zone(ATCA_ZONE_DATA, slot, 56, read_data, 4); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_MEMORY(write_data, read_data, 4); + TEST_ASSERT_EQUAL_MEMORY(write_data, read_data, 4); + } } -#if ATCA_CA_SUPPORT +#if TEST_ATCAB_WRITE_ENC_EN TEST(atca_cmd_basic_test, write_bytes_zone_slot8) { ATCA_STATUS status = ATCA_SUCCESS; @@ -576,6 +608,11 @@ TEST(atca_cmd_basic_test, write_config_zone) status = atcab_write_config_zone(test_ecc608_configdata); break; #endif +#ifdef ATCA_ECC204_SUPPORT + case ECC204: + status = atcab_write_config_zone(test_ecc204_configdata); + break; +#endif #if ATCA_TA_SUPPORT case TA100: @@ -590,6 +627,7 @@ TEST(atca_cmd_basic_test, write_config_zone) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#if CALIB_WRITE_EN || TALIB_WRITE_EN TEST(atca_cmd_basic_test, write_pubkey) { uint16_t public_key_id; @@ -621,30 +659,38 @@ TEST(atca_cmd_basic_test, write_pubkey) TEST_ASSERT_EQUAL_MEMORY(public_key_ref, public_key, sizeof(public_key_ref)); } } +#endif + +#endif /* TEST_ATCAB_WRITE_EN */ // *INDENT-OFF* - Preserve formatting t_test_case_info write_basic_test_info[] = { -#if ATCA_CA_SUPPORT - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_boundary_conditions), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, +#if TEST_ATCAB_WRITE_EN +#if CALIB_WRITE_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_boundary_conditions), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, //{ REGISTER_TEST_CASE(atca_cmd_basic_test, write_upper_slots), DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_invalid_block), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_invalid_block_len), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_bytes_zone_config), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_otp_zone_nolock), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_otp_zone_nolock_check), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_otp_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_slot4_key), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_invalid_block), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_invalid_block_len), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_bytes_zone_config), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_otp_zone_nolock), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_otp_zone_nolock_check), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_otp_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_slot4_key), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, #endif { REGISTER_TEST_CASE(atca_cmd_basic_test, write_data_zone_blocks), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, -#if ATCA_CA_SUPPORT +#if TEST_ATCAB_WRITE_ENC_EN //{ REGISTER_TEST_CASE(atca_cmd_basic_test, write_bytes_zone_slot8), DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_enc), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_enc_data_unlock), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_enc), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_enc_data_unlock), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC }, +#endif + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_config_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#if CALIB_WRITE_EN + { REGISTER_TEST_CASE(atca_cmd_basic_test, write_pubkey), DEVICE_MASK_ATECC | DEVICE_MASK(TA100) }, +#endif #endif - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_config_zone), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100)}, - { REGISTER_TEST_CASE(atca_cmd_basic_test, write_pubkey), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; // *INDENT-ON* + diff --git a/test/api_atcab/test_atcab.c b/test/api_atcab/test_atcab.c new file mode 100644 index 000000000..12c8162f1 --- /dev/null +++ b/test/api_atcab/test_atcab.c @@ -0,0 +1,135 @@ +/** + * \file + * \brief Tests for the cryptoauthlib Basic API + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_test.h" +#include "test_atcab.h" + +static t_test_case_info* basic_tests[] = +{ + /* Basic chip Tests */ + startup_basic_test_info, + info_basic_test_info, + random_basic_test_info, + write_basic_test_info, + read_basic_test_info, + lock_basic_test_info, + + /* ECC Key Tests */ + genkey_basic_test_info, + privwrite_basic_test_info, + verify_basic_test_info, + sign_basic_test_info, + ecdh_basic_test_info, + + /* Hashing and MAC tests */ + sha_basic_test_info, + hmac_basic_test_info, + mac_basic_test_info, + derivekey_basic_test_info, + + /* Chip and Key Features */ + gendig_basic_test_info, + nonce_basic_test_info, + updateextra_basic_test_info, + counter_basic_test_info, + + /* Advanced part test */ + kdf_basic_test_info, + sboot_basic_test_info, + selftest_basic_test_info, + aes_basic_test_info, + aes_cbc_basic_test_info, + aes_cmac_basic_test_info, + aes_ctr_basic_test_info, + aes_cbcmac_basic_test_info, + aes_gcm_basic_test_info, + aes_ccm_basic_test_info, + (t_test_case_info*)NULL, /* Array Termination element*/ +}; + +void RunAllBasicTests(void) +{ + RunAllTests(basic_tests); +} + +int run_basic_tests(int argc, char* argv[]) +{ +#ifdef ATCA_ATECC608_SUPPORT + if (ATECC608 == (gCfg->devtype)) + { + check_clock_divider(argc, argv); + } +#endif + if (gCfg->devtype < ATCA_DEV_UNKNOWN) + { + return run_test(argc, argv, RunAllBasicTests); + } + else + { + printf("Device is NOT Selected... Select device before running tests!"); + return -1; + } +} + +const char* ATCA_TEST_HELPER_FILE = "In helper: " __FILE__; +const char* TEST_GROUP_atca_cmd_basic_test = "atca_cmd_basic_test"; + +TEST_SETUP(atca_cmd_basic_test) +{ + UnityMalloc_StartTest(); + + ATCA_STATUS status = atcab_init(gCfg); + TEST_ASSERT_SUCCESS_MSG(status, ATCA_TEST_HELPER_FILE); +} + +TEST_TEAR_DOWN(atca_cmd_basic_test) +{ + ATCA_STATUS status; + bool test_failed = atca_test_already_exiting(); + bool comm_failed = atca_test_unresponsive(); + + if(comm_failed) + { + /* Assume if there are comm failures there isn't a point trying to + continue to fail here */ + status = atcab_wakeup(); + if (!test_failed) TEST_ASSERT_SUCCESS_MSG(status, ATCA_TEST_HELPER_FILE); + + status = atcab_sleep(); + if (!test_failed) TEST_ASSERT_SUCCESS_MSG(status, ATCA_TEST_HELPER_FILE); + } + + status = atcab_release(); + if (!test_failed && !comm_failed) + { + /* Don't override the existing failure location or the global + status return value */ + TEST_ASSERT_SUCCESS_MSG(status, ATCA_TEST_HELPER_FILE); + } + + UnityMalloc_EndTest(); +} diff --git a/test/api_atcab/test_atcab.h b/test/api_atcab/test_atcab.h new file mode 100644 index 000000000..c9ce54c21 --- /dev/null +++ b/test/api_atcab/test_atcab.h @@ -0,0 +1,83 @@ +/** + * \file + * \brief Unity tests for the cryptoauthlib Basic API + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef TEST_ATCAB_H +#define TEST_ATCAB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "atca_test.h" + +extern t_test_case_info startup_basic_test_info[]; +extern t_test_case_info info_basic_test_info[]; +extern t_test_case_info aes_basic_test_info[]; +extern t_test_case_info aes_cbc_basic_test_info[]; +extern t_test_case_info aes_cmac_basic_test_info[]; +extern t_test_case_info aes_ctr_basic_test_info[]; +extern t_test_case_info aes_cbcmac_basic_test_info[]; +extern t_test_case_info aes_gcm_basic_test_info[]; +extern t_test_case_info aes_ccm_basic_test_info[]; +extern t_test_case_info verify_basic_test_info[]; +extern t_test_case_info derivekey_basic_test_info[]; +extern t_test_case_info sha_basic_test_info[]; +extern t_test_case_info hmac_basic_test_info[]; +extern t_test_case_info sign_basic_test_info[]; +extern t_test_case_info mac_basic_test_info[]; +extern t_test_case_info ecdh_basic_test_info[]; +extern t_test_case_info write_basic_test_info[]; +extern t_test_case_info read_basic_test_info[]; +extern t_test_case_info genkey_basic_test_info[]; +extern t_test_case_info privwrite_basic_test_info[]; +extern t_test_case_info lock_basic_test_info[]; +extern t_test_case_info kdf_basic_test_info[]; +extern t_test_case_info selftest_basic_test_info[]; +extern t_test_case_info gendig_basic_test_info[]; +extern t_test_case_info random_basic_test_info[]; +extern t_test_case_info nonce_basic_test_info[]; +extern t_test_case_info pause_basic_test_info[]; +extern t_test_case_info updateextra_basic_test_info[]; +extern t_test_case_info counter_basic_test_info[]; +extern t_test_case_info sboot_basic_test_info[]; + +/* Atcab unity tests */ +void RunAllBasicTests(void); + +/* Console function */ +int run_basic_tests(int argc, char* argv[]); + +/* Common test setup/teardown */ +extern const char* TEST_GROUP_atca_cmd_basic_test; +void TEST_atca_cmd_basic_test_SETUP(void); +void TEST_atca_cmd_basic_test_TEAR_DOWN(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/test/api_calib/test_calib.h b/test/api_calib/test_calib.h index f8d058fed..1c159c16f 100644 --- a/test/api_calib/test_calib.h +++ b/test/api_calib/test_calib.h @@ -38,6 +38,7 @@ extern t_test_case_info calib_commands_info[]; extern t_test_case_info calib_packet_info[]; ATCA_STATUS calib_config_get_slot_by_test(uint8_t test_type, uint16_t* handle); +ATCA_STATUS calib_config_get_ecc204_slot_by_test(uint8_t test_type, uint16_t* handle); #ifdef __cplusplus } diff --git a/test/api_calib/test_calib_config.c b/test/api_calib/test_calib_config.c index 4ea1f79c8..4f313c08b 100644 --- a/test/api_calib/test_calib_config.c +++ b/test/api_calib/test_calib_config.c @@ -38,6 +38,7 @@ const uint8_t g_slot4_key[] = { #include "test_calib.h" +#ifdef ATCA_ATECC608_SUPPORT uint8_t test_ecc608_configdata[ATCA_ECC_CONFIG_SIZE] = { 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x04, 0x05, 0x06, 0x07, 0xEE, 0x01, 0x01, 0x00, //15 0xC0, 0x00, 0xA1, 0x00, 0xAF, 0x2F, 0xC4, 0x44, 0x87, 0x20, 0xC4, 0xF4, 0x8F, 0x0F, 0x0F, 0x0F, //31, @@ -48,7 +49,9 @@ uint8_t test_ecc608_configdata[ATCA_ECC_CONFIG_SIZE] = { 0x33, 0x00, 0x1C, 0x00, 0x13, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x3A, 0x10, 0x1C, 0x00, 0x33, 0x00, //111 0x1C, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x30, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x32, 0x00, 0x30, 0x00 //127 }; +#endif +#if defined(ATCA_ATECC108A_SUPPORT) || defined(ATCA_ATECC508A_SUPPORT) const uint8_t test_ecc_configdata[ATCA_ECC_CONFIG_SIZE] = { 0x01, 0x23, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00, 0x04, 0x05, 0x06, 0x07, 0xEE, 0x00, 0x01, 0x00, //15 0xC0, 0x00, 0x55, 0x00, 0x8F, 0x2F, 0xC4, 0x44, 0x87, 0x20, 0xC4, 0xF4, 0x8F, 0x0F, 0x8F, 0x8F, //31, @@ -59,33 +62,67 @@ const uint8_t test_ecc_configdata[ATCA_ECC_CONFIG_SIZE] = { 0x33, 0x00, 0x1C, 0x00, 0x13, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x33, 0x00, //111 0x1C, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0x30, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x32, 0x00, 0x30, 0x00 //127 }; +#endif + static device_object_meta_t calib_config_object_data[] = { - { TEST_TYPE_ECC_SIGN, 2, NULL }, - { TEST_TYPE_ECC_VERIFY, 15, NULL }, - { TEST_TYPE_ECC_GENKEY, 2, NULL }, - { TEST_TYPE_ECDH, 0, NULL }, - { TEST_TYPE_AES, 10, NULL }, - { TEST_TYPE_HMAC, 4, NULL }, - { TEST_TYPE_DATA, 11, NULL }, - { 0, 0, NULL } + { TEST_TYPE_ECC_SIGN, 2, NULL }, + { TEST_TYPE_ECC_VERIFY, 15, NULL }, + { TEST_TYPE_ECC_GENKEY, 2, NULL }, + { TEST_TYPE_ECDH, 0, NULL }, + { TEST_TYPE_AES, 10, NULL }, + { TEST_TYPE_HMAC, 4, NULL }, + { TEST_TYPE_DATA, 11, NULL }, + { 0, 0, NULL } }; -ATCA_STATUS calib_config_get_slot_by_test(uint8_t test_type, uint16_t* handle) + + +static ATCA_STATUS calib_config_get_slot_internal(device_object_meta_t * table, uint8_t test_type, uint16_t* handle) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; - device_object_meta_t* ptr = calib_config_object_data; - for (; ptr->test_type; ptr++) + for (; table->test_type; table++) { - if (ptr->test_type == test_type) + if (table->test_type == test_type) { - *handle = ptr->handle; + *handle = table->handle; status = ATCA_SUCCESS; break; } } return status; } + +ATCA_STATUS calib_config_get_slot_by_test(uint8_t test_type, uint16_t* handle) +{ + return calib_config_get_slot_internal(calib_config_object_data, test_type, handle); +} #endif + +#ifdef ATCA_ECC204_SUPPORT + +const uint8_t test_ecc204_configdata[ATCA_ECC204_CONFIG_SIZE] = { + 0xB9, 0xFA, 0x3C, 0x1A, 0xAA, 0xD4, 0x91, 0x7C, 0x03, 0x3C, 0x00, 0x00, 0x3E, 0xAF, 0x81, 0x80, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +static device_object_meta_t calib_config_ecc204_object_data[] = +{ + { TEST_TYPE_ECC_SIGN, 0, NULL }, + { TEST_TYPE_ECC_GENKEY, 0, NULL }, + { TEST_TYPE_DATA, 1, NULL }, + { 0, 0, NULL } +}; + +ATCA_STATUS calib_config_get_ecc204_slot_by_test(uint8_t test_type, uint16_t* handle) +{ + return calib_config_get_slot_internal(calib_config_ecc204_object_data, test_type, handle); +} + + +#endif + diff --git a/lib/crypto/atca_crypto_sw_ecdsa.c b/test/api_crypto/test_crypto.c similarity index 57% rename from lib/crypto/atca_crypto_sw_ecdsa.c rename to test/api_crypto/test_crypto.c index 137007757..109b61867 100644 --- a/lib/crypto/atca_crypto_sw_ecdsa.c +++ b/test/api_crypto/test_crypto.c @@ -1,7 +1,6 @@ /** * \file - * \brief API wrapper for software ECDSA verify. Currently unimplemented but could be - * implemented via a 3rd party library such as MicroECC. + * \brief Tests for the CryptoAuthLib software crypto API. * * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. * @@ -26,23 +25,27 @@ * THIS SOFTWARE. */ +#include "test_crypto.h" -#include "atca_crypto_sw_ecdsa.h" - -/** \brief return software generated ECDSA verification result and the function is currently not implemented - * \param[in] msg ptr to message or challenge - * \param[in] signature ptr to the signature to verify - * \param[in] public_key ptr to public key of device which signed the challenge - * return ATCA_UNIMPLEMENTED , as the function is currently not implemented - */ +static t_test_case_info* atcac_tests[] = +{ + atcac_sha_test_info, + atcac_pbkdf2_test_info, + atcac_pad_test_info, +#if defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) + atcac_aes_test_info, + atcac_pk_test_info, +#endif + (t_test_case_info*)NULL, /* Array Termination element*/ +}; -int atcac_sw_ecdsa_verify_p256(const uint8_t msg[ATCA_ECC_P256_FIELD_SIZE], - const uint8_t signature[ATCA_ECC_P256_SIGNATURE_SIZE], - const uint8_t public_key[ATCA_ECC_P256_PUBLIC_KEY_SIZE]) +static void run_atcac_tests(void) { - (void)msg; - (void)signature; - (void)public_key; + RunAllTests(atcac_tests); +} - return ATCA_UNIMPLEMENTED; +/* Console function */ +int atca_crypto_sw_tests(int argc, char* argv[]) +{ + return run_test(argc, argv, run_atcac_tests); } diff --git a/lib/crypto/atca_crypto_sw_ecdsa.h b/test/api_crypto/test_crypto.h similarity index 61% rename from lib/crypto/atca_crypto_sw_ecdsa.h rename to test/api_crypto/test_crypto.h index bb33b43c4..6926dc61e 100644 --- a/lib/crypto/atca_crypto_sw_ecdsa.h +++ b/test/api_crypto/test_crypto.h @@ -1,6 +1,6 @@ /** * \file - * \brief + * \brief Tests for the CryptoAuthLib software crypto API. * * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. * @@ -25,38 +25,27 @@ * THIS SOFTWARE. */ - -#ifndef ATCA_CRYPTO_SW_ECDSA_H -#define ATCA_CRYPTO_SW_ECDSA_H - -#include "atca_crypto_sw.h" -#include -#include - -/** \defgroup atcac_ Software crypto methods (atcac_) - * - * \brief - * These methods provide a software implementation of various crypto - * algorithms - * - @{ */ - -#define ATCA_ECC_P256_FIELD_SIZE (256 / 8) -#define ATCA_ECC_P256_PRIVATE_KEY_SIZE (ATCA_ECC_P256_FIELD_SIZE) -#define ATCA_ECC_P256_PUBLIC_KEY_SIZE (ATCA_ECC_P256_FIELD_SIZE * 2) -#define ATCA_ECC_P256_SIGNATURE_SIZE (ATCA_ECC_P256_FIELD_SIZE * 2) +#ifndef TEST_CRYPTO_H +#define TEST_CRYPTO_H #ifdef __cplusplus extern "C" { #endif -int atcac_sw_ecdsa_verify_p256(const uint8_t msg[ATCA_ECC_P256_FIELD_SIZE], - const uint8_t signature[ATCA_ECC_P256_SIGNATURE_SIZE], - const uint8_t public_key[ATCA_ECC_P256_PUBLIC_KEY_SIZE]); + +#include "atca_test.h" + +extern t_test_case_info atcac_aes_test_info[]; +extern t_test_case_info atcac_pk_test_info[]; +extern t_test_case_info atcac_pbkdf2_test_info[]; +extern t_test_case_info atcac_pad_test_info[]; +extern t_test_case_info atcac_sha_test_info[]; + +/* Console function */ +int atca_crypto_sw_tests(int argc, char* argv[]); #ifdef __cplusplus } #endif -/** @} */ -#endif +#endif /* TEST_CRYPTO_H */ diff --git a/test/api_crypto/test_crypto_aes.c b/test/api_crypto/test_crypto_aes.c new file mode 100644 index 000000000..afb6f6e09 --- /dev/null +++ b/test/api_crypto/test_crypto_aes.c @@ -0,0 +1,227 @@ +/** + * \file + * \brief Tests for the CryptoAuthLib software crypto API. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "test_crypto.h" + +#if defined(ATCA_OPENSSL) || defined(ATCA_MBEDTLS) || defined(ATCA_WOLFSSL) + +#include "vectors/aes_gcm_nist_vectors.h" +#include "vectors/aes_cmac_nist_vectors.h" + +TEST_GROUP(atcac_aes); + +TEST_SETUP(atcac_aes) +{ + UnityMalloc_StartTest(); +} + +TEST_TEAR_DOWN(atcac_aes) +{ + UnityMalloc_EndTest(); +} + +TEST(atcac_aes, aes128_gcm_nist) +{ + ATCA_STATUS status; + uint8_t test_index; + uint8_t ciphertext[GCM_TEST_VECTORS_DATA_SIZE_MAX]; + uint8_t plaintext[GCM_TEST_VECTORS_DATA_SIZE_MAX]; +#ifndef ATCA_WOLFSSL + size_t ct_size; + size_t pt_size; +#endif + uint8_t tag[AES_DATA_SIZE]; + bool is_verified; + atcac_aes_gcm_ctx ctx; + + + for (test_index = 0; test_index < GCM_TEST_VECTORS_COUNT; test_index++) + { + ////////////////////////////////////// Encryption ///////////////////////////////////////// + status = atcac_aes_gcm_encrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + +#ifdef ATCA_WOLFSSL + status = atcac_aes_gcm_encrypt(&ctx, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size, ciphertext, + tag, sizeof(tag), gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#else + //Add aad to gcm + status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Encrypt data + ct_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; + status = atcac_aes_gcm_encrypt_update(&ctx, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size, ciphertext, &ct_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif + //Verify ciphertext with expected data + if (gcm_test_cases[test_index].text_size > 0) + { + TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].ciphertext, ciphertext, gcm_test_cases[test_index].text_size); + } + +#ifndef ATCA_WOLFSSL + //Calculate authentication tag + status = atcac_aes_gcm_encrypt_finish(&ctx, tag, sizeof(tag)); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif + + //Verify calculated tag + TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].tag, tag, sizeof(tag)); + +#ifndef ATCA_WOLFSSL + // Repeat, but skip unused calls + if (gcm_test_cases[test_index].aad_size == 0 || gcm_test_cases[test_index].text_size == 0) + { + //Initialize gcm ctx with IV + status = atcac_aes_gcm_encrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Add aad to gcm + status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Encrypt data + if (gcm_test_cases[test_index].text_size > 0) + { + ct_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; + status = atcac_aes_gcm_encrypt_update(&ctx, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size, ciphertext, &ct_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].ciphertext, ciphertext, gcm_test_cases[test_index].text_size); + } + + //Calculate authentication tag + status = atcac_aes_gcm_encrypt_finish(&ctx, tag, sizeof(tag)); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Verify calculated tag + TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].tag, tag, sizeof(tag)); + } +#endif + + + ////////////////////////////////////// Decryption ///////////////////////////////////////// + //Initialize gcm ctx with IV + status = atcac_aes_gcm_decrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + +#ifdef ATCA_WOLFSSL + status = atcac_aes_gcm_decrypt(&ctx, gcm_test_cases[test_index].ciphertext, gcm_test_cases[test_index].text_size, plaintext, tag, sizeof(tag), + gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size, &is_verified); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#else + + //Add aad to gcm + status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Add ciphertext to gcm + pt_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; + status = atcac_aes_gcm_decrypt_update(&ctx, gcm_test_cases[test_index].ciphertext, gcm_test_cases[test_index].text_size, plaintext, &pt_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif + //Verify plaintext with expected data + if (gcm_test_cases[test_index].text_size > 0) + { + TEST_ASSERT_EQUAL_MEMORY(plaintext, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size); + } + +#ifndef ATCA_WOLFSSL + status = atcac_aes_gcm_decrypt_finish(&ctx, gcm_test_cases[test_index].tag, sizeof(tag), &is_verified); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif + TEST_ASSERT(is_verified); + +#ifndef ATCA_WOLFSSL + // Repeat, but skip unused calls + if (gcm_test_cases[test_index].aad_size == 0 || gcm_test_cases[test_index].text_size == 0) + { + //Initialize gcm ctx with IV + status = atcac_aes_gcm_decrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Add aad to gcm + status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Add ciphertext to gcm + if (gcm_test_cases[test_index].text_size > 0) + { + pt_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; + status = atcac_aes_gcm_decrypt_update(&ctx, gcm_test_cases[test_index].ciphertext, gcm_test_cases[test_index].text_size, plaintext, &pt_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + //Verify plaintext with expected data + TEST_ASSERT_EQUAL_MEMORY(plaintext, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size); + } + + status = atcac_aes_gcm_decrypt_finish(&ctx, gcm_test_cases[test_index].tag, sizeof(tag), &is_verified); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT(is_verified); + } +#endif + } +} + +TEST(atcac_aes, aes128_cmac_nist) +{ + ATCA_STATUS status = 0; + atcac_aes_cmac_ctx ctx; + uint8_t key_block = 0; + size_t msg_index = 0; + uint8_t cmac[AES_DATA_SIZE]; + size_t cmac_size; + + for (key_block = 0; key_block < 4; key_block++) + { + for (msg_index = 0; msg_index < sizeof(g_cmac_msg_sizes) / sizeof(g_cmac_msg_sizes[0]); msg_index++) + { + status = atcac_aes_cmac_init(&ctx, g_aes_keys[key_block], 16); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcac_aes_cmac_update(&ctx, g_plaintext, g_cmac_msg_sizes[msg_index]); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + cmac_size = sizeof(cmac); + status = atcac_aes_cmac_finish(&ctx, cmac, &cmac_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(g_cmacs[key_block][msg_index], cmac, sizeof(cmac)); + } + } +} + +// *INDENT-OFF* - Preserve formatting +t_test_case_info atcac_aes_test_info[] = +{ + { REGISTER_TEST_CASE(atcac_aes, aes128_gcm_nist), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_aes, aes128_cmac_nist), DEVICE_MASK_NONE }, + { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ +}; +// *INDENT-ON* + +#endif diff --git a/test/api_crypto/test_crypto_pad.c b/test/api_crypto/test_crypto_pad.c new file mode 100644 index 000000000..5011baf32 --- /dev/null +++ b/test/api_crypto/test_crypto_pad.c @@ -0,0 +1,132 @@ +/** + * \file + * \brief Tests for the CryptoAuthLib software crypto API. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_test.h" +#include "vectors/pkcs7_pad_vectors.h" + +#ifndef TEST_ATCAC_PKCS7_EN +#define TEST_ATCAC_PKCS7_EN ATCAC_PKCS7_PAD_EN +#endif + +#if TEST_ATCAC_PKCS7_EN +TEST_GROUP(atcac_pkcs7); + +TEST_SETUP(atcac_pkcs7) +{ + UnityMalloc_StartTest(); +} + +TEST_TEAR_DOWN(atcac_pkcs7) +{ + UnityMalloc_EndTest(); +} + +TEST(atcac_pkcs7, pad_success) +{ + ATCA_STATUS status; + const pkcs7_pad_test_vector * pVector = pkcs7_pad_test_vectors; + size_t i; + uint8_t buffer[130]; + size_t length1; + size_t length2; + + for (i = 0; i < pkcs7_pad_test_vectors_count; i++, pVector++) + { + length1 = sizeof(buffer)/2; + status = atcab_hex2bin(pVector->in, strlen(pVector->in), &buffer[sizeof(buffer)/2], &length1); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + length2 = sizeof(buffer)/2; + status = atcac_pkcs7_pad(&buffer[sizeof(buffer)/2], &length2, length1, pVector->blocksize); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + length1 = sizeof(buffer); + status = atcab_bin2hex_(&buffer[sizeof(buffer)/2], length2, (char*)buffer, &length1, false, false, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + TEST_ASSERT_EQUAL_MEMORY(pVector->out, buffer, length1); + } +} + +TEST(atcac_pkcs7, unpad_success) +{ + ATCA_STATUS status; + const pkcs7_pad_test_vector * pVector = pkcs7_pad_test_vectors; + size_t i; + uint8_t buffer[130]; + size_t length1; + size_t length2; + + for (i = 0; i < pkcs7_pad_test_vectors_count; i++, pVector++) + { + length1 = sizeof(buffer)/2; + status = atcab_hex2bin(pVector->out, strlen(pVector->out), &buffer[sizeof(buffer)/2], &length1); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcac_pkcs7_unpad(&buffer[sizeof(buffer)/2], &length1, pVector->blocksize); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + length2 = sizeof(buffer); + status = atcab_bin2hex_(&buffer[sizeof(buffer)/2], length1, (char*)buffer, &length2, false, false, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + TEST_ASSERT_EQUAL_MEMORY(pVector->in, buffer, length2); + } +} + +TEST(atcac_pkcs7, unpad_invalid) +{ + ATCA_STATUS status; + const pkcs7_pad_test_vector * pVector = pkcs7_unpad_test_vectors; + size_t i; + uint8_t buffer[65]; + size_t length1; + + for (i = 0; i < pkcs7_unpad_test_vectors_count; i++, pVector++) + { + length1 = sizeof(buffer); + status = atcab_hex2bin(pVector->in, strlen(pVector->in), buffer, &length1); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcac_pkcs7_unpad(buffer, &length1, pVector->blocksize); + TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); + } +} + +#endif /* TEST_ATCAC_PBKDF2_EN */ + + +t_test_case_info atcac_pad_test_info[] = +{ +#if TEST_ATCAC_PKCS7_EN + { REGISTER_TEST_CASE(atcac_pkcs7, pad_success), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_pkcs7, unpad_success), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_pkcs7, unpad_invalid), DEVICE_MASK_NONE }, +#endif + /* Array Termination element*/ + { (fp_test_case)NULL, (uint8_t)0 }, +}; diff --git a/test/api_crypto/test_crypto_pbkdf2.c b/test/api_crypto/test_crypto_pbkdf2.c index 202f3376e..3bdea42f4 100644 --- a/test/api_crypto/test_crypto_pbkdf2.c +++ b/test/api_crypto/test_crypto_pbkdf2.c @@ -28,17 +28,28 @@ #include "atca_test.h" #include "vectors/pbkdf2_sha256_vectors.h" -TEST_GROUP(atca_crypto_pbkdf2_sw); +#ifndef TEST_ATCAC_PBKDF2_EN +#define TEST_ATCAC_PBKDF2_EN ATCAC_PBKDF2_SHA256_EN +#endif -TEST_SETUP(atca_crypto_pbkdf2_sw) +#ifndef TEST_ATCAB_PBKDF2_EN +#define TEST_ATCAB_PBKDF2_EN ATCAB_PBKDF2_SHA256_EN +#endif + +#if TEST_ATCAC_PBKDF2_EN +TEST_GROUP(atcac_pbkdf2); + +TEST_SETUP(atcac_pbkdf2) { + UnityMalloc_StartTest(); } -TEST_TEAR_DOWN(atca_crypto_pbkdf2_sw) +TEST_TEAR_DOWN(atcac_pbkdf2) { + UnityMalloc_EndTest(); } -TEST(atca_crypto_pbkdf2_sw, vectors) +TEST(atcac_pbkdf2, vectors) { ATCA_STATUS status; const pbkdf2_sha256_test_vector * pVector = pbkdf2_sha256_test_vectors; @@ -53,8 +64,38 @@ TEST(atca_crypto_pbkdf2_sw, vectors) TEST_ASSERT_EQUAL_MEMORY(pVector->dk, result, pVector->dklen); } } +#endif /* TEST_ATCAC_PBKDF2_EN */ + +#if TEST_ATCAB_PBKDF2_EN +TEST_GROUP(atcab_pbkdf2); + +TEST_SETUP(atcab_pbkdf2) +{ + UnityMalloc_StartTest(); + + TEST_IGNORE_MESSAGE("Skipping because a device is NOT selected"); + + ATCA_STATUS status = atcab_init(gCfg); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +} + +TEST_TEAR_DOWN(atcab_pbkdf2) +{ + ATCA_STATUS status; + + status = atcab_wakeup(); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcab_sleep(); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcab_release(); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + UnityMalloc_EndTest(); +} -TEST(atca_cmd_basic_test, pdkdf2_hw_vectors) +TEST(atcab_pbkdf2, vectors) { ATCA_STATUS status; const pbkdf2_sha256_fixed_size_test_vector* pVector = pbkdf2_sha256_fixed_size_test_vectors; @@ -72,11 +113,18 @@ TEST(atca_cmd_basic_test, pdkdf2_hw_vectors) TEST_ASSERT_EQUAL_MEMORY(pVector->dk, result, ATCA_SHA256_DIGEST_SIZE); } } +#endif /* TEST_ATCAB_PBKDF2_EN */ -t_test_case_info test_crypto_pbkdf2_info[] = +t_test_case_info atcac_pbkdf2_test_info[] = { - { REGISTER_TEST_CASE(atca_crypto_pbkdf2_sw, vectors), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, - { REGISTER_TEST_CASE(atca_cmd_basic_test, pdkdf2_hw_vectors), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#if TEST_ATCAC_PBKDF2_EN + { REGISTER_TEST_CASE(atcac_pbkdf2, vectors), DEVICE_MASK_NONE }, +#endif +#if TEST_ATCAB_PBKDF2_EN + { REGISTER_TEST_CASE(atcab_pbkdf2, vectors), DEVICE_MASK(ATSHA204A) | DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, +#endif /* Array Termination element*/ { (fp_test_case)NULL, (uint8_t)0 }, }; + + diff --git a/test/api_crypto/test_crypto_pk.c b/test/api_crypto/test_crypto_pk.c new file mode 100644 index 000000000..5915ad0e0 --- /dev/null +++ b/test/api_crypto/test_crypto_pk.c @@ -0,0 +1,213 @@ +/** + * \file + * \brief Tests for the CryptoAuthLib software crypto API. + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "test_crypto.h" + +#if defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) + +#include "vectors/ecdsa_nist_vectors.h" +#include "vectors/ecdh_nist_vectors.h" + +TEST_GROUP(atcac_pk); + +TEST_SETUP(atcac_pk) +{ + UnityMalloc_StartTest(); +} + +TEST_TEAR_DOWN(atcac_pk) +{ + UnityMalloc_EndTest(); +} + +TEST(atcac_pk, verify_nist) +{ + uint8_t pubkey[64]; + uint8_t signature[64]; + uint8_t digest[32]; + atcac_pk_ctx pkey_ctx; + ATCA_STATUS status; + size_t i; + + /* Test verification using [P-256,SHA-256] vectors */ + for (i = 0; i < ecdsa_p256_test_vectors_count; i++) + { + /* Copy pubkey */ + memcpy(pubkey, ecdsa_p256_test_vectors[i].Qx, 32); + memcpy(&pubkey[32], ecdsa_p256_test_vectors[i].Qy, 32); + + /* Copy the signature */ + memcpy(signature, ecdsa_p256_test_vectors[i].R, 32); + memcpy(&signature[32], ecdsa_p256_test_vectors[i].S, 32); + + /* Hash the message */ + status = atcac_sw_sha2_256(ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Initialize the key using the provided X,Y cordinantes */ + status = atcac_pk_init(&pkey_ctx, pubkey, sizeof(pubkey), 0, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Perform the verification */ + status = atcac_pk_verify(&pkey_ctx, digest, sizeof(digest), signature, sizeof(signature)); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result against the expected success/failure */ + if (ecdsa_p256_test_vectors[i].Result) + { + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + } + else + { + TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); + } + } +} + +static uint8_t private_key_pem[] = + "-----BEGIN EC PRIVATE KEY-----\n" + "MHcCAQEEICFZhAyzqkUgyheo51bhg3mcp+qwfl+koE+Mhs/sRyzBoAoGCCqGSM49\n" + "AwEHoUQDQgAExAE2yqujppBzD0hIpdqdXmMgtlXT90QqllaQYWEVBjdf+LmY5DCf\n" + "Mx8PXEVxhbDmgo6HHbz0S4VaZjShBLMaPw==\n" + "-----END EC PRIVATE KEY-----\n"; + +static uint8_t public_key_pem[] = + "-----BEGIN PUBLIC KEY-----\n" + "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExAE2yqujppBzD0hIpdqdXmMgtlXT\n" + "90QqllaQYWEVBjdf+LmY5DCfMx8PXEVxhbDmgo6HHbz0S4VaZjShBLMaPw==\n" + "-----END PUBLIC KEY-----\n"; + +static uint8_t public_key_bytes[64] = { + 0xc4, 0x01, 0x36, 0xca, 0xab, 0xa3, 0xa6, 0x90, 0x73, 0x0f, 0x48, 0x48, 0xa5, 0xda, 0x9d, 0x5e, + 0x63, 0x20, 0xb6, 0x55, 0xd3, 0xf7, 0x44, 0x2a, 0x96, 0x56, 0x90, 0x61, 0x61, 0x15, 0x06, 0x37, + 0x5f, 0xf8, 0xb9, 0x98, 0xe4, 0x30, 0x9f, 0x33, 0x1f, 0x0f, 0x5c, 0x45, 0x71, 0x85, 0xb0, 0xe6, + 0x82, 0x8e, 0x87, 0x1d, 0xbc, 0xf4, 0x4b, 0x85, 0x5a, 0x66, 0x34, 0xa1, 0x04, 0xb3, 0x1a, 0x3f +}; + +TEST(atcac_pk, init_public) +{ + atcac_pk_ctx priv_ctx; + uint8_t public_key[64]; + size_t public_key_size = 64; + ATCA_STATUS status; + + /* Test initialization of a private key with a pem encoded key (without password) */ + status = atcac_pk_init_pem(&priv_ctx, private_key_pem, sizeof(private_key_pem), false); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcac_pk_public(&priv_ctx, public_key, &public_key_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + TEST_ASSERT_EQUAL_MEMORY(public_key_bytes, public_key, 64); + + status = atcac_pk_free(&priv_ctx); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +} + +TEST(atcac_pk, sign_simple) +{ + atcac_pk_ctx sign_ctx; + atcac_pk_ctx verify_ctx; + uint8_t digest[32] = { 0x1A, 0x3A, 0xA5, 0x45, 0x04, 0x94, 0x53, 0xAF, + 0xDF, 0x17, 0xE9, 0x89, 0xA4, 0x1F, 0xA0, 0x97, + 0x94, 0xA5, 0x1B, 0xD5, 0xDB, 0x91, 0x36, 0x37, + 0x67, 0x55, 0x0C, 0x0F, 0x0A, 0xF3, 0x27, 0xD4 }; + uint8_t signature[128]; + size_t sig_size = sizeof(signature); + ATCA_STATUS status; + + memset(signature, 0, sig_size); + + /* Test initialization of a private key with a pem encoded key (without password) */ + status = atcac_pk_init_pem(&sign_ctx, private_key_pem, sizeof(private_key_pem), false); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Test signing with the private key */ + status = atcac_pk_sign(&sign_ctx, digest, sizeof(digest), signature, &sig_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Test initialization of a public key with a pem encoded key */ + status = atcac_pk_init_pem(&verify_ctx, public_key_pem, sizeof(public_key_pem), true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Test verification of the siguature */ + status = atcac_pk_verify(&verify_ctx, digest, sizeof(digest), &signature[sig_size - 64], 64); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + signature[10] ^= signature[10]; + + /* Test failure to validate a corrupted signature */ + status = atcac_pk_verify(&verify_ctx, digest, sizeof(digest), &signature[sig_size - 64], 64); + TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); +} + +TEST(atcac_pk, derive_ecdh_p256_nist) +{ + ATCA_STATUS status; + atcac_pk_ctx pri_ctx; + atcac_pk_ctx pub_ctx; + uint8_t result[32]; + size_t result_size; + size_t i; + + /* Test verification using [P-256] vectors */ + for (i = 0; i < ecdh_p256_test_vectors_count; i++) + { + uint8_t pubkey[64]; + + memcpy(pubkey, ecdh_p256_test_vectors[i].QCAVSx, 32); + memcpy(&pubkey[32], ecdh_p256_test_vectors[i].QCAVSy, 32); + + (void)atcac_pk_init(&pub_ctx, pubkey, sizeof(pubkey), 0, true); + (void)atcac_pk_init(&pri_ctx, (uint8_t*)ecdh_p256_test_vectors[i].dIUT, 32, 0, false); + + result_size = sizeof(result); + status = atcac_pk_derive(&pri_ctx, &pub_ctx, result, &result_size); + + (void)atcac_pk_free(&pri_ctx); + (void)atcac_pk_free(&pub_ctx); + + /* Check Test Results */ + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL_MEMORY(ecdh_p256_test_vectors[i].ZIUT, result, 32); + } +} + +// *INDENT-OFF* - Preserve formatting +t_test_case_info atcac_pk_test_info[] = +{ + { REGISTER_TEST_CASE(atcac_pk, verify_nist), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_pk, init_public), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_pk, sign_simple), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_pk, derive_ecdh_p256_nist), DEVICE_MASK_NONE }, + { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ +}; +// *INDENT-ON* + +#endif diff --git a/test/atca_crypto_sw_tests.c b/test/api_crypto/test_crypto_sha.c similarity index 53% rename from test/atca_crypto_sw_tests.c rename to test/api_crypto/test_crypto_sha.c index c06456bc9..b4407dcdc 100644 --- a/test/atca_crypto_sw_tests.c +++ b/test/api_crypto/test_crypto_sha.c @@ -25,65 +25,38 @@ * THIS SOFTWARE. */ -#include "cryptoauthlib.h" - -#include "atca_crypto_sw_tests.h" +#include "test_crypto.h" #include "crypto/atca_crypto_sw.h" -#include "crypto/atca_crypto_sw_sha1.h" -#include "crypto/atca_crypto_sw_sha2.h" +#ifndef TEST_ATCAC_SHA1_EN +#define TEST_ATCAC_SHA1_EN ATCAC_SHA1_EN +#endif + +#ifndef TEST_ATCAC_SHA256_EN +#define TEST_ATCAC_SHA256_EN ATCAC_SHA256_EN +#endif -#include "vectors/aes_gcm_nist_vectors.h" -#include "vectors/aes_cmac_nist_vectors.h" -#include "vectors/ecdsa_nist_vectors.h" -#include "vectors/ecdh_nist_vectors.h" +#include "crypto/atca_crypto_sw_sha1.h" +#include "crypto/atca_crypto_sw_sha2.h" static const uint8_t nist_hash_msg1[] = "abc"; static const uint8_t nist_hash_msg2[] = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; static const uint8_t nist_hash_msg3[] = "a"; -int atca_crypto_sw_tests(int argc, char * argv[]) +TEST_GROUP(atcac_sha); + +TEST_SETUP(atcac_sha) { - ((void)argc); - ((void)argv); - - UnityBegin("atca_crypto_sw_tests.c"); - - RUN_TEST(test_atcac_sw_sha1_nist1); - RUN_TEST(test_atcac_sw_sha1_nist2); - RUN_TEST(test_atcac_sw_sha1_nist3); - RUN_TEST(test_atcac_sw_sha1_nist_short); - RUN_TEST(test_atcac_sw_sha1_nist_long); - RUN_TEST(test_atcac_sw_sha1_nist_monte); - - RUN_TEST(test_atcac_sw_sha2_256_nist1); - RUN_TEST(test_atcac_sw_sha2_256_nist2); - RUN_TEST(test_atcac_sw_sha2_256_nist3); - RUN_TEST(test_atcac_sw_sha2_256_nist_short); - RUN_TEST(test_atcac_sw_sha2_256_nist_long); - RUN_TEST(test_atcac_sw_sha2_256_nist_monte); - - RUN_TEST(test_atcac_sha256_hmac); - RUN_TEST(test_atcac_sha256_hmac_nist); - -#if defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) - RUN_TEST(test_atcac_aes128_gcm); - RUN_TEST(test_atcac_aes128_cmac); - - RUN_TEST(test_atcac_public); - /* Because it is not realistic to perform signature vector tests on real - systems the verify test is executed first to ensure verify is working - correctly which will then be used to bootstrap the sign test */ - RUN_TEST(test_atcac_verify_nist); - RUN_TEST(test_atcac_sign); - - RUN_TEST(test_atcac_derive_nist); -#endif + UnityMalloc_StartTest(); +} - return UnityEnd(); +TEST_TEAR_DOWN(atcac_sha) +{ + UnityMalloc_EndTest(); } -void test_atcac_sw_sha1_nist1(void) +#if TEST_ATCAC_SHA1_EN +TEST(atcac_sha, sha1_nist1) { const uint8_t digest_ref[] = { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a, 0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c, @@ -99,7 +72,7 @@ void test_atcac_sw_sha1_nist1(void) TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); } -void test_atcac_sw_sha1_nist2(void) +TEST(atcac_sha, sha1_nist2) { const uint8_t digest_ref[] = { 0x84, 0x98, 0x3e, 0x44, 0x1c, 0x3b, 0xd2, 0x6e, 0xba, 0xae, 0x4a, 0xa1, 0xf9, 0x51, 0x29, 0xe5, @@ -115,7 +88,7 @@ void test_atcac_sw_sha1_nist2(void) TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); } -void test_atcac_sw_sha1_nist3(void) +TEST(atcac_sha, sha1_nist3) { const uint8_t digest_ref[] = { 0x34, 0xaa, 0x97, 0x3c, 0xd4, 0xc4, 0xda, 0xa4, 0xf6, 0x1e, 0xeb, 0x2b, 0xdb, 0xad, 0x27, 0x31, @@ -139,6 +112,7 @@ void test_atcac_sw_sha1_nist3(void) TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); } +#endif #if defined(_WIN32) || defined(__linux__) static void hex_to_uint8(const char hex_str[2], uint8_t* num) @@ -276,6 +250,7 @@ static int read_rsp_int_value(FILE* file, const char* name, int* value) #endif +#if TEST_ATCAC_SHA1_EN static void test_atcac_sw_sha1_nist_simple(const char* filename) { #if !defined(_WIN32) && !defined(__linux__) @@ -323,17 +298,17 @@ static void test_atcac_sw_sha1_nist_simple(const char* filename) #endif } -void test_atcac_sw_sha1_nist_short(void) +TEST(atcac_sha, sha1_nist_short) { test_atcac_sw_sha1_nist_simple("sha-byte-test-vectors/SHA1ShortMsg.rsp"); } -void test_atcac_sw_sha1_nist_long(void) +TEST(atcac_sha, sha1_nist_long) { test_atcac_sw_sha1_nist_simple("sha-byte-test-vectors/SHA1LongMsg.rsp"); } -void test_atcac_sw_sha1_nist_monte(void) +TEST(atcac_sha, sha1_nist_monte) { #if !defined(_WIN32) && !defined(__linux__) TEST_IGNORE_MESSAGE("Test is not available for this platform."); @@ -372,10 +347,10 @@ void test_atcac_sw_sha1_nist_monte(void) } #endif } +#endif /* TEST_ATCAC_SHA1_EN */ - - -void test_atcac_sw_sha2_256_nist1(void) +#if TEST_ATCAC_SHA256_EN +TEST(atcac_sha, sha256_nist1) { const uint8_t digest_ref[] = { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA, 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23, @@ -391,7 +366,7 @@ void test_atcac_sw_sha2_256_nist1(void) TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); } -void test_atcac_sw_sha2_256_nist2(void) +TEST(atcac_sha, sha256_nist2) { const uint8_t digest_ref[] = { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8, 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39, @@ -407,7 +382,7 @@ void test_atcac_sw_sha2_256_nist2(void) TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); } -void test_atcac_sw_sha2_256_nist3(void) +TEST(atcac_sha, sha256_nist3) { const uint8_t digest_ref[] = { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92, 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67, @@ -479,17 +454,17 @@ static void test_atcac_sw_sha2_256_nist_simple(const char* filename) #endif } -void test_atcac_sw_sha2_256_nist_short(void) +TEST(atcac_sha, sha256_nist_short) { test_atcac_sw_sha2_256_nist_simple("sha-byte-test-vectors/SHA256ShortMsg.rsp"); } -void test_atcac_sw_sha2_256_nist_long(void) +TEST(atcac_sha, sha256_nist_long) { test_atcac_sw_sha2_256_nist_simple("sha-byte-test-vectors/SHA256LongMsg.rsp"); } -void test_atcac_sw_sha2_256_nist_monte(void) +TEST(atcac_sha, sha256_nist_monte) { #if !defined(_WIN32) && !defined(__linux__) TEST_IGNORE_MESSAGE("Test is not available for this platform."); @@ -529,179 +504,7 @@ void test_atcac_sw_sha2_256_nist_monte(void) #endif } -#if defined(ATCA_OPENSSL) || defined(ATCA_MBEDTLS) || defined(ATCA_WOLFSSL) - -void test_atcac_aes128_gcm(void) -{ - ATCA_STATUS status; - uint8_t test_index; - uint8_t ciphertext[GCM_TEST_VECTORS_DATA_SIZE_MAX]; - size_t ct_size; - uint8_t plaintext[GCM_TEST_VECTORS_DATA_SIZE_MAX]; - size_t pt_size; - uint8_t tag[AES_DATA_SIZE]; - bool is_verified; - atcac_aes_gcm_ctx ctx; - - - for (test_index = 0; test_index < GCM_TEST_VECTORS_COUNT; test_index++) - { - ////////////////////////////////////// Encryption ///////////////////////////////////////// - status = atcac_aes_gcm_encrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - -#ifdef ATCA_WOLFSSL - status = atcac_aes_gcm_encrypt(&ctx, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size, ciphertext, - tag, sizeof(tag), gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -#else - //Add aad to gcm - status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Encrypt data - ct_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; - status = atcac_aes_gcm_encrypt_update(&ctx, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size, ciphertext, &ct_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -#endif - //Verify ciphertext with expected data - if (gcm_test_cases[test_index].text_size > 0) - { - TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].ciphertext, ciphertext, gcm_test_cases[test_index].text_size); - } - -#ifndef ATCA_WOLFSSL - //Calculate authentication tag - status = atcac_aes_gcm_encrypt_finish(&ctx, tag, sizeof(tag)); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -#endif - - //Verify calculated tag - TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].tag, tag, sizeof(tag)); - -#ifndef ATCA_WOLFSSL - // Repeat, but skip unused calls - if (gcm_test_cases[test_index].aad_size == 0 || gcm_test_cases[test_index].text_size == 0) - { - //Initialize gcm ctx with IV - status = atcac_aes_gcm_encrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Add aad to gcm - status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Encrypt data - if (gcm_test_cases[test_index].text_size > 0) - { - ct_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; - status = atcac_aes_gcm_encrypt_update(&ctx, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size, ciphertext, &ct_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].ciphertext, ciphertext, gcm_test_cases[test_index].text_size); - } - - //Calculate authentication tag - status = atcac_aes_gcm_encrypt_finish(&ctx, tag, sizeof(tag)); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Verify calculated tag - TEST_ASSERT_EQUAL_MEMORY(gcm_test_cases[test_index].tag, tag, sizeof(tag)); - } -#endif - - - ////////////////////////////////////// Decryption ///////////////////////////////////////// - //Initialize gcm ctx with IV - status = atcac_aes_gcm_decrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - -#ifdef ATCA_WOLFSSL - status = atcac_aes_gcm_decrypt(&ctx, gcm_test_cases[test_index].ciphertext, gcm_test_cases[test_index].text_size, plaintext, tag, sizeof(tag), - gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size, &is_verified); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -#else - - //Add aad to gcm - status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Add ciphertext to gcm - pt_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; - status = atcac_aes_gcm_decrypt_update(&ctx, gcm_test_cases[test_index].ciphertext, gcm_test_cases[test_index].text_size, plaintext, &pt_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -#endif - //Verify plaintext with expected data - if (gcm_test_cases[test_index].text_size > 0) - { - TEST_ASSERT_EQUAL_MEMORY(plaintext, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size); - } - -#ifndef ATCA_WOLFSSL - status = atcac_aes_gcm_decrypt_finish(&ctx, gcm_test_cases[test_index].tag, sizeof(tag), &is_verified); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -#endif - TEST_ASSERT(is_verified); - -#ifndef ATCA_WOLFSSL - // Repeat, but skip unused calls - if (gcm_test_cases[test_index].aad_size == 0 || gcm_test_cases[test_index].text_size == 0) - { - //Initialize gcm ctx with IV - status = atcac_aes_gcm_decrypt_start(&ctx, gcm_test_cases[test_index].key, 16, gcm_test_cases[test_index].iv, gcm_test_cases[test_index].iv_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Add aad to gcm - status = atcac_aes_gcm_aad_update(&ctx, gcm_test_cases[test_index].aad, gcm_test_cases[test_index].aad_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Add ciphertext to gcm - if (gcm_test_cases[test_index].text_size > 0) - { - pt_size = GCM_TEST_VECTORS_DATA_SIZE_MAX; - status = atcac_aes_gcm_decrypt_update(&ctx, gcm_test_cases[test_index].ciphertext, gcm_test_cases[test_index].text_size, plaintext, &pt_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - //Verify plaintext with expected data - TEST_ASSERT_EQUAL_MEMORY(plaintext, gcm_test_cases[test_index].plaintext, gcm_test_cases[test_index].text_size); - } - - status = atcac_aes_gcm_decrypt_finish(&ctx, gcm_test_cases[test_index].tag, sizeof(tag), &is_verified); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT(is_verified); - } -#endif - } -} - -void test_atcac_aes128_cmac(void) -{ - ATCA_STATUS status = 0; - atcac_aes_cmac_ctx ctx; - uint8_t key_block = 0; - size_t msg_index = 0; - uint8_t cmac[AES_DATA_SIZE]; - size_t cmac_size; - - for (key_block = 0; key_block < 4; key_block++) - { - for (msg_index = 0; msg_index < sizeof(g_cmac_msg_sizes) / sizeof(g_cmac_msg_sizes[0]); msg_index++) - { - status = atcac_aes_cmac_init(&ctx, g_aes_keys[key_block], 16); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - status = atcac_aes_cmac_update(&ctx, g_plaintext, g_cmac_msg_sizes[msg_index]); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - cmac_size = sizeof(cmac); - status = atcac_aes_cmac_finish(&ctx, cmac, &cmac_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_MEMORY(g_cmacs[key_block][msg_index], cmac, sizeof(cmac)); - } - } -} -#endif - -void test_atcac_sha256_hmac(void) +TEST(atcac_sha, sha256_hmac) { ATCA_STATUS status = ATCA_GEN_FAIL; uint8_t hmac[ATCA_SHA256_DIGEST_SIZE]; @@ -745,7 +548,7 @@ void test_atcac_sha256_hmac(void) TEST_ASSERT_EQUAL_MEMORY(hmac_ref, hmac, ATCA_SHA256_DIGEST_SIZE); } -void test_atcac_sha256_hmac_nist(void) +TEST(atcac_sha, sha256_hmac_nist) { #if !defined(_WIN32) && !defined(__linux__) TEST_IGNORE_MESSAGE("Test is not available for this platform."); @@ -803,162 +606,29 @@ void test_atcac_sha256_hmac_nist(void) #endif } +#endif /* TEST_ATCAC_SHA256_EN */ - -#if defined(ATCA_MBEDTLS) || defined(ATCA_OPENSSL) || defined(ATCA_WOLFSSL) -void test_atcac_verify_nist(void) -{ - uint8_t pubkey[64]; - uint8_t signature[64]; - uint8_t digest[32]; - atcac_pk_ctx pkey_ctx; - ATCA_STATUS status; - size_t i; - - /* Test verification using [P-256,SHA-256] vectors */ - for (i = 0; i < ecdsa_p256_test_vectors_count; i++) - { - /* Copy pubkey */ - memcpy(pubkey, ecdsa_p256_test_vectors[i].Qx, 32); - memcpy(&pubkey[32], ecdsa_p256_test_vectors[i].Qy, 32); - - /* Copy the signature */ - memcpy(signature, ecdsa_p256_test_vectors[i].R, 32); - memcpy(&signature[32], ecdsa_p256_test_vectors[i].S, 32); - - /* Hash the message */ - status = atcac_sw_sha2_256(ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - /* Initialize the key using the provided X,Y cordinantes */ - status = atcac_pk_init(&pkey_ctx, pubkey, sizeof(pubkey), 0, true); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - /* Perform the verification */ - status = atcac_pk_verify(&pkey_ctx, digest, sizeof(digest), signature, sizeof(signature)); - - /* Make sure to free the key before testing the result of the verify */ - atcac_pk_free(&pkey_ctx); - - /* Check verification result against the expected success/failure */ - if (ecdsa_p256_test_vectors[i].Result) - { - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - } - else - { - TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); - } - } -} - -static uint8_t private_key_pem[] = - "-----BEGIN EC PRIVATE KEY-----\n" - "MHcCAQEEICFZhAyzqkUgyheo51bhg3mcp+qwfl+koE+Mhs/sRyzBoAoGCCqGSM49\n" - "AwEHoUQDQgAExAE2yqujppBzD0hIpdqdXmMgtlXT90QqllaQYWEVBjdf+LmY5DCf\n" - "Mx8PXEVxhbDmgo6HHbz0S4VaZjShBLMaPw==\n" - "-----END EC PRIVATE KEY-----\n"; - -static uint8_t public_key_pem[] = - "-----BEGIN PUBLIC KEY-----\n" - "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExAE2yqujppBzD0hIpdqdXmMgtlXT\n" - "90QqllaQYWEVBjdf+LmY5DCfMx8PXEVxhbDmgo6HHbz0S4VaZjShBLMaPw==\n" - "-----END PUBLIC KEY-----\n"; - -static uint8_t public_key_bytes[64] = { - 0xc4, 0x01, 0x36, 0xca, 0xab, 0xa3, 0xa6, 0x90, 0x73, 0x0f, 0x48, 0x48, 0xa5, 0xda, 0x9d, 0x5e, - 0x63, 0x20, 0xb6, 0x55, 0xd3, 0xf7, 0x44, 0x2a, 0x96, 0x56, 0x90, 0x61, 0x61, 0x15, 0x06, 0x37, - 0x5f, 0xf8, 0xb9, 0x98, 0xe4, 0x30, 0x9f, 0x33, 0x1f, 0x0f, 0x5c, 0x45, 0x71, 0x85, 0xb0, 0xe6, - 0x82, 0x8e, 0x87, 0x1d, 0xbc, 0xf4, 0x4b, 0x85, 0x5a, 0x66, 0x34, 0xa1, 0x04, 0xb3, 0x1a, 0x3f -}; - -void test_atcac_public(void) -{ - atcac_pk_ctx priv_ctx; - uint8_t public_key[64]; - size_t public_key_size = 64; - ATCA_STATUS status; - - /* Test initialization of a private key with a pem encoded key (without password) */ - status = atcac_pk_init_pem(&priv_ctx, private_key_pem, sizeof(private_key_pem), false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - status = atcac_pk_public(&priv_ctx, public_key, &public_key_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - TEST_ASSERT_EQUAL_MEMORY(public_key_bytes, public_key, 64); - - status = atcac_pk_free(&priv_ctx); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); -} - -void test_atcac_sign(void) -{ - atcac_pk_ctx sign_ctx; - atcac_pk_ctx verify_ctx; - uint8_t digest[32] = { 0x1A, 0x3A, 0xA5, 0x45, 0x04, 0x94, 0x53, 0xAF, - 0xDF, 0x17, 0xE9, 0x89, 0xA4, 0x1F, 0xA0, 0x97, - 0x94, 0xA5, 0x1B, 0xD5, 0xDB, 0x91, 0x36, 0x37, - 0x67, 0x55, 0x0C, 0x0F, 0x0A, 0xF3, 0x27, 0xD4 }; - uint8_t signature[128]; - size_t sig_size = sizeof(signature); - ATCA_STATUS status; - - memset(signature, 0, sig_size); - - /* Test initialization of a private key with a pem encoded key (without password) */ - status = atcac_pk_init_pem(&sign_ctx, private_key_pem, sizeof(private_key_pem), false); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - /* Test signing with the private key */ - status = atcac_pk_sign(&sign_ctx, digest, sizeof(digest), signature, &sig_size); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - /* Test initialization of a public key with a pem encoded key */ - status = atcac_pk_init_pem(&verify_ctx, public_key_pem, sizeof(public_key_pem), true); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - /* Test verification of the siguature */ - status = atcac_pk_verify(&verify_ctx, digest, sizeof(digest), &signature[sig_size - 64], 64); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - - signature[10] ^= signature[10]; - - /* Test failure to validate a corrupted signature */ - status = atcac_pk_verify(&verify_ctx, digest, sizeof(digest), &signature[sig_size - 64], 64); - TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); -} - -void test_atcac_derive_nist(void) +// *INDENT-OFF* - Preserve formatting +t_test_case_info atcac_sha_test_info[] = { - ATCA_STATUS status; - atcac_pk_ctx pri_ctx; - atcac_pk_ctx pub_ctx; - uint8_t result[32]; - size_t result_size; - size_t i; - - /* Test verification using [P-256] vectors */ - for (i = 0; i < ecdh_p256_test_vectors_count; i++) - { - uint8_t pubkey[64]; - - memcpy(pubkey, ecdh_p256_test_vectors[i].QCAVSx, 32); - memcpy(&pubkey[32], ecdh_p256_test_vectors[i].QCAVSy, 32); - - (void)atcac_pk_init(&pub_ctx, pubkey, sizeof(pubkey), 0, true); - (void)atcac_pk_init(&pri_ctx, (uint8_t*)ecdh_p256_test_vectors[i].dIUT, 32, 0, false); - - result_size = sizeof(result); - status = atcac_pk_derive(&pri_ctx, &pub_ctx, result, &result_size); - - (void)atcac_pk_free(&pri_ctx); - (void)atcac_pk_free(&pub_ctx); - - /* Check Test Results */ - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL_MEMORY(ecdh_p256_test_vectors[i].ZIUT, result, 32); - } -} - +#if TEST_ATCAC_SHA1_EN + { REGISTER_TEST_CASE(atcac_sha, sha1_nist1), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha1_nist2), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha1_nist3), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha1_nist_short), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha1_nist_long), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha1_nist_monte), DEVICE_MASK_NONE }, +#endif +#if TEST_ATCAC_SHA256_EN + { REGISTER_TEST_CASE(atcac_sha, sha256_nist1), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha256_nist2), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha256_nist3), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha256_nist_short), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha256_nist_long), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha256_nist_monte), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha256_hmac), DEVICE_MASK_NONE }, + { REGISTER_TEST_CASE(atcac_sha, sha256_hmac_nist), DEVICE_MASK_NONE }, #endif + { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ +}; +// *INDENT-ON* diff --git a/test/atca_crypto_sw_tests.h b/test/atca_crypto_sw_tests.h deleted file mode 100644 index f544257b7..000000000 --- a/test/atca_crypto_sw_tests.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * \file - * \brief Unity tests for the CryptoAuthLib software crypto API. - * - * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. - * - * \page License - * - * Subject to your compliance with these terms, you may use Microchip software - * and any derivatives exclusively with Microchip products. It is your - * responsibility to comply with third party license terms applicable to your - * use of third party software (including open source software) that may - * accompany Microchip software. - * - * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER - * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED - * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A - * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, - * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE - * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF - * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE - * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL - * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED - * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR - * THIS SOFTWARE. - */ - -#ifndef ATCA_CRYPTO_TESTS_H_ -#define ATCA_CRYPTO_TESTS_H_ - -#include "third_party/unity/unity.h" - -int atca_crypto_sw_tests(int argc, char* argv[]); - -void test_atcac_sw_sha1_nist1(void); -void test_atcac_sw_sha1_nist2(void); -void test_atcac_sw_sha1_nist3(void); -void test_atcac_sw_sha1_nist_short(void); -void test_atcac_sw_sha1_nist_long(void); -void test_atcac_sw_sha1_nist_monte(void); -void test_atcac_sw_sha2_256_nist1(void); -void test_atcac_sw_sha2_256_nist2(void); -void test_atcac_sw_sha2_256_nist3(void); -void test_atcac_sw_sha2_256_nist_short(void); -void test_atcac_sw_sha2_256_nist_long(void); -void test_atcac_sw_sha2_256_nist_monte(void); - -void test_atcac_aes128_gcm(void); -void test_atcac_aes128_cmac(void); -void test_atcac_sha256_hmac(void); -void test_atcac_sha256_hmac_nist(void); - -void test_atcac_verify_nist(void); -void test_atcac_public(void); -void test_atcac_sign(void); -void test_atcac_derive_nist(void); - - -#endif diff --git a/test/atca_test.c b/test/atca_test.c index b43a1709e..e7d3b3a9e 100644 --- a/test/atca_test.c +++ b/test/atca_test.c @@ -30,6 +30,10 @@ #include "app/tng/tng_atca.h" #define ATCA_TEST_TNG #endif +#if defined(ATCA_WPC_SUPPORT) +#include "app/wpc/wpc_apis.h" +#define ATCA_TEST_WPC +#endif #if ATCA_CA_SUPPORT #include "api_calib/test_calib.h" #endif @@ -37,14 +41,19 @@ #include "api_talib/test_talib.h" #endif -const char* ATCA_TEST_HELPER_FILE = "In helper: " __FILE__; +/* Access to test runner internal details */ +extern struct UNITY_STORAGE_T Unity; -const char* TEST_GROUP_atca_cmd_basic_test = "atca_cmd_basic_test"; +/* Track the last status code for the last command run (early abort) */ +ATCA_STATUS g_last_status; -bool g_atca_test_quiet_mode = false; +/* Terminate all testing immediately */ +bool g_test_abort; -#ifdef ATCA_SHA_SUPPORT +/* Answer yes to prompts in the next command run */ +bool g_atca_test_quiet_mode = false; +#ifdef ATCA_ATSHA204A_SUPPORT const uint8_t sha204_default_config[ATCA_SHA_CONFIG_SIZE] = { // block 0 // Not Written: First 16 bytes are not written @@ -104,40 +113,6 @@ const uint8_t g_plaintext[64] = { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17, 0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 }; -t_test_case_info* basic_tests[] = -{ - startup_basic_test_info, - info_basic_test_info, - aes_basic_test_info, - aes_cbc_basic_test_info, - aes_cmac_basic_test_info, - aes_ctr_basic_test_info, - aes_cbcmac_basic_test_info, - aes_gcm_basic_test_info, - aes_ccm_basic_test_info, - verify_basic_test_info, - derivekey_basic_test_info, - sha_basic_test_info, - hmac_basic_test_info, - sign_basic_test_info, - mac_basic_test_info, - ecdh_basic_test_info, - write_basic_test_info, - read_basic_test_info, - genkey_basic_test_info, - privwrite_basic_test_info, - lock_basic_test_info, - kdf_basic_test_info, - sboot_basic_test_info, - selftest_basic_test_info, - gendig_basic_test_info, - random_basic_test_info, - nonce_basic_test_info, - updateextra_basic_test_info, - counter_basic_test_info, - (t_test_case_info*)NULL, /* Array Termination element*/ -}; - t_test_case_info* otpzero_tests[] = { otpzero_basic_test_info, @@ -147,7 +122,6 @@ t_test_case_info* otpzero_tests[] = t_test_case_info* helper_tests[] = { helper_basic_test_info, - jwt_unit_test_info, (t_test_case_info*)NULL, /* Array Termination element*/ }; @@ -162,18 +136,47 @@ t_test_case_info* tng_tests[] = (t_test_case_info*)NULL, /* Array Termination element*/ }; - -#ifdef ATCA_MBEDTLS - -extern t_test_case_info test_mbedtls_ecdsa_info[]; - -t_test_case_info* crypto_integration_tests[] = +t_test_case_info* wpc_tests[] = { - test_mbedtls_ecdsa_info, +#ifdef ATCA_TEST_WPC + wpc_apis_unit_test_info, +#ifndef DO_NOT_TEST_CERT + wpccert_client_unit_test_info, +#endif +#endif (t_test_case_info*)NULL, /* Array Termination element*/ }; -#endif +/** \brief Runs a test suite or individual test - the function is expected to call + * unity test operations +*/ +int run_test(int argc, char* argv[], void (*fptest)(void)) +{ + int ret; + if (CMD_PROCESSOR_MAX_ARGS > argc) + { + argv[argc++] = "-v"; + } + + /* Reset the last status result */ + g_last_status = ATCA_SUCCESS; + + /* Reset the abort */ + g_test_abort = false; + + /* Launch the unity test framework */ + ret = UnityMain(argc, (const char**)argv, fptest); + + if(!ret && !Unity.NumberOfTests) + { + /* The assumption is that tests were supposed to have been run so if + non were executed the assumption is there is a configuration problem. + If a test suite has no tests for a given configuration don't run it */ + printf("No tests were run for this configuration\n"); + ret = -1; + } + return ret; +} void RunAllTests(t_test_case_info** tests_list) { @@ -181,7 +184,7 @@ void RunAllTests(t_test_case_info** tests_list) uint32_t support_device_mask; /*Loop through all the commands test info*/ - while (*tests_list != NULL) + while ((*tests_list != NULL) && !atca_test_unresponsive()) { /*Get current command test info*/ sp_current_test = *tests_list; @@ -189,16 +192,23 @@ void RunAllTests(t_test_case_info** tests_list) /*Loop through till last test in the test info*/ while (sp_current_test->fp_test != NULL) { - /*Get current device mask*/ - support_device_mask = DEVICE_MASK(gCfg->devtype); + /*Get current device mask */ + support_device_mask = (gCfg->devtype < ATCA_DEV_UNKNOWN) ? DEVICE_MASK(gCfg->devtype) : DEVICE_MASK_NONE; /*check if current test mask contains current device mask*/ - if ((sp_current_test->support_device_mask & support_device_mask) == support_device_mask) + if (!sp_current_test->support_device_mask || + ((sp_current_test->support_device_mask & support_device_mask) == support_device_mask)) { /*Execute current test case*/ sp_current_test->fp_test(); } + if(atca_test_unresponsive()) + { + /* Early return on communication failures */ + break; + } + /*Move to next test*/ sp_current_test++; } @@ -208,11 +218,6 @@ void RunAllTests(t_test_case_info** tests_list) } } -void RunAllBasicTests(void) -{ - RunAllTests(basic_tests); -}; - void RunBasicOtpZero(void) { RunAllTests(otpzero_tests); @@ -228,24 +233,9 @@ void RunTNGTests(void) RunAllTests(tng_tests); } -#if defined(ATCA_MBEDTLS) -void RunCryptoIntegrationTests(void) +void RunWPCTests(void) { - RunAllTests(crypto_integration_tests); -} -#endif - -extern t_test_case_info test_crypto_pbkdf2_info[]; - -t_test_case_info* pbkdf2_tests[] = -{ - test_crypto_pbkdf2_info, - (t_test_case_info*)NULL, /* Array Termination element*/ -}; - -void RunPbkdf2Tests(void) -{ - RunAllTests(pbkdf2_tests); + RunAllTests(wpc_tests); } #ifdef ATCA_NO_HEAP @@ -255,6 +245,15 @@ ATCA_DLL struct atca_command g_atcab_command; ATCA_DLL struct atca_iface g_atcab_iface; #endif +bool atca_test_unresponsive(void) +{ + return (g_test_abort || (ATCA_COMM_FAIL == g_last_status) || (ATCA_WAKE_FAILED == g_last_status)); +} + +bool atca_test_already_exiting(void) +{ + return (Unity.CurrentTestFailed || Unity.CurrentTestIgnored); +} void atca_test_assert_config_is_unlocked(UNITY_LINE_TYPE from_line) { @@ -389,11 +388,14 @@ ATCA_STATUS atca_test_config_get_id(uint8_t test_type, uint16_t* handle) case ATECC508A: /* fallthrough */ case ATECC608: - /* fallthrough */ - case ECC204: status = calib_config_get_slot_by_test(test_type, handle); break; #endif +#ifdef ATCA_ECC204_SUPPORT + case ECC204: + status = calib_config_get_ecc204_slot_by_test(test_type, handle); + break; +#endif #if ATCA_TA_SUPPORT case TA100: status = talib_config_get_handle_by_test(test_type, handle); @@ -412,27 +414,16 @@ ATCA_STATUS atca_test_config_get_id(uint8_t test_type, uint16_t* handle) return status; } -TEST_SETUP(atca_cmd_basic_test) -{ - UnityMalloc_StartTest(); - - ATCA_STATUS status = atcab_init(gCfg); - - TEST_ASSERT_EQUAL_INT_MESSAGE(ATCA_SUCCESS, status, ATCA_TEST_HELPER_FILE); -} - -TEST_TEAR_DOWN(atca_cmd_basic_test) +/* Helper function to execute genkey and retry if there are failures since there is + a chance that the genkey will fail to produce a valid keypair and a retry is nearly + always successful */ +ATCA_STATUS atca_test_genkey(uint16_t key_id, uint8_t *public_key) { + int attempts = 2; ATCA_STATUS status; - - status = atcab_wakeup(); - TEST_ASSERT_EQUAL_INT_MESSAGE(ATCA_SUCCESS, status, ATCA_TEST_HELPER_FILE); - - status = atcab_sleep(); - TEST_ASSERT_EQUAL_INT_MESSAGE(ATCA_SUCCESS, status, ATCA_TEST_HELPER_FILE); - - status = atcab_release(); - TEST_ASSERT_EQUAL_INT_MESSAGE(ATCA_SUCCESS, status, ATCA_TEST_HELPER_FILE); - - UnityMalloc_EndTest(); + do + { + status = atcab_genkey(key_id, public_key); + } while (status && --attempts); + return status; } diff --git a/test/atca_test.h b/test/atca_test.h index fbf9be02c..3ce56df37 100644 --- a/test/atca_test.h +++ b/test/atca_test.h @@ -32,14 +32,17 @@ #include "third_party/unity/unity_fixture.h" #include "cryptoauthlib.h" -#define TEST_ASSERT_SUCCESS(x) TEST_ASSERT_EQUAL(ATCA_SUCCESS, x) +extern bool g_test_abort; +extern ATCA_STATUS g_last_status; +#define TEST_ASSERT_SUCCESS(x) TEST_ASSERT_EQUAL(ATCA_SUCCESS, g_last_status=x) +#define TEST_ASSERT_SUCCESS_MSG(x,m) TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, g_last_status=x, m) extern ATCAIfaceCfg *gCfg; extern const uint8_t g_slot4_key[]; #define AES_CONFIG_ENABLE_BIT_MASK (uint8_t)0x01 -#define CMD_PROCESSOR_MAX_ARGS 10 +#define CMD_PROCESSOR_MAX_ARGS 16 typedef void (*fp_test_case)(void); @@ -51,18 +54,34 @@ typedef struct typedef int (*fp_menu_handler)(int argc, char* argv[]); +typedef struct +{ + const char* menu_cmd; + fp_menu_handler fp_handler; +} t_menu_info_simple; +#define MENU_ITEM_SIMPLE(c,f) {c, f} + +#ifdef ATCA_TEST_SIMPLE_MENU +typedef t_menu_info_simple t_menu_info +#define MENU_ITEM MENU_ITEM_SIMPLE +#else typedef struct { const char* menu_cmd; const char* menu_cmd_description; fp_menu_handler fp_handler; } t_menu_info; +#define MENU_ITEM(c,d, f) {c, d, f} +#endif #define DEVICE_MASK(device) ((uint8_t)1 << device) #define REGISTER_TEST_CASE(group, name) TEST_ ## group ## _ ## name ## _run -#define DEVICE_MASK_ECC (DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608)) - +#define DEVICE_MASK_SHA (DEVICE_MASK(ATSHA204A) | DEVICE_MASK(ATSHA206A)) +#define DEVICE_MASK_ATECC (DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608)) +#define DEVICE_MASK_ECC (DEVICE_MASK(ATECC108A) | DEVICE_MASK(ECC204) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608)) +#define DEVICE_MASK_NONE (0) +#define DEVICE_MASK_ANY UINT32_MAX #if !defined(ATCA_ECC_SUPPORT) && !defined(DO_NOT_TEST_CERT) #define DO_NOT_TEST_CERT @@ -76,59 +95,26 @@ typedef struct #include "api_talib/test_talib.h" #endif +#ifdef ATCA_HAL_KIT_SUPPORT +extern ATCA_STATUS hal_kit_bridge_connect(ATCAIfaceCfg * cfg); +#endif + extern bool g_atca_test_quiet_mode; +/* Cryptoauthlib Test Api */ void RunAllTests(t_test_case_info** tests_list); int run_test(int argc, char* argv[], void (*fptest)(void)); void run_all_talib_tests(void); -extern const char* TEST_GROUP_atca_cmd_basic_test; -void TEST_atca_cmd_basic_test_SETUP(void); -void TEST_atca_cmd_basic_test_TEAR_DOWN(void); - -extern const char* TEST_GROUP_atca_cmd_unit_test; -void TEST_atca_cmd_unit_test_SETUP(void); -void TEST_atca_cmd_unit_test_TEAR_DOWN(void); - - -extern t_test_case_info startup_basic_test_info[]; -extern t_test_case_info info_basic_test_info[]; -extern t_test_case_info aes_basic_test_info[]; -extern t_test_case_info aes_cbc_basic_test_info[]; -extern t_test_case_info aes_cmac_basic_test_info[]; -extern t_test_case_info aes_ctr_basic_test_info[]; -extern t_test_case_info aes_cbcmac_basic_test_info[]; -extern t_test_case_info aes_gcm_basic_test_info[]; -extern t_test_case_info aes_ccm_basic_test_info[]; -extern t_test_case_info verify_basic_test_info[]; -extern t_test_case_info derivekey_basic_test_info[]; -extern t_test_case_info sha_basic_test_info[]; -extern t_test_case_info hmac_basic_test_info[]; -extern t_test_case_info sign_basic_test_info[]; -extern t_test_case_info mac_basic_test_info[]; -extern t_test_case_info ecdh_basic_test_info[]; -extern t_test_case_info write_basic_test_info[]; -extern t_test_case_info read_basic_test_info[]; -extern t_test_case_info genkey_basic_test_info[]; -extern t_test_case_info privwrite_basic_test_info[]; -extern t_test_case_info lock_basic_test_info[]; -extern t_test_case_info kdf_basic_test_info[]; -extern t_test_case_info selftest_basic_test_info[]; -extern t_test_case_info gendig_basic_test_info[]; -extern t_test_case_info random_basic_test_info[]; -extern t_test_case_info nonce_basic_test_info[]; -extern t_test_case_info pause_basic_test_info[]; -extern t_test_case_info updateextra_basic_test_info[]; -extern t_test_case_info counter_basic_test_info[]; -extern t_test_case_info sboot_basic_test_info[]; - extern t_test_case_info helper_basic_test_info[]; extern t_test_case_info otpzero_basic_test_info[]; -extern t_test_case_info jwt_unit_test_info[]; extern t_test_case_info tng_atca_unit_test_info[]; extern t_test_case_info tng_atcacert_client_unit_test_info[]; +extern t_test_case_info wpccert_client_unit_test_info[]; +extern t_test_case_info wpc_apis_unit_test_info[]; + extern t_test_case_info test_crypto_pbkdf2_info[]; void test_assert_interface_init(void); @@ -136,13 +122,23 @@ void test_assert_interface_deinit(void); #if ATCA_CA_SUPPORT extern uint8_t test_ecc608_configdata[ATCA_ECC_CONFIG_SIZE]; +#endif +#if defined(ATCA_ATECC108A_SUPPORT) || defined(ATCA_ATECC508A_SUPPORT) extern const uint8_t test_ecc_configdata[ATCA_ECC_CONFIG_SIZE]; +#endif +#ifdef ATCA_ATSHA204A_SUPPORT extern const uint8_t sha204_default_config[ATCA_SHA_CONFIG_SIZE]; #endif +#ifdef ATCA_ECC204_SUPPORT +extern const uint8_t test_ecc204_configdata[ATCA_ECC204_CONFIG_SIZE]; +#endif #if ATCA_TA_SUPPORT extern const uint8_t test_ta100_configdata[TA_CONFIG_SIZE]; #endif +bool atca_test_already_exiting(void); +bool atca_test_unresponsive(void); + void atca_test_assert_config_is_unlocked(UNITY_LINE_TYPE from_line); void atca_test_assert_config_is_locked(UNITY_LINE_TYPE from_line); void atca_test_assert_data_is_unlocked(UNITY_LINE_TYPE from_line); @@ -195,28 +191,18 @@ ATCA_STATUS atca_test_config_get_id(uint8_t test_type, uint16_t* handle); int run_tests(int test); void RunAllHelperTests(void); void RunBasicOtpZero(void); -void RunAllBasicTests(void); -void RunAllFeatureTests(void); void RunTNGTests(void); -void RunCryptoIntegrationTests(void); +void RunWPCTests(void); void RunPbkdf2Tests(void); /* Setup & Configuration */ void atca_test_config_set_ifacecfg(ATCAIfaceCfg * ifacecfg); +ATCA_STATUS atca_test_genkey(uint16_t key_id, uint8_t *public_key); /* Commands */ int process_options(int argc, char* argv[]); +int select_device(int argc, char* argv[]); -int select_204(int argc, char* argv[]); -int select_206(int argc, char* argv[]); -int select_108(int argc, char* argv[]); -int select_508(int argc, char* argv[]); -int select_608(int argc, char* argv[]); -int select_ta100(int argc, char* argv[]); -int select_ecc204(int argc, char* argv[]); - -int certdata_unit_tests(int argc, char* argv[]); -int certio_unit_tests(int argc, char* argv[]); ATCA_STATUS is_config_locked(bool* isLocked); ATCA_STATUS is_data_locked(bool* isLocked); int lock_status(int argc, char* argv[]); @@ -232,8 +218,6 @@ int info(int argc, char* argv[]); int read_sernum(int argc, char* argv[]); int discover(int argc, char* argv[]); -int run_basic_tests(int argc, char* argv[]); -int run_unit_tests(int argc, char* argv[]); int run_otpzero_tests(int argc, char* argv[]); int run_helper_tests(int argc, char* argv[]); int run_all_tests(int argc, char* argv[]); @@ -244,8 +228,7 @@ int set_clock_divider_m0(int argc, char* argv[]); int set_clock_divider_m1(int argc, char* argv[]); int set_clock_divider_m2(int argc, char* argv[]); int run_tng_tests(int argc, char* argv[]); -int run_crypto_integration_tests(int argc, char* argv[]); -int run_pbkdf2_tests(int argc, char* argv[]); +int run_wpc_tests(int argc, char* argv[]); ATCA_STATUS check_clock_divider(int argc, char* argv[]); diff --git a/test/atca_test_config.c b/test/atca_test_config.c index 6950e6f51..1bf58d2bf 100644 --- a/test/atca_test_config.c +++ b/test/atca_test_config.c @@ -30,11 +30,11 @@ #ifdef ATCA_TEST_MULTIPLE_INSTANCES #include "atca_devcfg_list.h" -void select_dev_cfg_data(); #endif #ifdef ATCA_HAL_CUSTOM extern int select_204_custom(int argc, char* argv[]); +extern int select_206_custom(int argc, char* argv[]); extern int select_108_custom(int argc, char* argv[]); extern int select_508_custom(int argc, char* argv[]); extern int select_608_custom(int argc, char* argv[]); @@ -42,6 +42,19 @@ extern int select_ta100_custom(int argc, char* argv[]); extern int select_ecc204_custom(int argc, char* argv[]); #endif +#ifdef ATCA_HAL_KIT_BRIDGE +/** The bridging protocol doesn't control the "physical" interface so to start + the connection inside the test application it needs to be linked to + something that exposes the following function */ +extern ATCA_STATUS hal_kit_bridge_connect(ATCAIfaceCfg *, int, char **); +#endif + +//#if defined(__linux__) && (defined(ATCA_HAL_SWI_UART) || defined(ATCA_HAL_KIT_UART)) +#ifdef __linux__ +/** In order to access the uart on linux the full device path needs to be known */ +static char opt_device_name[20]; +#endif + /** gCfg must point to one of the cfg_ structures for any unit test to work. this allows the command console to switch device types at runtime. */ ATCAIfaceCfg g_iface_config = { @@ -78,6 +91,17 @@ ATCAIfaceCfg g_iface_config = { ATCAIfaceCfg* gCfg = &g_iface_config; +static void print_args(const char * f, int argc, char* argv[]) +{ + int i; + printf("Called from %s with %d args: ", f, argc); + for(i=0; idevtype = device_type; - if (interative) + int ret; + switch(gCfg->devtype) { - printf("Device Selected.\r\n"); +#ifdef ATCA_ATSHA204A_SUPPORT + case ATSHA204A: + ret = select_204_custom(argc, argv); + break; +#endif +#ifdef ATCA_ATECC108A_SUPPORT + case ATECC108A: + ret = select_108_custom(argc, argv); + break; +#endif +#ifdef ATCA_ATECC508A_SUPPORT + case ATECC508A: + ret = select_508_custom(argc, argv); + break; +#endif +#ifdef ATCA_ATECC608_SUPPORT + case ATECC608: + ret = select_608_custom(argc, argv); + break; +#endif +#ifdef ATCA_ATSHA206A_SUPPORT + case ATSHA206A: + ret = select_204_custom(argc, argv); + break; +#endif +#ifdef ATCA_ECC204_SUPPORT + case ECC204: + ret = select_ecc204_custom(argc, argv); + break; +#endif +#ifdef ATCA_ECC204_SUPPORT + case TA100: + ret = select_ta100_custom(argc, argv); + break; +#endif + default: + ret = -1; + break; } - return 0; + return ret; } - -int select_204(int argc, char* argv[]) -{ -#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATSHA204A_SUPPORT) - return select_204_custom(argc, argv); -#else - ((void)argc); - return select_device(ATSHA204A, NULL != argv); #endif -} -int select_206(int argc, char* argv[]) +static int select_device_internal(int argc, char* argv[], bool interactive) { -#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATSHA206A_SUPPORT) - return select_206_custom(argc, argv); -#else - ((void)argc); - return select_device(ATSHA206A, NULL != argv); -#endif -} + int ret = -1; -int select_108(int argc, char* argv[]) -{ -#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATECC108A_SUPPORT) - return select_108_custom(argc, argv); -#else - ((void)argc); - return select_device(ATECC108A, NULL != argv); -#endif -} + if (argc) + { + if (ATCA_DEV_UNKNOWN != (gCfg->devtype = iface_get_device_type_by_name(argv[0]))) + { + ret = 0; + } + } -int select_508(int argc, char* argv[]) -{ -#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATECC508A_SUPPORT) - return select_508_custom(argc, argv); -#else - ((void)argc); - return select_device(ATECC508A, NULL != argv); +#ifdef ATCA_HAL_CUSTOM + if (!ret) + { + ret = select_custom(argc, argv); + } #endif -} -int select_608(int argc, char* argv[]) -{ -#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ATECC608_SUPPORT) - return select_608_custom(argc, argv); -#else - ((void)argc); - return select_device(ATECC608, NULL != argv); -#endif + if (!ret && interactive) + { + printf("Device Selected.\n"); + } + + return ret; } -int select_ta100(int argc, char* argv[]) +/** \brief Select a device by it's name - expects one argument */ +int select_device(int argc, char* argv[]) { -#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_TA100_SUPPORT) - return select_ta100_custom(argc, argv); -#else - ((void)argc); - return select_device(TA100, NULL != argv); -#endif + return select_device_internal(argc, argv, true); } -int select_ecc204(int argc, char* argv[]) +/** \brief Process an individual command option + * \return Number of arguments parsed from the list or an error + */ +static int process_option( + const t_menu_info_simple * list, /**< [in] List of options */ + int argc, /**< [in] Number of arguments in the arg list */ + char* argv[] /**< [in] Argument list */ +) { -#if defined(ATCA_HAL_CUSTOM) && defined(ATCA_ECC204_SUPPORT) - return select_ecc204_custom(argc, argv); -#else - ((void)argc); - return select_device(ECC204, NULL != argv); + int ret = -1; + const t_menu_info_simple * pList = list; + if (pList) + { + if (argc) + { + for (;pList->menu_cmd;pList++) + { + if (!strcmp(pList->menu_cmd, argv[0])) + { + if (pList->fp_handler) + { + if(0 < (ret = pList->fp_handler(argc-1, &argv[1]))) + { + ret = argc; + } + } + break; + } + } + } + else + { + ret = 0; + } + if (!ret) + { +#ifdef ATCA_PRINTF + /* */ + pList = list; + for (;pList->menu_cmd;pList++) + { + + } #endif + } + } + return ret; } /** \brief Sets the device the command or test suite will use @@ -175,227 +250,258 @@ int select_ecc204(int argc, char* argv[]) */ static int opt_device_type(int argc, char* argv[]) { - int ret = 0; + return select_device_internal(argc, argv, false); +} - if (argc >= 2) +/** \brief Map the name of an iterface to the enum */ +static ATCAKitType opt_get_kit_iface_type(const char * kit_iface_type_name) +{ + ATCAKitType ret = ATCA_KIT_AUTO_IFACE; + if (kit_iface_type_name) { - if (0 == strcmp("sha204", argv[1])) + if(lib_strcasestr(kit_iface_type_name, "i2c")) { - select_204(0, NULL); + ret = ATCA_KIT_I2C_IFACE; } - else if (0 == strcmp("sha206", argv[1])) + else if(lib_strcasestr(kit_iface_type_name, "spi")) { - select_206(0, NULL); + ret = ATCA_KIT_SPI_IFACE; } - else if (0 == strcmp("ecc108", argv[1])) + else if(lib_strcasestr(kit_iface_type_name, "swi")) { - select_108(0, NULL); + ret = ATCA_KIT_SWI_IFACE; } - else if (0 == strcmp("ecc508", argv[1])) - { - select_508(0, NULL); - } - else if (0 == strcmp("ecc608", argv[1])) - { - select_608(0, NULL); - } - else if (0 == strcmp("ta100", argv[1])) - { - select_ta100(0, NULL); - } - ret = 2; } return ret; } -#ifndef _WIN32 -static char opt_device_name[20]; +#ifdef ATCA_HAL_KIT_HID +/** \brief Configure the hid hal */ +static int opt_iface_hid(int argc, char* argv[]) +{ + ((void)argc); + + gCfg->iface_type = ATCA_HID_IFACE; + + ATCA_IFACECFG_VALUE(gCfg, atcahid.idx) = 0; + ATCA_IFACECFG_VALUE(gCfg, atcahid.vid) = 0x03EB; + ATCA_IFACECFG_VALUE(gCfg, atcahid.pid) = 0x2312; + ATCA_IFACECFG_VALUE(gCfg, atcahid.packetsize) = 64; + + ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_interface) = opt_get_kit_iface_type(argv[0]); + ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_identity) = 0; + + return 0; +} #endif -/** \brief Sets the interface the command or test suite will use - * - * \param[in] argc Number of arguments in the arg list - * \param[out] argv Argument list - * \return Number of arguments parsed - */ -static int opt_iface_type(int argc, char* argv[]) +#ifdef ATCA_HAL_I2C +/** \brief Configure the i2c hal */ +static int opt_iface_i2c(int argc, char* argv[]) { - int ret = 0; + int ret = -1; + gCfg->iface_type = ATCA_I2C_IFACE; - if (argc >= 2) + if (argc) { - ret = 2; + ATCA_IFACECFG_VALUE(gCfg, atcai2c.bus) = (uint8_t)strtol(argv[0], NULL, 10); + ret = 0; + } - if (0 == strcmp("hid", argv[1])) + if (1 < argc) + { +#ifdef __linux__ + ATCA_IFACECFG_VALUE(gCfg, atcai2c.baud) = 100000; +#else + ATCA_IFACECFG_VALUE(gCfg, atcai2c.baud) = (uint32_t)strtol(argv[1], NULL, 10); +#endif + } + + return ret; +} +#endif + +#if defined(ATCA_HAL_SWI_UART) || defined(ATCA_HAL_SWI_GPIO) || defined(ATCA_HAL_SWI_BB) +/** \brief Configure the swi hal */ +static int opt_iface_swi(int argc, char* argv[]) +{ + int ret = -1; + + gCfg->iface_type = ATCA_SWI_IFACE; + + if (argc) + { +#ifdef __linux__ + size_t len = strlen(argv[0]); + if (len < sizeof(opt_device_name) - 1) { - gCfg->iface_type = ATCA_HID_IFACE; - gCfg->atcahid.dev_identity = 0; - gCfg->atcahid.idx = 0; - gCfg->atcahid.vid = 0x03EB; - gCfg->atcahid.pid = 0x2312; - gCfg->atcahid.packetsize = 64; - - if (argc >= 3 && argv[2][0] != '-') - { - ret = 3; - if (0 == strcmp("i2c", argv[2])) - { - gCfg->atcahid.dev_interface = ATCA_KIT_I2C_IFACE; - if (argc >= 4 && argv[3][0] != '-') - { - uint32_t val = strtol(argv[3], NULL, 16); - gCfg->atcahid.dev_identity = (uint8_t)val; - } - } - else if (0 == strcmp("swi", argv[2])) - { - gCfg->atcahid.dev_interface = ATCA_KIT_SWI_IFACE; - } - else if (0 == strcmp("spi", argv[2])) - { - gCfg->atcahid.dev_interface = ATCA_KIT_SPI_IFACE; - } - } - else - { - gCfg->atcahid.dev_interface = ATCA_KIT_AUTO_IFACE; - } + memcpy(opt_device_name, argv[0], len); + opt_device_name[len] = '\0'; + gCfg->cfg_data = opt_device_name; } - else if (0 == strcmp("i2c", argv[1])) - { -#ifdef ATCA_HAL_I2C - gCfg->iface_type = ATCA_I2C_IFACE; +#else + ATCA_IFACECFG_VALUE(gCfg, atcaswi.bus) = (uint8_t)strtol(argv[0], NULL, 10); +#endif + ret = 0; + } - if (argc >= 3 && argv[2][0] != '-') - { - uint32_t val = strtol(argv[2], NULL, 16); - gCfg->atcai2c.bus = (uint8_t)val; - ret = 3; - } -#ifdef __linux__ - gCfg->atcai2c.baud = 100000; + return ret; +} #endif -#endif /* ATCA_HAL_KIT_HID */ - } - else if (0 == strcmp("swi", argv[1])) - { - gCfg->iface_type = ATCA_SWI_IFACE; - if (argc >= 3 && argv[2][0] != '-') - { - uint32_t val = strtol(argv[2], NULL, 16); - gCfg->atcaswi.bus = (uint8_t)val; - ret = 3; - } - } - else if (0 == strcmp("spi", argv[1])) - { - gCfg->iface_type = ATCA_SPI_IFACE; +#ifdef ATCA_HAL_SPI +/** \brief Configure the spi hal */ +static int opt_iface_spi(int argc, char* argv[]) +{ + int ret = 0; + gCfg->iface_type = ATCA_SPI_IFACE; - if (argc >= 3 && argv[2][0] != '-') - { - gCfg->atcaspi.bus = (uint8_t)strtol(argv[2], NULL, 16); - ret = 3; - } - else - { - gCfg->atcaspi.bus = 0; - } + if(argc) + { + ATCA_IFACECFG_VALUE(gCfg, atcaspi.bus) = (uint8_t)strtol(argv[0], NULL, 16); + } + else + { + ATCA_IFACECFG_VALUE(gCfg, atcaspi.bus) = 0; + } - if (argc >= 4 && argv[3][0] != '-') - { - gCfg->atcaspi.select_pin = (uint8_t)strtol(argv[3], NULL, 16); - } - else - { - gCfg->atcaspi.select_pin = 0; - } + if (1 < argc) + { + ATCA_IFACECFG_VALUE(gCfg, atcaspi.select_pin) = (uint8_t)strtol(argv[1], NULL, 16); + } + else + { + ATCA_IFACECFG_VALUE(gCfg, atcaspi.select_pin) = 0; + } - if (argc >= 5 && argv[4][0] != '-') - { - gCfg->atcaspi.baud = (uint32_t)strtol(argv[4], NULL, 10); - } - else - { - gCfg->atcaspi.baud = 200000; - } - } - else if (0 == strcmp("uart", argv[1])) - { - gCfg->iface_type = ATCA_UART_IFACE; - gCfg->atcauart.dev_interface = ATCA_KIT_AUTO_IFACE; - gCfg->atcauart.dev_identity = 0; + if (2 < argc) + { + ATCA_IFACECFG_VALUE(gCfg, atcaspi.baud) = (uint32_t)strtol(argv[2], NULL, 10); + } + else + { + ATCA_IFACECFG_VALUE(gCfg, atcaspi.baud) = 200000; + } - if (argc >= 3 && argv[2][0] != '-') - { - /* Port/Device */ -#ifdef _WIN32 - gCfg->atcauart.port = (uint8_t)strtol(argv[2], NULL, 10); + return ret; +} +#endif + +#ifdef ATCA_HAL_KIT_UART +/** \brief Configure the kit uart hal */ +static int opt_iface_uart(int argc, char* argv[]) +{ + int ret = -1; + + gCfg->iface_type = ATCA_UART_IFACE; + ATCA_IFACECFG_VALUE(gCfg, atcauart.dev_interface) = ATCA_KIT_AUTO_IFACE; + ATCA_IFACECFG_VALUE(gCfg, atcauart.dev_identity) = 0; + + if (argc) + { + /* Port/Device */ +#ifdef __linux__ + size_t len = strlen(argv[0]); + if (len < sizeof(opt_device_name)) + { + memcpy(opt_device_name, argv[0], len); + gCfg->cfg_data = opt_device_name; + } #else - size_t len = strlen(argv[2]); - if (len < sizeof(opt_device_name)) - { - memcpy(opt_device_name, argv[2], len); - gCfg->cfg_data = opt_device_name; - } + ATCA_IFACECFG_VALUE(gCfg, atcauart.port) = (uint8_t)strtol(argv[0], NULL, 10); #endif - ret = 3; - } + ret = 0; + } - if (argc >= 4 && argv[3][0] != '-') - { - /* Baud rate */ - gCfg->atcauart.baud = (uint8_t)strtol(argv[3], NULL, 10); - ret++; - } - else - { - gCfg->atcauart.baud = 115200UL; - } + if (1 < argc) + { + /* Baud rate */ + ATCA_IFACECFG_VALUE(gCfg, atcauart.baud) = (uint8_t)strtol(argv[1], NULL, 10); + } + else + { + ATCA_IFACECFG_VALUE(gCfg, atcauart.baud) = 115200UL; + } - if (argc >= 5 && argv[4][0] != '-') - { - /* Word size */ - gCfg->atcauart.wordsize = (uint8_t)strtol(argv[4], NULL, 10); - ret++; - } - else - { - gCfg->atcauart.wordsize = 8; - } + if (2 < argc) + { + /* Word size */ + ATCA_IFACECFG_VALUE(gCfg, atcauart.wordsize) = (uint8_t)strtol(argv[2], NULL, 10); + } + else + { + ATCA_IFACECFG_VALUE(gCfg, atcauart.wordsize) = 8; + } - if (argc >= 6 && argv[5][0] != '-') - { - /* Stop Bits */ - gCfg->atcauart.stopbits = (uint8_t)strtol(argv[5], NULL, 10); - ret++; - } - else - { - gCfg->atcauart.stopbits = 1; - } + if (3 < argc) + { + /* Stop Bits */ + ATCA_IFACECFG_VALUE(gCfg, atcauart.stopbits) = (uint8_t)strtol(argv[3], NULL, 10); + } + else + { + ATCA_IFACECFG_VALUE(gCfg, atcauart.stopbits) = 1; + } - if (argc >= 7 && argv[6][0] != '-') - { - /* Parity Bits */ - //gCfg->atcauart.parity = (uint8_t)strtol(argv[6], NULL, 16); - ret++; - } - else - { - gCfg->atcauart.parity = 2; - } - } + if (4 < argc) + { + /* Parity Bits */ + //gCfg->atcauart.parity = (uint8_t)strtol(argv[4], NULL, 16); + } + else + { + ATCA_IFACECFG_VALUE(gCfg, atcauart.parity) = 2; } -#ifdef ATCA_TEST_MULTIPLE_INSTANCES - select_dev_cfg_data(); + return ret; +} #endif + +#ifdef ATCA_HAL_KIT_BRIDGE +/** \brief Configure the bridge hal - requires hal_kit_bridge_connect to be + * linked into the application */ +static int opt_iface_bridge(int argc, char* argv[]) +{ + int ret = -1; + + gCfg->iface_type = ATCA_KIT_IFACE, + ATCA_IFACECFG_VALUE(gCfg, atcakit.dev_interface) = ATCA_KIT_AUTO_IFACE; + ATCA_IFACECFG_VALUE(gCfg, atcakit.dev_identity) = 0; + + if(ATCA_SUCCESS == hal_kit_bridge_connect(gCfg, argc, argv)) + { + ret = 0; + } + return ret; } +#endif + +/** List of support interface types */ +static t_menu_info_simple opt_iface_type_list[] = { +#ifdef ATCA_HAL_KIT_HID + MENU_ITEM_SIMPLE("hid", opt_iface_hid), +#endif +#ifdef ATCA_HAL_I2C + MENU_ITEM_SIMPLE("i2c", opt_iface_i2c), +#endif +#if defined(ATCA_HAL_SWI_UART) || defined(ATCA_HAL_SWI_GPIO) || defined(ATCA_HAL_SWI_BB) + MENU_ITEM_SIMPLE("swi", opt_iface_swi), +#endif +#ifdef ATCA_HAL_SPI + MENU_ITEM_SIMPLE("spi", opt_iface_spi), +#endif +#ifdef ATCA_HAL_KIT_UART + MENU_ITEM_SIMPLE("uart", opt_iface_uart), +#endif +#ifdef ATCA_HAL_KIT_BRIDGE + MENU_ITEM_SIMPLE("bridge", opt_iface_bridge), +#endif + MENU_ITEM_SIMPLE(NULL, NULL) +}; #ifdef ATCA_TEST_MULTIPLE_INSTANCES -void select_dev_cfg_data() +static void select_dev_cfg_data() { size_t num_of_elements; int i; @@ -432,6 +538,22 @@ void select_dev_cfg_data() } #endif +/** \brief Sets the interface the command or test suite will use + * + * \param[in] argc Number of arguments in the arg list + * \param[out] argv Argument list + * \return Number of arguments parsed + */ +static int opt_iface_type(int argc, char* argv[]) +{ + int ret = process_option(opt_iface_type_list, argc, argv); + +#ifdef ATCA_TEST_MULTIPLE_INSTANCES + select_dev_cfg_data(); +#endif + return ret; +} + /** \brief Sets the device address based on interface type (this option must be provided after * specifying the interface type otherwise it might produce unexpected results). * @@ -442,67 +564,28 @@ void select_dev_cfg_data() static int opt_address(int argc, char* argv[]) { int ret = 0; - ATCAKitType kit_type = ATCA_KIT_AUTO_IFACE; + uint8_t address = 0; + ATCAKitType kit_type = ATCA_KIT_UNKNOWN_IFACE; - if (argc >= 2) + if(argc) { - uint32_t val = strtol(argv[1], NULL, 16); - - if (argc >= 3 && argv[2][0] != '-') - { - if (0 == strcmp("i2c", argv[2])) - { - kit_type = ATCA_KIT_I2C_IFACE; - } - else if (0 == strcmp("swi", argv[2])) - { - kit_type = ATCA_KIT_SWI_IFACE; - } - else if (0 == strcmp("spi", argv[2])) - { - kit_type = ATCA_KIT_SPI_IFACE; - } - ret = 3; - } - else - { - ret = 2; - } + address = (uint8_t)strtol(argv[0], NULL, 16); + } + else + { + ret = -1; + } - switch (gCfg->iface_type) + if( 1 < argc ) + { + if(ifacetype_is_kit(gCfg->iface_type)) { - case ATCA_I2C_IFACE: -#ifdef ATCA_ENABLE_DEPRECATED - gCfg->atcai2c.slave_address = (uint8_t)val; -#else - gCfg->atcai2c.address = (uint8_t)val; -#endif - break; - case ATCA_SWI_IFACE: - gCfg->atcaswi.address = (uint8_t)val; - break; - case ATCA_UART_IFACE: - gCfg->atcauart.dev_identity = (uint8_t)val; - if (argc >= 3) - { - gCfg->atcauart.dev_interface = kit_type; - } - break; - case ATCA_SPI_IFACE: - gCfg->atcaspi.select_pin = (uint8_t)val; - break; - case ATCA_HID_IFACE: - gCfg->atcahid.dev_identity = (uint8_t)val; - if (argc >= 3) - { - gCfg->atcahid.dev_interface = kit_type; - } - break; - default: - break; + kit_type = opt_get_kit_iface_type(argv[1]); } } + (void)ifacecfg_set_address(gCfg, address, kit_type); + #ifdef ATCA_TEST_MULTIPLE_INSTANCES select_dev_cfg_data(); #endif @@ -512,69 +595,79 @@ static int opt_address(int argc, char* argv[]) static int opt_quiet(int argc, char* argv[]) { + print_args(__func__, argc, argv); ((void)argc); ((void)argv); g_atca_test_quiet_mode = true; return 1; } -// *INDENT-OFF* - Preserve formatting -static t_menu_info cmd_options[] = +/** \brief Options support for the command line - '-p' is reserved to + * stop any argument parsing and to pass the remaining arguments through + * to the command itself */ +static const t_menu_info_simple cmd_options[] = { - { "-d", "device type", opt_device_type }, - { "-i", "interface", opt_iface_type }, - { "-a", "address", opt_address }, - { "-y", "silence prompts (implicit agreement)", opt_quiet }, - { NULL, NULL, NULL }, + MENU_ITEM_SIMPLE("-d", opt_device_type), + MENU_ITEM_SIMPLE("-i", opt_iface_type), + MENU_ITEM_SIMPLE("-a", opt_address), + MENU_ITEM_SIMPLE("-y", opt_quiet), + MENU_ITEM_SIMPLE(NULL, NULL) }; -// *INDENT-ON* -/** \brief Process an individual command option +/** \brief Helper function to count parameters before another + argument is encountered */ +static inline int process_options_count_params(int argc, char* argv[]) +{ + int i = 1; + if (argv) + { + for(; imenu_cmd, argv[0])) + int opt_argc = process_options_count_params(argc, pargv); + if (!strcmp("-p", *pargv)) { - if (menu_item->fp_handler) + /* Special command at the end the parsing and passthrough + arguments to the test framework */ + int i; + pargv++; + --argc; + for(i=0; i < argc; i++) { - ret = menu_item->fp_handler(argc, argv); + argv[i] = pargv[i]; } + ret = 0; break; } + else if (0 <= (ret = process_option(cmd_options, opt_argc, pargv))) + { + argc -= opt_argc; + pargv += opt_argc; + } } - while ((++menu_item)->menu_cmd); + while (argc > 0 && ret >= 0 && *pargv); } - return ret; -} - -/** \brief Iterate through and argument list and process all options - * - * \param[in] argc Number of arguments in the arg list - * \param[out] argv Argument list - * \return Number of arguments parsed from the list - */ -int process_options(int argc, char* argv[]) -{ - int ret; - int cur_arg = 0; - - do + else if(!argc) { - ret = process_option(argc - cur_arg, &argv[cur_arg]); - cur_arg += ret; + ret = 0; } - while (argc > cur_arg && ret >= 0); - return ret; + return (0 > ret) ? ret : argc; } diff --git a/test/atca_test_console.c b/test/atca_test_console.c index 73db0ebbd..469ec58d2 100644 --- a/test/atca_test_console.c +++ b/test/atca_test_console.c @@ -27,7 +27,8 @@ #include "cryptoauthlib.h" #include "atca_test.h" -#include "atca_crypto_sw_tests.h" +#include "api_atcab/test_atcab.h" +#include "api_crypto/test_crypto.h" #ifndef ATCA_SERIAL_NUM_SIZE #define ATCA_SERIAL_NUM_SIZE (9) @@ -37,17 +38,6 @@ #define RANDOM_RSP_SIZE (32) #endif -int run_basic_tests(int argc, char* argv[]) -{ -#ifdef ATCA_ATECC608_SUPPORT - if (ATECC608 == (gCfg->devtype)) - { - check_clock_divider(argc, argv); - } -#endif - return run_test(argc, argv, RunAllBasicTests); -} - int run_otpzero_tests(int argc, char* argv[]) { return run_test(argc, argv, RunBasicOtpZero); @@ -146,7 +136,10 @@ int lock_config(int argc, char* argv[]) { int ret = lock_config_zone(argc, argv); - lock_status(argc, argv); + if (ATCA_COMM_FAIL != ret) + { + lock_status(argc, argv); + } return ret; } @@ -154,52 +147,58 @@ int lock_data(int argc, char* argv[]) { int ret = lock_data_zone(argc, argv); - lock_status(argc, argv); + if (ATCA_COMM_FAIL != ret) + { + lock_status(argc, argv); + } return ret; } int do_randoms(int argc, char* argv[]) { - ATCA_STATUS status; - uint8_t randout[RANDOM_RSP_SIZE]; - char displayStr[100]; - size_t displen = sizeof(displayStr); - int i; - + ATCA_STATUS status = ATCA_GEN_FAIL; ((void)argc); ((void)argv); if ((gCfg->devtype == ATSHA206A) || (ECC204 == gCfg->devtype)) { printf("Selected Device doesn't support random command\r\n"); - return ATCA_GEN_FAIL; } - - status = atcab_init(gCfg); - if (status != ATCA_SUCCESS) + else { - printf("atcab_init() failed with ret=0x%08X\r\n", status); - return status; - } +#if CALIB_RANDOM_EN || TALIB_RANDOM_EN + uint8_t randout[RANDOM_RSP_SIZE]; + char displayStr[100]; + size_t displen = sizeof(displayStr); + int i; - printf("Random Numbers:\r\n"); - for (i = 0; i < 5; i++) - { - if ((status = atcab_random(randout)) != ATCA_SUCCESS) + status = atcab_init(gCfg); + if (status != ATCA_SUCCESS) { - break; + printf("atcab_init() failed with ret=0x%08X\r\n", status); + return status; } - displen = sizeof(displayStr); - atcab_bin2hex(randout, 32, displayStr, &displen); - printf("%s\r\n", displayStr); - } - if (status != ATCA_SUCCESS) - { - printf("atcab_random() failed with ret=0x%08X\r\n", status); - } + printf("Random Numbers:\r\n"); + for (i = 0; i < 5; i++) + { + if ((status = atcab_random(randout)) != ATCA_SUCCESS) + { + break; + } + displen = sizeof(displayStr); + atcab_bin2hex(randout, 32, displayStr, &displen); + printf("%s\r\n", displayStr); + } - atcab_release(); + if (status != ATCA_SUCCESS) + { + printf("atcab_random() failed with ret=0x%08X\r\n", status); + } + + atcab_release(); +#endif + } return status; } @@ -249,15 +248,13 @@ int read_sernum(int argc, char* argv[]) void RunAllCertDataTests(void); int certdata_unit_tests(int argc, char* argv[]) { - UnityMain(argc, (const char**)argv, RunAllCertDataTests); - return ATCA_SUCCESS; + return run_test(argc, argv, RunAllCertDataTests); } void RunAllCertIOTests(void); int certio_unit_tests(int argc, char* argv[]) { - UnityMain(argc, (const char**)argv, RunAllCertIOTests); - return ATCA_SUCCESS; + return run_test(argc, argv, RunAllCertIOTests); } #endif @@ -431,24 +428,6 @@ ATCA_STATUS get_serial_no(uint8_t* sernum) return status; } -int run_test(int argc, char* argv[], void (*fptest)(void)) -{ - if (CMD_PROCESSOR_MAX_ARGS > argc) - { - argv[argc++] = "-v"; - } - - if (gCfg->devtype < ATCA_DEV_UNKNOWN) - { - return UnityMain(argc, (const char**)argv, fptest); - } - else - { - printf("Device is NOT Selected... Select device before running tests!!!"); - return -1; - } -} - int run_all_tests(int argc, char* argv[]) { ATCA_STATUS status; @@ -596,8 +575,8 @@ int run_tng_tests(int argc, char* argv[]) { ATCA_STATUS status; - gCfg->atcahid.dev_interface = ATCA_KIT_I2C_IFACE; - gCfg->atcahid.dev_identity = 0x6C; + ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_interface) = ATCA_KIT_I2C_IFACE; + ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_identity) = 0x6C; status = atcab_init(gCfg); if (status != ATCA_SUCCESS) @@ -612,14 +591,22 @@ int run_tng_tests(int argc, char* argv[]) return 0; } -#if defined(ATCA_MBEDTLS) -int run_crypto_integration_tests(int argc, char* argv[]) +int run_wpc_tests(int argc, char* argv[]) { - return run_test(argc, argv, RunCryptoIntegrationTests); -} -#endif + ATCA_STATUS status; -int run_pbkdf2_tests(int argc, char* argv[]) -{ - return run_test(argc, argv, RunPbkdf2Tests); +// ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_interface) = ATCA_KIT_I2C_IFACE; +// ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_identity) = 0x70; + + status = atcab_init(gCfg); + if (status != ATCA_SUCCESS) + { + printf("atcab_init() failed with ret=0x%08X\r\n", status); + return status; + } + + run_test(argc, argv, RunWPCTests); + + atcab_release(); + return 0; } diff --git a/test/atcacert/all_atcacert_tests.c b/test/atcacert/test_atcacert.c similarity index 96% rename from test/atcacert/all_atcacert_tests.c rename to test/atcacert/test_atcacert.c index 087a9d3f7..724699438 100644 --- a/test/atcacert/all_atcacert_tests.c +++ b/test/atcacert/test_atcacert.c @@ -42,18 +42,26 @@ void RunAllCertDataTests(void) RUN_TEST_GROUP(atcacert_der_enc_ecdsa_sig_value); RUN_TEST_GROUP(atcacert_der_dec_ecdsa_sig_value); +#if ATCACERT_DATEFMT_ISO_EN RUN_TEST_GROUP(atcacert_date_enc_iso8601_sep); +#endif RUN_TEST_GROUP(atcacert_date_enc_rfc5280_utc); +#if ATCACERT_DATEFMT_POSIX_EN RUN_TEST_GROUP(atcacert_date_enc_posix_uint32_be); RUN_TEST_GROUP(atcacert_date_enc_posix_uint32_le); +#endif RUN_TEST_GROUP(atcacert_date_enc_rfc5280_gen); RUN_TEST_GROUP(atcacert_date_enc_compcert); RUN_TEST_GROUP(atcacert_date_enc); +#if ATCACERT_DATEFMT_ISO_EN RUN_TEST_GROUP(atcacert_date_dec_iso8601_sep); +#endif RUN_TEST_GROUP(atcacert_date_dec_rfc5280_utc); +#if ATCACERT_DATEFMT_POSIX_EN RUN_TEST_GROUP(atcacert_date_dec_posix_uint32_be); RUN_TEST_GROUP(atcacert_date_dec_posix_uint32_le); +#endif RUN_TEST_GROUP(atcacert_date_dec_rfc5280_gen); RUN_TEST_GROUP(atcacert_date_get_max_date); RUN_TEST_GROUP(atcacert_date_dec_compcert); diff --git a/lib/crypto/atca_crypto_sw_rand.c b/test/atcacert/test_atcacert.h similarity index 71% rename from lib/crypto/atca_crypto_sw_rand.c rename to test/atcacert/test_atcacert.h index be25677d3..9acc28573 100644 --- a/lib/crypto/atca_crypto_sw_rand.c +++ b/test/atcacert/test_atcacert.h @@ -1,6 +1,6 @@ /** * \file - * \brief API wrapper for software random + * \brief Test for the Cryptoauthlib Compressed Certficiate API * * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. * @@ -25,21 +25,23 @@ * THIS SOFTWARE. */ -#include "cryptoauthlib.h" +#ifndef TEST_ATCACERT_H +#define TEST_ATCACERT_H -#ifdef ATCA_ENABLE_RAND_IMPL +#ifdef __cplusplus +extern "C" { +#endif -#include "atca_crypto_sw_rand.h" +#include "atca_test.h" -/** \brief return software generated random number and the function is currently not implemented - * \param[out] data ptr to space to receive the random number - * \param[in] data_size size of data buffer - * return ATCA_UNIMPLEMENTED , as the function is not implemented - */ -int atcac_sw_random(uint8_t* data, size_t data_size) -{ - return ATCA_UNIMPLEMENTED; -} +/* Console Functions */ +int certdata_unit_tests(int argc, char* argv[]); +int certio_unit_tests(int argc, char* argv[]); + +#ifdef __cplusplus +} #endif + +#endif /* TEST_ATCACERT_H */ diff --git a/test/atcacert/test_atcacert_client.c b/test/atcacert/test_atcacert_client.c index 8cdc1cce0..72e927e38 100644 --- a/test/atcacert/test_atcacert_client.c +++ b/test/atcacert/test_atcacert_client.c @@ -220,21 +220,21 @@ TEST(atcacert_client, init) ret = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, config32, 32); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); - ret = atcab_genkey(signer_ca_private_key_slot, g_signer_ca_public_key); + ret = atca_test_genkey(signer_ca_private_key_slot, g_signer_ca_public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); disp_size = sizeof(disp_str); ret = atcab_bin2hex(g_signer_ca_public_key, ATCA_ECCP256_PUBKEY_SIZE, disp_str, &disp_size); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); printf("Signer CA Public Key:\r\n%s\r\n", disp_str); - ret = atcab_genkey(signer_private_key_slot, g_signer_public_key); + ret = atca_test_genkey(signer_private_key_slot, g_signer_public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); disp_size = sizeof(disp_str); ret = atcab_bin2hex(g_signer_public_key, ATCA_ECCP256_PUBKEY_SIZE, disp_str, &disp_size); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); printf("Signer Public Key:\r\n%s\r\n", disp_str); - ret = atcab_genkey(device_private_key_slot, g_device_public_key); + ret = atca_test_genkey(device_private_key_slot, g_device_public_key); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); disp_size = sizeof(disp_str); ret = atcab_bin2hex(g_device_public_key, ATCA_ECCP256_PUBKEY_SIZE, disp_str, &disp_size); diff --git a/test/atcacert/test_atcacert_date.c b/test/atcacert/test_atcacert_date.c index 0ef277777..b8f2349b0 100644 --- a/test/atcacert/test_atcacert_date.c +++ b/test/atcacert/test_atcacert_date.c @@ -49,6 +49,7 @@ static void set_tm(atcacert_tm_utc_t* ts, int year, int month, int day, int hour ts->tm_sec = sec; } +#if ATCACERT_DATEFMT_ISO_EN TEST_GROUP(atcacert_date_enc_iso8601_sep); TEST_SETUP(atcacert_date_enc_iso8601_sep) @@ -209,9 +210,7 @@ TEST(atcacert_date_enc_iso8601_sep, bad_params) ret = atcacert_date_enc_iso8601_sep(NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); } - - - +#endif TEST_GROUP(atcacert_date_enc_rfc5280_utc); @@ -395,7 +394,7 @@ TEST(atcacert_date_enc_rfc5280_utc, bad_params) } - +#if ATCACERT_DATEFMT_POSIX_EN TEST_GROUP(atcacert_date_enc_posix_uint32_be); TEST_SETUP(atcacert_date_enc_posix_uint32_be) @@ -611,7 +610,7 @@ TEST(atcacert_date_enc_posix_uint32_le, bad_params) ret = atcacert_date_enc_posix_uint32_le(NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); } - +#endif TEST_GROUP(atcacert_date_enc_rfc5280_gen); @@ -954,6 +953,7 @@ TEST_TEAR_DOWN(atcacert_date_enc) { } +#if ATCACERT_DATEFMT_ISO_EN TEST(atcacert_date_enc, iso8601_sep) { int ret = 0; @@ -975,6 +975,7 @@ TEST(atcacert_date_enc, iso8601_sep) TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); TEST_ASSERT_EQUAL(DATEFMT_ISO8601_SEP_SIZE, ts_str_size); } +#endif TEST(atcacert_date_enc, rfc5280_utc) { @@ -998,6 +999,7 @@ TEST(atcacert_date_enc, rfc5280_utc) TEST_ASSERT_EQUAL(DATEFMT_RFC5280_UTC_SIZE, ts_str_size); } +#if ATCACERT_DATEFMT_POSIX_EN TEST(atcacert_date_enc, posix_uint32_be) { int ret = 0; @@ -1041,6 +1043,7 @@ TEST(atcacert_date_enc, posix_uint32_le) TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); TEST_ASSERT_EQUAL(DATEFMT_POSIX_UINT32_BE_SIZE, ts_str_size); } +#endif TEST(atcacert_date_enc, rfc5280_gen) { @@ -1130,7 +1133,7 @@ TEST(atcacert_date_enc, bad_params) - +#if ATCACERT_DATEFMT_ISO_EN TEST_GROUP(atcacert_date_dec_iso8601_sep); TEST_SETUP(atcacert_date_dec_iso8601_sep) @@ -1232,7 +1235,7 @@ TEST(atcacert_date_dec_iso8601_sep, bad_params) ret = atcacert_date_dec_iso8601_sep(NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); } - +#endif @@ -1361,7 +1364,7 @@ TEST(atcacert_date_dec_rfc5280_utc, bad_params) } - +#if ATCACERT_DATEFMT_POSIX_EN TEST_GROUP(atcacert_date_dec_posix_uint32_be); TEST_SETUP(atcacert_date_dec_posix_uint32_be) @@ -1564,7 +1567,7 @@ TEST(atcacert_date_dec_posix_uint32_le, bad_params) ret = atcacert_date_dec_posix_uint32_le(NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); } - +#endif TEST_GROUP(atcacert_date_dec_rfc5280_gen); diff --git a/test/atcacert/test_atcacert_date_runner.c b/test/atcacert/test_atcacert_date_runner.c index 2782b44c7..a20819f8a 100644 --- a/test/atcacert/test_atcacert_date_runner.c +++ b/test/atcacert/test_atcacert_date_runner.c @@ -34,6 +34,7 @@ #undef min #undef max +#if ATCACERT_DATEFMT_ISO_EN TEST_GROUP_RUNNER(atcacert_date_enc_iso8601_sep) { RUN_TEST_CASE(atcacert_date_enc_iso8601_sep, good); @@ -47,6 +48,7 @@ TEST_GROUP_RUNNER(atcacert_date_enc_iso8601_sep) RUN_TEST_CASE(atcacert_date_enc_iso8601_sep, bad_sec); RUN_TEST_CASE(atcacert_date_enc_iso8601_sep, bad_params); } +#endif TEST_GROUP_RUNNER(atcacert_date_enc_rfc5280_utc) { @@ -63,6 +65,7 @@ TEST_GROUP_RUNNER(atcacert_date_enc_rfc5280_utc) RUN_TEST_CASE(atcacert_date_enc_rfc5280_utc, bad_params); } +#if ATCACERT_DATEFMT_POSIX_EN TEST_GROUP_RUNNER(atcacert_date_enc_posix_uint32_be) { RUN_TEST_CASE(atcacert_date_enc_posix_uint32_be, good); @@ -84,6 +87,7 @@ TEST_GROUP_RUNNER(atcacert_date_enc_posix_uint32_le) RUN_TEST_CASE(atcacert_date_enc_posix_uint32_le, bad_high); RUN_TEST_CASE(atcacert_date_enc_posix_uint32_le, bad_params); } +#endif TEST_GROUP_RUNNER(atcacert_date_enc_rfc5280_gen) { @@ -114,17 +118,21 @@ TEST_GROUP_RUNNER(atcacert_date_enc_compcert) TEST_GROUP_RUNNER(atcacert_date_enc) { +#if ATCACERT_DATEFMT_ISO_EN RUN_TEST_CASE(atcacert_date_enc, iso8601_sep); +#endif RUN_TEST_CASE(atcacert_date_enc, rfc5280_utc); +#if ATCACERT_DATEFMT_POSIX_EN RUN_TEST_CASE(atcacert_date_enc, posix_uint32_be); RUN_TEST_CASE(atcacert_date_enc, posix_uint32_le); +#endif RUN_TEST_CASE(atcacert_date_enc, rfc5280_gen); RUN_TEST_CASE(atcacert_date_enc, small_buf); RUN_TEST_CASE(atcacert_date_enc, bad_format); RUN_TEST_CASE(atcacert_date_enc, bad_params); } - +#if ATCACERT_DATEFMT_ISO_EN TEST_GROUP_RUNNER(atcacert_date_dec_iso8601_sep) { RUN_TEST_CASE(atcacert_date_dec_iso8601_sep, good); @@ -133,6 +141,7 @@ TEST_GROUP_RUNNER(atcacert_date_dec_iso8601_sep) RUN_TEST_CASE(atcacert_date_dec_iso8601_sep, bad_int); RUN_TEST_CASE(atcacert_date_dec_iso8601_sep, bad_params); } +#endif TEST_GROUP_RUNNER(atcacert_date_dec_rfc5280_utc) { @@ -144,6 +153,7 @@ TEST_GROUP_RUNNER(atcacert_date_dec_rfc5280_utc) RUN_TEST_CASE(atcacert_date_dec_rfc5280_utc, bad_params); } +#if ATCACERT_DATEFMT_POSIX_EN TEST_GROUP_RUNNER(atcacert_date_dec_posix_uint32_be) { RUN_TEST_CASE(atcacert_date_dec_posix_uint32_be, good); @@ -163,6 +173,7 @@ TEST_GROUP_RUNNER(atcacert_date_dec_posix_uint32_le) RUN_TEST_CASE(atcacert_date_dec_posix_uint32_le, max); RUN_TEST_CASE(atcacert_date_dec_posix_uint32_le, bad_params); } +#endif TEST_GROUP_RUNNER(atcacert_date_dec_rfc5280_gen) { @@ -175,10 +186,14 @@ TEST_GROUP_RUNNER(atcacert_date_dec_rfc5280_gen) TEST_GROUP_RUNNER(atcacert_date_get_max_date) { +#if ATCACERT_DATEFMT_ISO_EN RUN_TEST_CASE(atcacert_date_get_max_date, iso8601_sep); +#endif RUN_TEST_CASE(atcacert_date_get_max_date, rfc5280_utc); +#if ATCACERT_DATEFMT_POSIX_EN RUN_TEST_CASE(atcacert_date_get_max_date, posix_uint32_be); RUN_TEST_CASE(atcacert_date_get_max_date, posix_uint32_le); +#endif RUN_TEST_CASE(atcacert_date_get_max_date, rfc5280_gen); RUN_TEST_CASE(atcacert_date_get_max_date, new_format); RUN_TEST_CASE(atcacert_date_get_max_date, bad_params); @@ -195,10 +210,14 @@ TEST_GROUP_RUNNER(atcacert_date_dec_compcert) TEST_GROUP_RUNNER(atcacert_date_dec) { +#if ATCACERT_DATEFMT_ISO_EN RUN_TEST_CASE(atcacert_date_dec, iso8601_sep); +#endif RUN_TEST_CASE(atcacert_date_dec, rfc5280_utc); +#if ATCACERT_DATEFMT_POSIX_EN RUN_TEST_CASE(atcacert_date_dec, posix_uint32_be); RUN_TEST_CASE(atcacert_date_dec, posix_uint32_le); +#endif RUN_TEST_CASE(atcacert_date_dec, rfc5280_gen); RUN_TEST_CASE(atcacert_date_dec, small_buf); RUN_TEST_CASE(atcacert_date_dec, bad_format); diff --git a/test/atcacert/test_atcacert_def.c b/test/atcacert/test_atcacert_def.c index 38aefee74..0d7f50862 100644 --- a/test/atcacert/test_atcacert_def.c +++ b/test/atcacert/test_atcacert_def.c @@ -5435,6 +5435,7 @@ TEST(atcacert_cert_build, start_signer) .device_sn = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }; atcacert_build_state_t build_state; + memset(&build_state, 0, sizeof(build_state)); ret = atcacert_cert_build_start( &build_state, diff --git a/test/atcacert/test_atcacert_host_hw.c b/test/atcacert/test_atcacert_host_hw.c index 50f522383..8e21a75c7 100644 --- a/test/atcacert/test_atcacert_host_hw.c +++ b/test/atcacert/test_atcacert_host_hw.c @@ -222,6 +222,16 @@ TEST(atcacert_host_hw, atcacert_gen_challenge_hw) uint8_t init[32]; uint8_t challenge1[32]; uint8_t challenge2[32]; + bool lockstate = false; + + /* The random command for unlocked cryptoauth devices returns + a fixed pattern that never changes */ + ret = atcab_is_config_locked(&lockstate); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + if (!lockstate) + { + TEST_IGNORE_MESSAGE("Config zone must be locked for this test."); + } memset(init, 0, sizeof(init)); memcpy(challenge1, init, sizeof(challenge1)); diff --git a/test/cmd-processor.c b/test/cmd-processor.c index 837361d22..da73717a9 100644 --- a/test/cmd-processor.c +++ b/test/cmd-processor.c @@ -34,14 +34,33 @@ #endif #include "cryptoauthlib.h" #include "atca_test.h" -#include "atca_crypto_sw_tests.h" #include "cmd-processor.h" #include "atca_cfgs.h" +#if ATCA_CA_SUPPORT +#include "api_calib/test_calib.h" +#endif + +#if ATCA_CA_SUPPORT && !defined(DO_NOT_TEST_CERT) +#include "atcacert/test_atcacert.h" +#endif + #if ATCA_TA_SUPPORT #include "api_talib/test_talib.h" #endif +/* Common API Testing - atcab_ is the classic Cryptoauthlib API */ +#include "api_atcab/test_atcab.h" + +/* Host side Cryptographic API Testing */ +#include "api_crypto/test_crypto.h" + +/* Library Integration Tests - Tests to ensure the library accesses device properly*/ +#include "integration/test_integration.h" + +/* JWT Support */ +#include "jwt/test_jwt.h" + static int help(int argc, char* argv[]); #if defined(_WIN32) || defined(__linux__) || defined(__APPLE__) @@ -54,25 +73,25 @@ static t_menu_info mas_menu_info[] = { { "help", "Display Menu", help }, #ifdef ATCA_ATSHA204A_SUPPORT - { "sha204", "Set Target Device to ATSHA204A", select_204 }, + { "sha204", "Set Target Device to ATSHA204A", select_device }, #endif #ifdef ATCA_ATSHA206A_SUPPORT - { "sha206", "Set Target Device to ATSHA206A", select_206 }, + { "sha206", "Set Target Device to ATSHA206A", select_device }, #endif #ifdef ATCA_ATECC108A_SUPPORT - { "ecc108", "Set Target Device to ATECC108A", select_108 }, + { "ecc108", "Set Target Device to ATECC108A", select_device }, #endif #ifdef ATCA_ECC204_SUPPORT - { "ecc204", "Set Target Device to ECC204", select_ecc204 }, + { "ecc204", "Set Target Device to ECC204", select_device }, #endif #ifdef ATCA_ATECC508A_SUPPORT - { "ecc508", "Set Target Device to ATECC508A", select_508 }, + { "ecc508", "Set Target Device to ATECC508A", select_device }, #endif #ifdef ATCA_ATECC608_SUPPORT - { "ecc608", "Set Target Device to ATECC608", select_608 }, + { "ecc608", "Set Target Device to ATECC608", select_device }, #endif #ifdef ATCA_TA100_SUPPORT - { "ta100", "Set Target Device to TA100", select_ta100 }, + { "ta100", "Set Target Device to TA100", select_device }, #endif { "info", "Get the Chip Revision", info }, { "sernum", "Get the Chip Serial Number", read_sernum }, @@ -85,6 +104,7 @@ static t_menu_info mas_menu_info[] = { "all", "Run all unit tests, locking as needed.", run_all_tests }, #endif { "tng", "Run unit tests on TNG type part.", run_tng_tests }, + { "wpc", "Run unit tests on WPC type part.", run_wpc_tests }, #ifndef DO_NOT_TEST_BASIC_UNIT { "basic", "Run Basic Test on Selected Device", run_basic_tests }, #ifdef ATCA_TEST_LOCK_ENABLE @@ -104,10 +124,10 @@ static t_menu_info mas_menu_info[] = #ifndef DO_NOT_TEST_SW_CRYPTO { "crypto", "Run Unit Tests for Software Crypto Functions", atca_crypto_sw_tests }, #endif - { "pbkdf2", "Run pbkdf2 tests", run_pbkdf2_tests }, #if defined(ATCA_MBEDTLS) - { "crypto_int", "Run crypto library integration tests", run_crypto_integration_tests }, + { "crypto_int", "Run crypto library integration tests", run_integration_tests }, #endif + { "jwt", "Run JWT support tests", run_jwt_tests }, #if ATCA_TA_SUPPORT { "config", "Create testing handles in TA100 device", talib_configure_device }, { "handles", "Print info for stored handles in TA100 device", talib_config_print_handles }, @@ -176,28 +196,27 @@ int parse_cmd_string(char* buffer, const size_t buf_len, const int argc, char* a * \param[in] argv Argument list * \return Execution return code */ -static int run_cmd(int argc, char* argv[]) +static int run_cmd(t_menu_info* menu_item, int argc, char* argv[]) { - t_menu_info* menu_item = mas_menu_info; int ret = -1; - printf("\r\n"); - if (argc) + printf("\n"); + if (argc && argv) { - (void)process_options(argc - 1, &argv[1]); - - do + if(0 <= (ret = process_options(argc - 1, &argv[1]))) { - if (0 == strcmp(menu_item->menu_cmd, argv[0])) + for( ;menu_item->menu_cmd; menu_item++) { - if (menu_item->fp_handler) + if (0 == strcmp(menu_item->menu_cmd, argv[0])) { - ret = menu_item->fp_handler(argc, argv); + if (menu_item->fp_handler) + { + ret = menu_item->fp_handler(ret+1, argv); + } + break; } - break; } } - while ((++menu_item)->menu_cmd); } if (!menu_item->menu_cmd) @@ -205,7 +224,10 @@ static int run_cmd(int argc, char* argv[]) printf("syntax error in command: %s", argv[0]); } - printf("\r\n"); + /* Reset quiet mode for the next command */ + g_atca_test_quiet_mode = false; + + printf("\n"); return ret; } @@ -227,7 +249,7 @@ static int parse_cmd(char *command, size_t max_len) argc = parse_cmd_string(command, max_len, argc, argv); - return run_cmd(argc, argv); + return run_cmd(mas_menu_info, argc, argv); } #if defined(_WIN32) || defined(__linux__) || defined(__APPLE__) @@ -249,7 +271,7 @@ int main(int argc, char* argv[]) { if (argc > 1) { - exit_code = run_cmd(argc - 1, &argv[1]); + exit_code = run_cmd(mas_menu_info, argc - 1, &argv[1]); } else { @@ -258,6 +280,7 @@ int main(int argc, char* argv[]) while (!exit_code) { printf("$ "); + fflush(stdout); if (fgets(buffer, sizeof(buffer), stdin)) { parse_cmd(buffer, sizeof(buffer)); diff --git a/test/integration/test_integration.c b/test/integration/test_integration.c new file mode 100644 index 000000000..f86b31859 --- /dev/null +++ b/test/integration/test_integration.c @@ -0,0 +1,47 @@ +/** + * \file + * \brief Test CryptoAuthLib Integrations into other Libraries + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "test_integration.h" + +static t_test_case_info* integration_tests[] = +{ +#ifdef ATCA_MBEDTLS + mbedtls_ecdsa_test_info, +#endif + (t_test_case_info*)NULL /* Array Termination element*/ +}; + +static void integration_test_runner(void) +{ + RunAllTests(integration_tests); +} + +/* Console function */ +int run_integration_tests(int argc, char* argv[]) +{ + return run_test(argc, argv, integration_test_runner); +} diff --git a/lib/crypto/atca_crypto_sw_rand.h b/test/integration/test_integration.h similarity index 78% rename from lib/crypto/atca_crypto_sw_rand.h rename to test/integration/test_integration.h index dc282c150..48e256382 100644 --- a/lib/crypto/atca_crypto_sw_rand.h +++ b/test/integration/test_integration.h @@ -1,6 +1,6 @@ /** * \file - * \brief + * \brief Test CryptoAuthLib Integrations into other Libraries * * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. * @@ -25,29 +25,24 @@ * THIS SOFTWARE. */ -#ifndef ATCA_CRYPTO_SW_RAND_H -#define ATCA_CRYPTO_SW_RAND_H +#ifndef TEST_INTEGRATION_H +#define TEST_INTEGRATION_H -#include "atca_crypto_sw.h" -#include -#include - -/** \defgroup atcac_ Software crypto methods (atcac_) - * - * \brief - * These methods provide a software implementation of various crypto - * algorithms - * - @{ */ #ifdef __cplusplus extern "C" { #endif -int atcac_sw_random(uint8_t* data, size_t data_size); +#include "atca_test.h" + +#if defined(ATCA_MBEDTLS) +extern t_test_case_info mbedtls_ecdsa_test_info[]; +#endif + +/* Console function */ +int run_integration_tests(int argc, char* argv[]); #ifdef __cplusplus } #endif -/** @} */ -#endif +#endif /* TEST_INTEGRATION_H */ diff --git a/test/integration/test_mbedtls.c b/test/integration/test_mbedtls.c new file mode 100644 index 000000000..8cef2e513 --- /dev/null +++ b/test/integration/test_mbedtls.c @@ -0,0 +1,236 @@ +/** + * \file + * \brief Validation test of the mbedtls integration of hardware accelerated + * ECDSA operations + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "atca_test.h" + +#if defined(ATCA_MBEDTLS) && defined(MBEDTLS_ECDSA_C) +#include "third_party/atca_mbedtls_patch.h" + +#include "mbedtls/atca_mbedtls_wrap.h" +#include "vectors/ecdsa_nist_vectors.h" + +TEST_GROUP(mbedtls_ecdsa); + +TEST_SETUP(mbedtls_ecdsa) +{ + UnityMalloc_StartTest(); + + ATCA_STATUS status = atcab_init(gCfg); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +} + +TEST_TEAR_DOWN(mbedtls_ecdsa) +{ + ATCA_STATUS status; + + status = atcab_wakeup(); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcab_sleep(); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atcab_release(); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + UnityMalloc_EndTest(); +} + +/** \brief This test uses NIST provided vectors for testing verify integration - It may be hardware accelerated . + */ +TEST(mbedtls_ecdsa, verify_nist) +{ + uint8_t pubkey[64]; + uint8_t signature[74]; + uint8_t digest[32]; + atcac_pk_ctx pkey_ctx; + int status; + size_t i; + mbedtls_mpi r; + mbedtls_mpi s; + + /* Test verification using [P-256,SHA-256] vectors */ + for (i = 0; i < ecdsa_p256_test_vectors_count; i++) + { + size_t sig_len = sizeof(signature); + + /* Copy pubkey */ + memcpy(pubkey, ecdsa_p256_test_vectors[i].Qx, 32); + memcpy(&pubkey[32], ecdsa_p256_test_vectors[i].Qy, 32); + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* Copy the signature */ + mbedtls_mpi_read_binary(&r, ecdsa_p256_test_vectors[i].R, 32); + mbedtls_mpi_read_binary(&s, ecdsa_p256_test_vectors[i].S, 32); + + /* Create the asn.1 signature */ + status = mbedtls_ecdsa_signature_to_asn1(&r, &s, signature, &sig_len); + + /* Clean up before checking the result */ + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Hash the message */ + status = atcac_sw_sha2_256(ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Initialize the key using the provided X,Y cordinantes */ + status = atcac_pk_init(&pkey_ctx, pubkey, sizeof(pubkey), 0, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Perform the verification */ + status = mbedtls_pk_verify(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, sig_len); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result against the expected success/failure */ + if (ecdsa_p256_test_vectors[i].Result) + { + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + } + else + { + TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); + } + } +} + +/** \brief Check verify with a stored key in a device + */ +TEST(mbedtls_ecdsa, verify_nist_stored_key) +{ + uint8_t pubkey[64]; + uint8_t signature[74]; + uint8_t digest[32]; + atcac_pk_ctx pkey_ctx; + ATCA_STATUS status; + mbedtls_mpi r; + mbedtls_mpi s; + size_t i; + uint16_t key_slot; + + status = atca_test_config_get_id(TEST_TYPE_ECC_VERIFY, &key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Test verification using [P-256,SHA-256] vectors */ + for (i = 0; i < ecdsa_p256_test_vectors_count; i++) + { + size_t sig_len = sizeof(signature); + + /* Copy pubkey */ + memcpy(pubkey, ecdsa_p256_test_vectors[i].Qx, 32); + memcpy(&pubkey[32], ecdsa_p256_test_vectors[i].Qy, 32); + + mbedtls_mpi_init(&r); + mbedtls_mpi_init(&s); + + /* Copy the signature */ + mbedtls_mpi_read_binary(&r, ecdsa_p256_test_vectors[i].R, 32); + mbedtls_mpi_read_binary(&s, ecdsa_p256_test_vectors[i].S, 32); + + /* Create the asn.1 signature */ + status = mbedtls_ecdsa_signature_to_asn1(&r, &s, signature, &sig_len); + + /* Clean up before checking the result */ + mbedtls_mpi_free(&r); + mbedtls_mpi_free(&s); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Hash the message */ + status = atcac_sw_sha2_256(ecdsa_p256_test_vectors[i].Msg, sizeof(ecdsa_p256_test_vectors[i].Msg), digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Initialize the key using the provided X,Y cordinantes */ + status = atcab_write_pubkey(key_slot, pubkey); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atca_mbedtls_pk_init(&pkey_ctx, key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Perform the verification */ + status = mbedtls_pk_verify(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, sig_len); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result against the expected success/failure */ + if (ecdsa_p256_test_vectors[i].Result) + { + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + } + else + { + TEST_ASSERT_NOT_EQUAL(ATCA_SUCCESS, status); + } + } +} + + +/** \brief Having confirmed the verify passes the NIST vectors the sign operation can be tested + */ +TEST(mbedtls_ecdsa, sign_stored_key) +{ + int status; + atcac_pk_ctx pkey_ctx; + uint8_t digest[32]; + uint8_t signature[74] = { 0 }; + size_t sig_len = sizeof(signature); + uint16_t key_slot; + + status = atca_test_config_get_id(TEST_TYPE_ECC_SIGN, &key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = atca_mbedtls_pk_init(&pkey_ctx, key_slot); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + status = mbedtls_pk_sign(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, &sig_len, NULL, NULL); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + + /* Perform the verification */ + status = mbedtls_pk_verify(&pkey_ctx, MBEDTLS_MD_SHA256, digest, sizeof(digest), signature, sig_len); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + +} + +t_test_case_info mbedtls_ecdsa_test_info[] = +{ + { REGISTER_TEST_CASE(mbedtls_ecdsa, verify_nist), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(mbedtls_ecdsa, verify_nist_stored_key), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + { REGISTER_TEST_CASE(mbedtls_ecdsa, sign_stored_key), DEVICE_MASK_ECC | DEVICE_MASK(TA100) }, + /* Array Termination element*/ + { (fp_test_case)NULL, (uint8_t)0 }, +}; + +#endif diff --git a/test/jwt/atca_jwt_test.c b/test/jwt/atca_jwt_test.c index 72efc3ccd..93bf17d39 100644 --- a/test/jwt/atca_jwt_test.c +++ b/test/jwt/atca_jwt_test.c @@ -23,10 +23,17 @@ * THIS SOFTWARE. */ -#include "third_party/unity/unity_fixture.h" -#include "atca_test.h" +#include "test_jwt.h" #include "jwt/atca_jwt.h" +#ifndef TEST_JWT_SIGN_EN +#define TEST_JWT_SIGN_EN (CALIB_SIGN_ECC204_EN || CALIB_SIGN_EN || TALIB_SIGN_EN) +#endif + +#ifndef TEST_JWT_VERIFY_EN +#define TEST_JWT_VERIFY_EN (ATCA_HOSTLIB_EN || CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN) +#endif + /* Configuration Options */ #define ATCA_JWT_TEST_DEVICES ( DEVICE_MASK(ATECC108A) | DEVICE_MASK(ATECC508A) | DEVICE_MASK(ATECC608) ) #define ATCA_JWT_TEST_SIGNING_KEY_ID (0) @@ -42,6 +49,7 @@ static const char atca_jwt_test_vector_payload_aud[] = "audience"; static const char atca_jwt_test_vector_payload[] = "eyJpYXQiOjEyMzQ1Njc4OSwiZXhwIjoyMzQ1Njc4OTAsImF1ZCI6ImF1ZGllbmNlIn0."; +#if TEST_JWT_VERIFY_EN static const uint8_t atca_jwt_test_vector_pubkey[ATCA_ECCP256_PUBKEY_SIZE] = { 0x01, 0x31, 0x95, 0xB2, 0x30, 0x4D, 0xC7, 0x7E, 0xC0, 0x94, 0x6A, 0x02, 0xE0, 0x4E, 0xDC, 0x51, 0xED, 0xF7, 0xE8, 0x77, 0x9D, 0x44, 0xC9, 0x2B, 0x90, 0xB8, 0xF7, 0xC3, 0x4B, 0x72, 0x9B, 0xD8, @@ -53,6 +61,7 @@ static const char atca_jwt_test_vector_sig[] = static const char atca_jwt_test_vector_invalid_sig[] = "OgnwEMP1l7x67pYNgGxHAIyHZkAwRT3cbWHKCrH4Zi5fOrxXLwFUpnF_0FdPGz3WakETEeWYg79h36tZG_Q_uw"; +#endif TEST_GROUP(atca_jwt); @@ -222,6 +231,7 @@ TEST(atca_jwt, claim_add_numeric_invalid_params) TEST_ASSERT_EQUAL_MEMORY(".", buf, 2); } +#if TEST_JWT_VERIFY_EN TEST(atca_jwt, verify_invalid_params) { char buf[512]; @@ -233,7 +243,9 @@ TEST(atca_jwt, verify_invalid_params) TEST_ASSERT_EQUAL(ATCA_BAD_PARAM, atca_jwt_verify(buf, sizeof(buf), NULL)); } +#endif +#if TEST_JWT_SIGN_EN TEST(atca_jwt, finalize_invalid_params) { atca_jwt_t jwt; @@ -256,6 +268,7 @@ TEST(atca_jwt, finalize_invalid_params) jwt.cur = 0; TEST_ASSERT_EQUAL(ATCA_BAD_PARAM, atca_jwt_finalize(&jwt, ATCA_JWT_TEST_SIGNING_KEY_ID)); } +#endif /* These tests require an attached and configured device */ TEST_GROUP(atca_jwt_crypto); @@ -283,6 +296,7 @@ TEST_TEAR_DOWN(atca_jwt_crypto) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); } +#if TEST_JWT_VERIFY_EN TEST(atca_jwt_crypto, verify) { char buf[512]; @@ -308,7 +322,9 @@ TEST(atca_jwt_crypto, verify_invalid) TEST_ASSERT_EQUAL(ATCA_CHECKMAC_VERIFY_FAILED, atca_jwt_verify(buf, sizeof(buf), atca_jwt_test_vector_pubkey)); } +#endif +#if TEST_JWT_SIGN_EN TEST(atca_jwt_crypto, finalize) { atca_jwt_t jwt; @@ -340,9 +356,12 @@ TEST(atca_jwt_crypto, finalize) /* Load the device public key */ TEST_ASSERT_EQUAL(ATCA_SUCCESS, atcab_get_pubkey(ATCA_JWT_TEST_SIGNING_KEY_ID, pubkey)); +#if TEST_JWT_VERIFY_EN /* Verify the token with the public key */ TEST_ASSERT_EQUAL(ATCA_SUCCESS, atca_jwt_verify(buf, sizeof(buf), pubkey)); +#endif } +#endif /* TEST_JWT_SIGN_EN */ // *INDENT-OFF* - Preserve formatting t_test_case_info jwt_unit_test_info[] = @@ -359,13 +378,37 @@ t_test_case_info jwt_unit_test_info[] = { REGISTER_TEST_CASE(atca_jwt, claim_add_numeric), ATCA_JWT_TEST_DEVICES}, { REGISTER_TEST_CASE(atca_jwt, claim_add_numeric_invalid_params), ATCA_JWT_TEST_DEVICES}, +#if TEST_JWT_VERIFY_EN { REGISTER_TEST_CASE(atca_jwt, verify_invalid_params), ATCA_JWT_TEST_DEVICES}, +#endif +#if TEST_JWT_SIGN_EN { REGISTER_TEST_CASE(atca_jwt, finalize_invalid_params), ATCA_JWT_TEST_DEVICES}, +#endif +#if TEST_JWT_VERIFY_EN { REGISTER_TEST_CASE(atca_jwt_crypto, verify), ATCA_JWT_TEST_DEVICES}, { REGISTER_TEST_CASE(atca_jwt_crypto, verify_invalid), ATCA_JWT_TEST_DEVICES}, +#endif +#if TEST_JWT_SIGN_EN { REGISTER_TEST_CASE(atca_jwt_crypto, finalize), ATCA_JWT_TEST_DEVICES}, - +#endif { (fp_test_case)NULL, (uint8_t)0 }, /* Array Termination element*/ }; -// *INDENT-ON* \ No newline at end of file +// *INDENT-ON* + +static t_test_case_info* jwt_tests[] = { + jwt_unit_test_info, + /* Array Termination element*/ + (t_test_case_info*)NULL +}; + +static void jwt_test_runner(void) +{ + RunAllTests(jwt_tests); +} + +/* Console function */ +int run_jwt_tests(int argc, char* argv[]) +{ + return run_test(argc, argv, jwt_test_runner); +} diff --git a/test/jwt/test_jwt.h b/test/jwt/test_jwt.h new file mode 100644 index 000000000..7ee140bf9 --- /dev/null +++ b/test/jwt/test_jwt.h @@ -0,0 +1,44 @@ +/** + * \file + * \brief Test CryptoAuthLib JWT Implementation + * + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#ifndef TEST_JWT_H +#define TEST_JWT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "atca_test.h" + +/* Console function */ +int run_jwt_tests(int argc, char* argv[]); + +#ifdef __cplusplus +} +#endif + +#endif /* TEST_JWT_H */ diff --git a/test/tng/tng_atcacert_client_test.c b/test/tng/tng_atcacert_client_test.c index 615da7758..10a489adb 100644 --- a/test/tng/tng_atcacert_client_test.c +++ b/test/tng/tng_atcacert_client_test.c @@ -113,7 +113,6 @@ TEST(tng_atcacert_client, tng_atcacert_read_signer_cert) uint8_t ca_public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t tbs_digest[ATCA_SHA2_256_DIGEST_SIZE]; uint8_t signature[ATCA_ECCP256_SIG_SIZE]; - bool is_verified = false; ret = tng_atcacert_max_signer_cert_size(&cert_size); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); @@ -142,9 +141,24 @@ TEST(tng_atcacert_client, tng_atcacert_read_signer_cert) signature); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); +#if ATCA_HOSTLIB_EN + atcac_pk_ctx pkey_ctx; + ret = atcac_pk_init(&pkey_ctx, ca_public_key, sizeof(ca_public_key), 0, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + ret = atcac_pk_verify(&pkey_ctx, tbs_digest, sizeof(tbs_digest), signature, sizeof(signature)); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result */ + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); +#elif CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN + bool is_verified = false; ret = atcab_verify_extern(tbs_digest, signature, ca_public_key, &is_verified); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); TEST_ASSERT(is_verified); +#endif } TEST(tng_atcacert_client, tng_atcacert_signer_public_key_no_cert) @@ -224,7 +238,6 @@ TEST(tng_atcacert_client, tng_atcacert_read_device_cert_no_signer) uint8_t ca_public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t tbs_digest[ATCA_SHA2_256_DIGEST_SIZE]; uint8_t signature[ATCA_ECCP256_SIG_SIZE]; - bool is_verified = false; ret = tng_atcacert_max_device_cert_size(&cert_size); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); @@ -253,9 +266,24 @@ TEST(tng_atcacert_client, tng_atcacert_read_device_cert_no_signer) signature); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); +#if ATCA_HOSTLIB_EN + atcac_pk_ctx pkey_ctx; + ret = atcac_pk_init(&pkey_ctx, ca_public_key, sizeof(ca_public_key), 0, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + ret = atcac_pk_verify(&pkey_ctx, tbs_digest, sizeof(tbs_digest), signature, sizeof(signature)); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result */ + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); +#elif CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN + bool is_verified = false; ret = atcab_verify_extern(tbs_digest, signature, ca_public_key, &is_verified); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); TEST_ASSERT(is_verified); +#endif } TEST(tng_atcacert_client, tng_atcacert_read_device_cert_signer) @@ -269,7 +297,6 @@ TEST(tng_atcacert_client, tng_atcacert_read_device_cert_signer) uint8_t ca_public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t tbs_digest[ATCA_SHA2_256_DIGEST_SIZE]; uint8_t signature[ATCA_ECCP256_SIG_SIZE]; - bool is_verified = false; ret = tng_atcacert_max_signer_cert_size(&signer_cert_size); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); @@ -305,9 +332,24 @@ TEST(tng_atcacert_client, tng_atcacert_read_device_cert_signer) signature); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); +#if ATCA_HOSTLIB_EN + atcac_pk_ctx pkey_ctx; + ret = atcac_pk_init(&pkey_ctx, ca_public_key, sizeof(ca_public_key), 0, true); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + ret = atcac_pk_verify(&pkey_ctx, tbs_digest, sizeof(tbs_digest), signature, sizeof(signature)); + + /* Make sure to free the key before testing the result of the verify */ + atcac_pk_free(&pkey_ctx); + + /* Check verification result */ + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); +#elif CALIB_VERIFY_EXTERN_EN || TALIB_VERIFY_EXTERN_EN + bool is_verified = false; ret = atcab_verify_extern(tbs_digest, signature, ca_public_key, &is_verified); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); TEST_ASSERT(is_verified); +#endif } TEST(tng_atcacert_client, tng_atcacert_device_public_key_no_cert) diff --git a/test/vectors/pbkdf2_sha256_vectors.c b/test/vectors/pbkdf2_sha256_vectors.c index a36976c14..3f67d1cbb 100644 --- a/test/vectors/pbkdf2_sha256_vectors.c +++ b/test/vectors/pbkdf2_sha256_vectors.c @@ -120,3 +120,4 @@ const pbkdf2_sha256_fixed_size_test_vector pbkdf2_sha256_fixed_size_test_vectors }; const size_t pbkdf2_sha256_fixed_size_test_vectors_count = sizeof(pbkdf2_sha256_fixed_size_test_vectors) / sizeof(pbkdf2_sha256_fixed_size_test_vector); + diff --git a/test/vectors/pkcs7_pad_vectors.c b/test/vectors/pkcs7_pad_vectors.c new file mode 100644 index 000000000..efc1706d2 --- /dev/null +++ b/test/vectors/pkcs7_pad_vectors.c @@ -0,0 +1,75 @@ +/** + * \file + * \brief Embedded vectors for PKCS7 Padding + */ + +#include "cryptoauthlib.h" +#include "pkcs7_pad_vectors.h" + +const pkcs7_pad_test_vector pkcs7_pad_test_vectors[] = { + { + "FFFFFF", + "FFFFFF0D0D0D0D0D0D0D0D0D0D0D0D0D", + 16 + }, + { + "FFFFFFFF", + "FFFFFFFF1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C1C", + 32, + }, + { + "FFFFFFFFFFFF", + "FFFFFFFFFFFF3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A3A", + 64 + }, + { + "FFFFFFFFFFFFFFFF", + "FFFFFFFFFFFFFFFF0808080808080808", + 8 + }, + { + "FFFFFFFFFFFFFFFFFF", + "FFFFFFFFFFFFFFFFFF07070707070707", + 8 + }, + { + "82", + "8207070707070707", + 8 + } +}; +const size_t pkcs7_pad_test_vectors_count = sizeof(pkcs7_pad_test_vectors) / sizeof(pkcs7_pad_test_vectors[0]); + +const pkcs7_pad_test_vector pkcs7_unpad_test_vectors[] = { + { + "FFFFFFFFFFFFFFFFFF07070706070707", + NULL, + 8 + }, + { + "FFFFFFFFFFFFFFFFFFFF070707070707", + NULL, + 8 + }, + { + "82040404", + NULL, + 4 + }, + { + "82050505", + NULL, + 4 + }, + { + "820606060606", + NULL, + 6 + }, + { + "8208080808080808", + NULL, + 8 + } +}; +const size_t pkcs7_unpad_test_vectors_count = sizeof(pkcs7_unpad_test_vectors) / sizeof(pkcs7_unpad_test_vectors[0]); diff --git a/test/vectors/pkcs7_pad_vectors.h b/test/vectors/pkcs7_pad_vectors.h new file mode 100644 index 000000000..d7003018b --- /dev/null +++ b/test/vectors/pkcs7_pad_vectors.h @@ -0,0 +1,21 @@ +/** + * \file + * \brief Embedded vectors for the PKCS7 padding algorithm + */ + +#ifndef PKCS7_PAD_VECTORS_H +#define PKCS7_PAD_VECTORS_H + +typedef struct +{ + const char * in; + const char * out; + uint8_t blocksize; +} pkcs7_pad_test_vector; + +extern const pkcs7_pad_test_vector pkcs7_pad_test_vectors[]; +extern const pkcs7_pad_test_vector pkcs7_unpad_test_vectors[]; +extern const size_t pkcs7_pad_test_vectors_count; +extern const size_t pkcs7_unpad_test_vectors_count; + +#endif /* PKCS7_PAD_VECTORS_H */ diff --git a/test/wpc/wpc_apis_test.c b/test/wpc/wpc_apis_test.c new file mode 100644 index 000000000..794fa5c1b --- /dev/null +++ b/test/wpc/wpc_apis_test.c @@ -0,0 +1,141 @@ +/** + * \file + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "third_party/unity/unity_fixture.h" +#include "atca_test.h" +#include "app/wpc/wpc_apis.h" +#include "app/wpc/zcust_def_1_signer.h" +#include "app/wpc/zcust_def_2_device.h" +#include "atcacert/atcacert_def.h" + +TEST_GROUP(wpc_apis); + +TEST_SETUP(wpc_apis) +{ + atcab_init(gCfg); + test_assert_data_is_locked(); +} + +TEST_TEAR_DOWN(wpc_apis) +{ + atcab_release(); +} + +TEST(wpc_apis, wpc_get_digests_request_response) +{ + int ret; + uint8_t request[2]; + uint8_t response[35]; + char displaystr[128]; + uint16_t buflen; + size_t displaylen; + ATCADevice device = atcab_get_device(); + + + /* Read the chain digest manually first */ + + buflen = sizeof(request); + ret = wpc_msg_get_digests(request, &buflen, 0x01); + TEST_ASSERT_SUCCESS(ret); + + displaylen = sizeof(displaystr); + atcab_bin2hex(request, sizeof(request), displaystr, &displaylen); + printf("Digests request: \r\n%s\r\n", displaystr); + + buflen = sizeof(response); + ret = wpc_msg_digests(device, response, &buflen, request); + TEST_ASSERT_SUCCESS(ret); + + displaylen = sizeof(displaystr); + atcab_bin2hex(response, sizeof(response), displaystr, &displaylen); + printf("Digests response: \r\n%s\r\n", displaystr); +} + +TEST(wpc_apis, wpc_get_certificate_request_response) +{ + int ret; + uint8_t request[2]; + uint8_t response[1024]; + uint8_t buffer[512]; + uint16_t buflen; + ATCADevice device = atcab_get_device(); + + /* Load the chain digest manually */ + + /* Request the full cert chain */ + buflen = sizeof(request); + ret = wpc_msg_get_certificate(request, &buflen, 0, 0, 0); + TEST_ASSERT_SUCCESS(ret); + + buflen = sizeof(response); + ret = wpc_msg_certificate(device, response, &buflen, request, buffer, (uint16_t)sizeof(buffer)); + TEST_ASSERT_SUCCESS(ret); + + /* Verify the chain digest matches */ + + /* Verify the certificate chain is correct */ +} + +TEST(wpc_apis, wpc_challenge_request_response) +{ + int ret; + uint8_t request[2+16]; + uint8_t response[3+32+32]; + uint16_t buflen; + char displaystr[256]; + size_t displaylen; + ATCADevice device = atcab_get_device(); + + /* Read the public key from the device manually */ + + /* Generate a challenge message */ + buflen = sizeof(request); + ret = wpc_msg_challenge(device, request, &buflen, 0); + TEST_ASSERT_SUCCESS(ret); + + displaylen = sizeof(displaystr); + atcab_bin2hex(request, sizeof(request), displaystr, &displaylen); + printf("Challenge request: \r\n%s\r\n", displaystr); + + buflen = sizeof(response); + ret = wpc_msg_challenge_auth(device, response, &buflen, request); + TEST_ASSERT_SUCCESS(ret); + + displaylen = sizeof(displaystr); + atcab_bin2hex(response, sizeof(response), displaystr, &displaylen); + printf("Challenge auth response: \r\n%s\r\n", displaystr); + + /* Verify the challenge response */ +} + +// *INDENT-OFF* - Preserve formatting +t_test_case_info wpc_apis_unit_test_info[] = +{ + { REGISTER_TEST_CASE(wpc_apis, wpc_get_digests_request_response), DEVICE_MASK(ATECC608)}, + { REGISTER_TEST_CASE(wpc_apis, wpc_get_certificate_request_response), DEVICE_MASK(ATECC608)}, + { REGISTER_TEST_CASE(wpc_apis, wpc_challenge_request_response), DEVICE_MASK(ATECC608)}, + { (fp_test_case)NULL, (uint8_t)0 }, +}; +// *INDENT-ON* diff --git a/test/wpc/wpccert_client_test.c b/test/wpc/wpccert_client_test.c new file mode 100644 index 000000000..53b39a46b --- /dev/null +++ b/test/wpc/wpccert_client_test.c @@ -0,0 +1,192 @@ +/** + * \file + * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. + * + * \page License + * + * Subject to your compliance with these terms, you may use Microchip software + * and any derivatives exclusively with Microchip products. It is your + * responsibility to comply with third party license terms applicable to your + * use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER + * EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED + * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, + * SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE + * OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE + * FORESEEABLE. TO THE FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL + * LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED + * THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR + * THIS SOFTWARE. + */ + +#include "third_party/unity/unity_fixture.h" +#include "atca_test.h" +#include "app/wpc/wpccert_client.h" +#include "app/wpc/zcust_def_1_signer.h" +#include "app/wpc/zcust_def_2_device.h" +#include "atcacert/atcacert_def.h" + +TEST_GROUP(wpccert_client); + +TEST_SETUP(wpccert_client) +{ + atcab_init(gCfg); + test_assert_data_is_locked(); +} + +TEST_TEAR_DOWN(wpccert_client) +{ + atcab_release(); +} + +TEST(wpccert_client, wpccert_read_mfg_cert) +{ + int ret; + uint8_t cert[512]; + size_t cert_size = 0; + ATCADevice device = atcab_get_device(); + + ret = wpccert_read_mfg_cert(device, cert, &cert_size, 0); + TEST_ASSERT_SUCCESS(ret); +} + +TEST(wpccert_client, wpccert_read_pdu_cert) +{ + int ret; + uint8_t cert[512]; + size_t cert_size = 0; + ATCADevice device = atcab_get_device(); + + ret = wpccert_read_pdu_cert(device, cert, &cert_size, 0); + TEST_ASSERT_SUCCESS(ret); +} + +TEST(wpccert_client, wpccert_mfg_public_key_no_cert) +{ + int ret; + uint8_t cert[512]; + size_t cert_size = 0; + uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; + uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + const atcacert_def_t* cert_def; + ATCADevice device = atcab_get_device(); + + ret = wpccert_get_slot_info(NULL, &cert_def, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_read_mfg_cert(device, cert, &cert_size, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = atcacert_get_subj_public_key( + cert_def, + cert, + cert_size, + cert_public_key); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_public_key(cert_def, public_key, NULL); + TEST_ASSERT_SUCCESS(ret); + TEST_ASSERT_EQUAL_MEMORY(cert_public_key, public_key, sizeof(public_key)); +} + +TEST(wpccert_client, wpccert_mfg_public_key_cert) +{ + int ret; + uint8_t cert[512]; + size_t cert_size = 0; + uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; + uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + const atcacert_def_t* cert_def; + ATCADevice device = atcab_get_device(); + + ret = wpccert_get_slot_info(NULL, &cert_def, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_read_mfg_cert(device, cert, &cert_size, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = atcacert_get_subj_public_key( + cert_def->ca_cert_def, + cert, + cert_size, + cert_public_key); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_public_key(cert_def, public_key, cert); + TEST_ASSERT_SUCCESS(ret); + TEST_ASSERT_EQUAL_MEMORY(cert_public_key, public_key, sizeof(public_key)); +} + + +TEST(wpccert_client, wpccert_pdu_public_key_no_cert) +{ + int ret; + uint8_t cert[512]; + size_t cert_size = 0; + uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; + uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + const atcacert_def_t* cert_def; + ATCADevice device = atcab_get_device(); + + ret = wpccert_get_slot_info(NULL, &cert_def, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_read_pdu_cert(device, cert, &cert_size, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = atcacert_get_subj_public_key( + cert_def, + cert, + cert_size, + cert_public_key); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_public_key(cert_def, public_key, NULL); + TEST_ASSERT_SUCCESS(ret); + TEST_ASSERT_EQUAL_MEMORY(cert_public_key, public_key, sizeof(public_key)); +} + +TEST(wpccert_client, wpccert_pdu_public_key_cert) +{ + int ret; + uint8_t cert[512]; + size_t cert_size = 0; + uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; + uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + const atcacert_def_t* cert_def; + ATCADevice device = atcab_get_device(); + + ret = wpccert_get_slot_info(NULL, &cert_def, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_read_pdu_cert(device, cert, &cert_size, 0); + TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); + + ret = atcacert_get_subj_public_key( + cert_def, + cert, + cert_size, + cert_public_key); + TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); + + ret = wpccert_public_key(cert_def, public_key, cert); + TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); + TEST_ASSERT_EQUAL_MEMORY(cert_public_key, public_key, sizeof(public_key)); +} + +// *INDENT-OFF* - Preserve formatting +t_test_case_info wpccert_client_unit_test_info[] = +{ + { REGISTER_TEST_CASE(wpccert_client, wpccert_read_mfg_cert), DEVICE_MASK(ATECC608)}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_read_pdu_cert), DEVICE_MASK(ATECC608)}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_mfg_public_key_no_cert), DEVICE_MASK(ATECC608)}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_mfg_public_key_cert), DEVICE_MASK(ATECC608)}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_pdu_public_key_no_cert), DEVICE_MASK(ATECC608)}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_pdu_public_key_cert), DEVICE_MASK(ATECC608)}, + { (fp_test_case)NULL, (uint8_t)0 }, +}; +// *INDENT-ON* diff --git a/third_party/unity/unity_fixture.c b/third_party/unity/unity_fixture.c index c3dda7963..7c4991a98 100644 --- a/third_party/unity/unity_fixture.c +++ b/third_party/unity/unity_fixture.c @@ -55,12 +55,12 @@ static int selected(const char* filter, const char* name) static int testSelected(const char* test) { - return selected(UnityFixture.NameFilter, test); + return UnityFixture.NameInvert ^ selected(UnityFixture.NameFilter, test); } static int groupSelected(const char* group) { - return selected(UnityFixture.GroupFilter, group); + return UnityFixture.GroupInvert ^ selected(UnityFixture.GroupFilter, group); } void UnityTestRunner(unityfunction* setup, @@ -209,8 +209,12 @@ int UnityGetCommandLineOptions(int argc, const char* argv[]) UNITY_PRINT_EOL(); UnityPrint(" -g NAME Only run tests in groups that contain the string NAME"); UNITY_PRINT_EOL(); + UnityPrint(" -G NAME Only run tests in groups that do not contain the string NAME"); + UNITY_PRINT_EOL(); UnityPrint(" -n NAME Only run tests whose name contains the string NAME"); UNITY_PRINT_EOL(); + UnityPrint(" -N NAME Only run tests whose name does not contain the string NAME"); + UNITY_PRINT_EOL(); UnityPrint(" -r NUMBER Repeatedly run all tests NUMBER times"); UNITY_PRINT_EOL(); UnityPrint(" -h, --help Display this help message"); @@ -245,6 +249,15 @@ int UnityGetCommandLineOptions(int argc, const char* argv[]) UnityFixture.GroupFilter = argv[i]; i++; } + else if (strcmp(argv[i], "-G") == 0) + { + i++; + if (i >= argc) + return 1; + UnityFixture.GroupFilter = argv[i]; + UnityFixture.GroupInvert = 1; + i++; + } else if (strcmp(argv[i], "-n") == 0) { i++; @@ -253,6 +266,15 @@ int UnityGetCommandLineOptions(int argc, const char* argv[]) UnityFixture.NameFilter = argv[i]; i++; } + else if (strcmp(argv[i], "-N") == 0) + { + i++; + if (i >= argc) + return 1; + UnityFixture.NameFilter = argv[i]; + UnityFixture.NameInvert = 1; + i++; + } else if (strcmp(argv[i], "-r") == 0) { UnityFixture.RepeatCount = 2; @@ -286,22 +308,25 @@ void UnityConcludeFixtureTest(void) if (Unity.CurrentTestIgnored) { Unity.TestIgnores++; - UNITY_PRINT_EOL(); } - else if (!Unity.CurrentTestFailed) + else if (Unity.CurrentTestFailed) { - if (UnityFixture.Verbose) + Unity.TestFailures++; + } + else if (UnityFixture.Verbose) { UnityPrint(" "); UnityPrint(UnityStrPass); + } + + if (UnityFixture.Verbose) + { UNITY_EXEC_TIME_STOP(); UNITY_PRINT_EXEC_TIME(); UNITY_PRINT_EOL(); } - } - else /* Unity.CurrentTestFailed */ + else if (Unity.CurrentTestIgnored || Unity.CurrentTestFailed) { - Unity.TestFailures++; UNITY_PRINT_EOL(); } diff --git a/third_party/unity/unity_fixture_internals.h b/third_party/unity/unity_fixture_internals.h index 1c51aa986..37fb93e7c 100644 --- a/third_party/unity/unity_fixture_internals.h +++ b/third_party/unity/unity_fixture_internals.h @@ -19,7 +19,9 @@ struct UNITY_FIXTURE_T int Silent; unsigned int RepeatCount; const char* NameFilter; + int NameInvert; const char* GroupFilter; + int GroupInvert; }; extern struct UNITY_FIXTURE_T UnityFixture;