diff --git a/CMakeLists.txt b/CMakeLists.txt index 49d9553c7..d3ff33f75 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 3.1.0) project (cryptoauthlib C) # Set the current release version -set(VERSION "3.7.5") +set(VERSION "3.7.6") set(VERSION_MAJOR 3) set(VERSION_MINOR 7) -set(VERSION_PATCH 5) +set(VERSION_PATCH 6) # Build Options option(BUILD_TESTS "Create Test Application with library" OFF) diff --git a/README.md b/README.md index 1a8a51618..45a21f919 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Directory Structure lib - primary library source code lib/atcacert - certificate data and i/o methods lib/calib - the Basic Cryptoauth API -lib/crypto - Software crypto implementations external crypto libraries support (primarily SHA1 and SHA256) +lib/crypto - Software crypto implementations external crypto libraries support (primarily SHA1 and SHA2) lib/hal - hardware abstraction layer code for supporting specific platforms lib/host - support functions for common host-side calculations lib/jwt - json web token functions diff --git a/app/kit_host/ascii_kit_host.c b/app/kit_host/ascii_kit_host.c index d4220918a..b1a2cb7a9 100644 --- a/app/kit_host/ascii_kit_host.c +++ b/app/kit_host/ascii_kit_host.c @@ -281,7 +281,11 @@ static ATCA_STATUS kit_host_ca_talk(ascii_kit_host_context_t* ctx, int argc, cha if (ctx && argc && response && rlen) { +#ifdef __XC8 + static ATCAPacket packet; +#else ATCAPacket packet; +#endif size_t plen = sizeof(packet) - 2; atcab_hex2bin(argv[0], strlen(argv[0]), (uint8_t*)&packet.txsize, &plen); @@ -293,6 +297,9 @@ static ATCA_STATUS kit_host_ca_talk(ascii_kit_host_context_t* ctx, int argc, cha { *rlen = kit_host_format_response(response, *rlen, status, NULL, 0); } +#ifdef __XC8 + (void)memset(&packet, 0, sizeof(ATCAPacket)); +#endif } return status; } diff --git a/app/pkcs11/trust_pkcs11_config.c b/app/pkcs11/trust_pkcs11_config.c index b4e49af37..68a3b2d7d 100644 --- a/app/pkcs11/trust_pkcs11_config.c +++ b/app/pkcs11/trust_pkcs11_config.c @@ -167,7 +167,7 @@ CK_RV pkcs11_trust_load_objects(pkcs11_slot_ctx_ptr pSlot) if (NULL == pSlot) { - rv = CKR_ARGUMENTS_BAD; + return CKR_ARGUMENTS_BAD; } if (CKR_OK == rv) diff --git a/app/tng/tng_atcacert_client.c b/app/tng/tng_atcacert_client.c index ee9da5bc4..34bb654df 100644 --- a/app/tng/tng_atcacert_client.c +++ b/app/tng/tng_atcacert_client.c @@ -74,6 +74,7 @@ int tng_atcacert_read_device_cert(uint8_t* cert, size_t* cert_size, const uint8_ int ret; const atcacert_def_t* cert_def = NULL; uint8_t ca_public_key[72]; + cal_buffer ca_pubkey = CAL_BUF_INIT(ATCA_ECCP256_PUBKEY_SIZE, ca_public_key); ret = tng_get_device_cert_def(&cert_def); if (ret != ATCA_SUCCESS) @@ -88,7 +89,7 @@ int tng_atcacert_read_device_cert(uint8_t* cert, size_t* cert_size, const uint8_ cert_def->ca_cert_def, signer_cert, cert_def->ca_cert_def->cert_template_size, // Cert size doesn't need to be accurate - ca_public_key); + &ca_pubkey); if (ret != ATCACERT_E_SUCCESS) { return ret; @@ -179,6 +180,7 @@ int tng_atcacert_signer_public_key(uint8_t* public_key, uint8_t* cert) int ret; const atcacert_def_t* cert_def = NULL; uint8_t raw_public_key[72]; + cal_buffer pubkey = CAL_BUF_INIT(ATCA_ECCP256_PUBKEY_SIZE, public_key); if (public_key == NULL) { @@ -192,7 +194,7 @@ int tng_atcacert_signer_public_key(uint8_t* public_key, uint8_t* cert) &g_tngtls_cert_def_1_signer, cert, g_tngtls_cert_def_1_signer.cert_template_size, // cert size doesn't need to be accurate - public_key); + &pubkey); } else { diff --git a/app/wpc/atca_config.h b/app/wpc/atca_config.h deleted file mode 100644 index a22b72fd3..000000000 --- a/app/wpc/atca_config.h +++ /dev/null @@ -1,140 +0,0 @@ -/* 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_DELETE_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 index ca9045f12..eebaa2c67 100644 --- a/app/wpc/wpc_apis.c +++ b/app/wpc/wpc_apis.c @@ -31,6 +31,9 @@ #include "atcacert/atcacert_client.h" #if WPC_MSG_PR_EN + +#define CA2_TRANSPORT_KEY 0x8000 + /** \brief WPC API - Builds the CHALLENGE message * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -42,8 +45,8 @@ ATCA_STATUS wpc_msg_challenge( const uint8_t slot /**< [in] Slot number */ ) { - ATCA_STATUS status; - uint8_t nonce[32]; + ATCA_STATUS status = ATCA_BAD_PARAM; + uint8_t nonce[32] = {0U}; ATCA_CHECK_INVALID_MSG((!message || !msg_len), ATCA_BAD_PARAM, "NULL pointer received"); @@ -58,7 +61,19 @@ ATCA_STATUS wpc_msg_challenge( else #endif { - status = ATCA_TRACE(atcab_random_ext(device, nonce), "atcab_random failed"); + if(true == atcab_is_ca2_device(atcab_get_device_type_ext(device))) + { +#if ATCA_CA2_SUPPORT + uint8_t num_in[20] = {0u}; + status = ATCA_TRACE(calib_nonce_gen_session_key(device, CA2_TRANSPORT_KEY, num_in ,nonce), "atcab_nonce_rand failed"); +#endif + } + else + { +#if ATCA_ECC_SUPPORT + status = ATCA_TRACE(atcab_random_ext(device, nonce), "atcab_random failed"); +#endif + } } if (ATCA_SUCCESS == status) @@ -166,11 +181,17 @@ ATCA_STATUS wpc_msg_challenge_auth( 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))) + if (ATCA_SUCCESS != (status = wpccert_get_slot_info(&handle, &cert_def, NULL, NULL, slot))) { return wpc_msg_error(response, resp_len, WPC_ERROR_INVALID_REQUEST, 0); } + if(NULL == cert_def) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received for cert def"); + return status; + } + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, ATCA_ZONE_DATA, handle, 0, chain_digest, sizeof(chain_digest)))) { @@ -217,7 +238,7 @@ ATCA_STATUS wpc_msg_digests( uint8_t slot_mask = (1 << slot); if (request[1] & slot_mask) { - if (ATCA_SUCCESS == wpccert_get_slot_info(&handle, NULL, slot)) + if (ATCA_SUCCESS == wpccert_get_slot_info(&handle, NULL, NULL, NULL, slot)) { if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, ATCA_ZONE_DATA, handle, 0, digest, ATCA_SHA256_DIGEST_SIZE))) @@ -267,15 +288,23 @@ ATCA_STATUS wpc_msg_certificate( uint16_t length; uint8_t * data; const atcacert_def_t * cert_def; + uint8_t* mfg_cert; + uint8_t root_digest[32] = {0}; 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))) + if (ATCA_SUCCESS != (status = wpccert_get_slot_info(NULL, &cert_def, &mfg_cert, root_digest, request[1] & 0x03))) { return wpc_msg_error(response, resp_len, WPC_ERROR_INVALID_REQUEST, 0); } + if(NULL == cert_def) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL pointer received for Product cert def"); + return status; + } + offset = (((uint16_t)(request[1] & 0xE0)) << 8) | request[2]; length = (((uint16_t)(request[1] & 0x1C)) << 8) | request[3]; @@ -284,21 +313,28 @@ ATCA_STATUS wpc_msg_certificate( 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))) + if ((NULL != mfg_cert) && (NULL == cert_def->ca_cert_def)) + { + n_mc = (size_t)((mfg_cert[2] << 8) | mfg_cert[3]) + 4u; + } + else { - status = ATCA_TRACE(status, "atcacert_read_cert_size execution is failed for mfg cert"); - return status; + /* Get the manufacturer certificate length */ + if (ATCA_SUCCESS != (status = wpccert_read_cert_size(device, 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))) + if(ATCA_SUCCESS != wpccert_read_cert_size(device, cert_def, &n_puc)) { - status = ATCA_TRACE(status, "atcacert_read_cert_size execution is failed for pdu cert"); - return status; + status = ATCA_TRACE(status, "wpccert_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"); @@ -335,31 +371,45 @@ ATCA_STATUS wpc_msg_certificate( { *data++ = ((chain_length >> 8) & 0xFF); length--; + offset += 1u; } *data++ = (chain_length & 0xFF); length--; + offset += 1u; } /* 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); + + memcpy(data, root_digest, rh_length); data += rh_length; length -= rh_length; + offset += rh_length; } /* Read the manufacturer certificate */ - if ((offset > WPC_CONST_OS_MC) && (offset < (WPC_CONST_OS_MC + n_mc))) + 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))) + + if((NULL != mfg_cert) && (NULL == cert_def->ca_cert_def)) { - return ATCA_TRACE(status, "wpccert_read_cert execution is failed for mfg cert"); + memcpy(buffer, mfg_cert, mc_length); } + else + { + 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; + offset += mc_length; } } else diff --git a/app/wpc/wpc_check_config.h b/app/wpc/wpc_check_config.h index bc91d03ef..3cb4a1e2c 100644 --- a/app/wpc/wpc_check_config.h +++ b/app/wpc/wpc_check_config.h @@ -3,6 +3,7 @@ /* Pick up the global configuration and library checks */ #include "cryptoauthlib.h" +#include "wpc_config.h" /* WPC "Slot" Configuration follows the WPC nomenclature where a slot is defined as a certificate chain which also has a uniquely defined format @@ -12,9 +13,14 @@ WPC_CHAIN_CERT_DEF_ WPC_CHAIN_ROOT_DIGEST_ + Configuring a chain for cryptoauth2 parts: + WPC_CHAIN_DIGEST_HANDLE_ + WPC_CHAIN_CERT_DEF_ + WPC_CHAIN_ROOT_DIGEST_ + WPC_CHAIN_MFG_CERT_ + Configuring a chain for trust anchor parts: WPC_CHAIN_DIGEST_HANDLE_ - WPC_CHAIN_HANDLE_ WPC_CHAIN_ROOT_DIGEST_ */ @@ -43,47 +49,44 @@ /* 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 + #if ATCA_ECC_SUPPORT + #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 + #else if ATCA_CA2_SUPPORT + #if !(defined(WPC_CHAIN_DIGEST_HANDLE_0) || defined(WPC_CHAIN_CERT_DEF_0) || defined(WPC_CHAIN_ROOT_DIGEST_0) || defined(WPC_CHAIN_MFG_CERT_0)) + #define WPC_CHAIN_DIGEST_HANDLE_0 0x02 + #define WPC_CHAIN_CERT_DEF_0 g_cert_def_3_device + #define WPC_CHAIN_ROOT_DIGEST_0 g_cert_def_3_root_digest + #define WPC_CHAIN_MFG_CERT_0 g_cert_def_3_signer + #endif + #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 +#if ATCA_ECC_SUPPORT && (ATCA_CA2_SUPPORT || ATCA_TA_SUPPORT) +#error "This WPC reference application is designed to work with only one of the cryptoauth, cryproauth2 or trust anchor device enabled" +#elif (ATCA_CA2_SUPPORT && (ATCA_ECC_SUPPORT || ATCA_TA_SUPPORT)) +#error "This WPC reference application is designed to work with only one of the cryptoauth, cryproauth2 or trust anchor device enabled" #endif /* Chain 0 must always be defined per the WPC */ -#if !(defined(WPC_CHAIN_HANDLE_0) || defined(WPC_CHAIN_CERT_DEF_0)) +#if !(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)) +#if (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)) +#if (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)) +#if (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)) +#if (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 diff --git a/app/wpc/wpc_config.h b/app/wpc/wpc_config.h new file mode 100644 index 000000000..935a0e52c --- /dev/null +++ b/app/wpc/wpc_config.h @@ -0,0 +1,33 @@ +#ifndef WPC_CONFIG_H +#define WPC_CONFIG_H + + + +#if ATCA_ECC_SUPPORT + /* WPC Configuration */ + #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 +#elif ATCA_CA2_SUPPORT + /* WPC Configuration */ + #define WPC_CHAIN_DIGEST_HANDLE_0 0x02 + #define WPC_CHAIN_CERT_DEF_0 g_cert_def_3_device + #define WPC_CHAIN_ROOT_DIGEST_0 g_cert_def_3_root_digest + #define WPC_CHAIN_MFG_CERT_0 g_cert_def_3_signer +#endif + +/* 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 + +#endif \ No newline at end of file diff --git a/app/wpc/wpccert_client.c b/app/wpc/wpccert_client.c index d51413369..94219b92c 100644 --- a/app/wpc/wpccert_client.c +++ b/app/wpc/wpccert_client.c @@ -67,20 +67,48 @@ extern const uint8_t WPC_CHAIN_ROOT_DIGEST_2[]; extern const uint8_t WPC_CHAIN_ROOT_DIGEST_3[]; #endif + +#if ATCA_CA2_SUPPORT +#ifdef WPC_CHAIN_MFG_CERT_0 +extern const uint8_t WPC_CHAIN_MFG_CERT_0[]; +#endif + +#ifdef WPC_CHAIN_MFG_CERT_1 +extern const uint8_t WPC_CHAIN_MFG_CERT_1[]; +#endif + +#ifdef WPC_CHAIN_MFG_CERT_2 +extern const uint8_t WPC_CHAIN_MFG_CERT_2[]; +#endif + +#ifdef WPC_CHAIN_MFG_CERT_3 +extern const uint8_t WPC_CHAIN_MFG_CERT_3[]; +#endif +#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; + uint16_t handle; // Chain digest Handle + const uint8_t* root; // Root digest + uint8_t* mfg; // Manufacturer certificate + const atcacert_def_t* def; // Cert 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 } +#if ATCA_ECC_SUPPORT + #if !WPC_STRICT_SLOT_INDEX_EN + #define WPC_INFO(n) { n, WPC_CHAIN_DIGEST_HANDLE_ ## n, WPC_CHAIN_ROOT_DIGEST_ ## n, NULL, &WPC_CHAIN_CERT_DEF_ ## n } + #else + #define WPC_INFO(n) { WPC_CHAIN_DIGEST_HANDLE_ ## n, WPC_CHAIN_ROOT_DIGEST_ ## n, NULL, &WPC_CHAIN_CERT_DEF_ ## n } + #endif +#elif ATCA_CA2_SUPPORT + #if !WPC_STRICT_SLOT_INDEX_EN + #define WPC_INFO(n) { n, WPC_CHAIN_DIGEST_HANDLE_ ## n, WPC_CHAIN_ROOT_DIGEST_ ## n, WPC_CHAIN_MFG_CERT_ ## n, &WPC_CHAIN_CERT_DEF_ ## n} + #else + #define WPC_INFO(n) { WPC_CHAIN_DIGEST_HANDLE_ ## n, WPC_CHAIN_ROOT_DIGEST_ ## n, WPC_CHAIN_MFG_CERT_ ## n, &WPC_CHAIN_CERT_DEF_ ## n} + #endif #endif static const wpc_slot_info_t wpc_slot_info[] = { @@ -121,9 +149,11 @@ uint8_t wpccert_get_slots_populated(void) } 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 */ + uint16_t * handle, /**< [out] Digest handle */ + const atcacert_def_t** def, /**< [out] Chain definition (device) */ + uint8_t** mfg, /**< [out] Manufacture cert */ + uint8_t * root_dgst, /**< [out] Root digest */ + uint8_t slot /**< [in] Chain slot number */ ) { #if WPC_STRICT_SLOT_INDEX_EN @@ -136,6 +166,14 @@ ATCA_STATUS wpccert_get_slot_info( { *def = wpc_slot_info[slot].def; } + if (mfg) + { + *mfg = wpc_slot_info[slot].mfg; + } + if(root_dgst) + { + *root_dgst = wpc_slot_info[slot].root + } return ATCA_SUCCESS; #else uint8_t i; @@ -151,6 +189,14 @@ ATCA_STATUS wpccert_get_slot_info( { *def = wpc_slot_info[i].def; } + if(mfg) + { + *mfg = wpc_slot_info[i].mfg; + } + if(root_dgst) + { + *root_dgst = wpc_slot_info[slot].root; + } return ATCA_SUCCESS; } } @@ -159,6 +205,64 @@ ATCA_STATUS wpccert_get_slot_info( } #endif +ATCA_STATUS wpccert_read_cert_size(ATCADevice device, + const atcacert_def_t* cert_def, + size_t* cert_size) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if ((NULL == cert_def) || (NULL == cert_size)) + { + return ATCA_BAD_PARAM; + } + + if (CERTTYPE_X509_FULL_STORED == cert_def->type) + { + uint8_t cert_hdr[4u] = { 0x00 }; + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, (uint8_t)cert_def->comp_cert_dev_loc.zone, + cert_def->comp_cert_dev_loc.slot, 0u, cert_hdr, sizeof(cert_hdr)))) + { + status = ATCA_TRACE(status, "atcab_read_bytes_zone_ext execution is failed for wpccert_read_cert_size"); + return status; + } + + *cert_size = (size_t)((cert_hdr[2] << 8) | cert_hdr[3]) + 4u; + } + else + { +#if ATCACERT_COMPCERT_EN + uint8_t buffer[75]; + size_t buflen = sizeof(buffer); + size_t max_cert_size; + atcacert_device_loc_t comp_cert_loc = cert_def->comp_cert_dev_loc; + + /* 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; + } +#endif + } + + return status; +} + + /** \brief WPC API - * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -170,147 +274,164 @@ ATCA_STATUS wpccert_read_cert( size_t * cert_size) { ATCA_STATUS status = ATCA_UNIMPLEMENTED; +#if ATCA_ECC_SUPPORT uint8_t subj_public_key[72]; uint8_t buffer[75], enc_dates[3]; size_t buflen = sizeof(buffer); - size_t max_cert_size; + size_t max_cert_size = 0; 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]; - +#endif 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))) + if (CERTTYPE_X509_FULL_STORED == cert_def->type) { - status = ATCA_TRACE(status, "ecdsa signature encode failed"); - return status; - } + if (cert == NULL) + { + return wpccert_read_cert_size(device, cert_def, cert_size); + } - max_cert_size = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset + buflen; - *cert_size = max_cert_size; + if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, (uint8_t)cert_def->comp_cert_dev_loc.zone, + cert_def->comp_cert_dev_loc.slot, 0u, cert, *cert_size))) + { + status = ATCA_TRACE(status, "read cert failed"); + return status; + } - if (*cert_size > cert_def->cert_template_size) - { - *cert_size = cert_def->cert_template_size; + #if ATCACERT_INTEGRATION_EN + cal_buffer buf = CAL_BUF_INIT(*cert_size, cert); + /* Load parsed certificate if not already done */ + if (NULL == *cert_def->parsed) + { + if (ATCACERT_E_SUCCESS != (status = atcac_parse_der(cert_def->parsed, &buf))) + { + return status; + } + } + #endif } + else + { +#if ATCA_ECC_SUPPORT + if(ATCA_SUCCESS != wpccert_read_cert_size(device, cert_def, cert_size)) + { + return status; + } - memcpy(cert, cert_def->cert_template, *cert_size); + memcpy(cert, cert_def->cert_template, *cert_size); + max_cert_size = cert_def->std_cert_elements[STDCERT_SIGNATURE].offset + buflen; - // set comp_cert - if (ATCA_SUCCESS != (status = atcab_read_bytes_zone_ext(device, comp_cert_loc.zone, comp_cert_loc.slot, + // 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; - } + { + status = ATCA_TRACE(status, "read comp cert 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 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; + } - // 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); + 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 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))) + // 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, "read cert sn failed"); + status = ATCA_TRACE(status, "date encoding failed"); return status; } - memcpy(&cert[cert_def->std_cert_elements[STDCERT_CERT_SN].offset], buffer, cert_sn_loc.count); - } + memcpy(&cert[cert_def->std_cert_elements[STDCERT_ISSUE_DATE].offset], formatted_date, formatted_date_size); - // 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_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 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))) + // set subj_public_key + if (ATCA_SUCCESS != (status = wpccert_public_key(cert_def, subj_public_key, NULL))) { - status = ATCA_TRACE(status, "read cert elements failed"); + status = ATCA_TRACE(status, "subj public key read failed"); return status; } - memcpy(&cert[cert_def->cert_elements[i].cert_loc.offset], buffer, cert_def->cert_elements[i].cert_loc.count); - } + // 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]; + 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 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); + // 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; - } + 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); + // 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)); + 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; - } + 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 + 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); + memcpy(&cert[cert_def->std_cert_elements[STDCERT_CERT_SN].offset], sn, cert_def->std_cert_elements[STDCERT_CERT_SN].count); + } +#endif /* WPC_CERT_SN_FROM_HASH */ +#endif /* ATCA_ECC_SUPPORT*/ } -#endif return status; } @@ -335,106 +456,114 @@ ATCA_STATUS wpccert_write_cert(ATCADevice device, const atcacert_def_t* cert_def 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]))) + if (CERTTYPE_X509_FULL_STORED == cert_def->type) { - status = ATCA_TRACE(status, "atcacert_der_dec_ecdsa_sig_value failed"); - return status; + status = atcab_write_bytes_zone_ext(device, (uint8_t)cert_def->comp_cert_dev_loc.zone, + cert_def->comp_cert_dev_loc.slot, 0, cert, cert_size); } - 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))) + else { - status = ATCA_TRACE(status, "date decoding failed"); - return status; - } + // get comp cert + der_sig_size = cert_size - sig_offset; - memset(&temp_buf[64], 0, 3); + 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); - 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)); + 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[67], 0, sizeof(uint16_t)); // no signer_id in cert use 0 + memset(&temp_buf[64], 0, 3); - 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; + 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)); - 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; - } + 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; - // 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))) + comp_cert_loc.zone, + comp_cert_loc.slot, + comp_cert_loc.offset, + temp_buf, comp_cert_loc.count))) { - status = ATCA_TRACE(status, "write cert serial number failed"); + status = ATCA_TRACE(status, "compcert write 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) + // get certificate serial number + if (cert_sn_loc.count != 0) { - status = ATCA_TRACE(status, "public key count not valid"); - return status; // Unexpected public key size + 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 (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))) + if (public_key_loc.is_genkey == 0) { - status = ATCA_TRACE(status, "write subj public key failed"); - return status; + //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))) + //get cert elements + for (uint8_t i = 0; i < cert_def->cert_elements_count; i++) { - status = ATCA_TRACE(status, "write cert elements failed"); - return status; + 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; + } } } @@ -447,7 +576,7 @@ ATCA_STATUS wpccert_read_pdu_cert(ATCADevice device, uint8_t* cert, size_t* cert ATCA_STATUS status; const atcacert_def_t* chain; - if (ATCA_SUCCESS == (status = wpccert_get_slot_info(NULL, &chain, slot))) + if (ATCA_SUCCESS == (status = wpccert_get_slot_info(NULL, &chain, NULL, NULL, slot))) { status = wpccert_read_cert(device, chain, cert, cert_size); } @@ -458,10 +587,31 @@ ATCA_STATUS wpccert_read_mfg_cert(ATCADevice device, uint8_t* cert, size_t* cert { ATCA_STATUS status; const atcacert_def_t* chain; + uint8_t *mfg; - if (ATCA_SUCCESS == (status = wpccert_get_slot_info(NULL, &chain, slot))) + if (ATCA_SUCCESS == (status = wpccert_get_slot_info(NULL, &chain, &mfg , NULL, slot))) { - status = wpccert_read_cert(device, chain->ca_cert_def, cert, cert_size); + if(NULL == chain) + { + status = ATCA_TRACE(ATCA_BAD_PARAM, "NULL Pointer receieved for cert def"); + return status; + } + + if(NULL != chain->ca_cert_def) + { + //! CA device MFG Cert + status = wpccert_read_cert(device, chain->ca_cert_def, cert, cert_size); + } + else if(NULL != mfg) + { + //! CA2 device MFG Cert + memcpy(cert, mfg, *cert_size); + status = ATCA_SUCCESS; + } + else + { + /* Do Nothing */ + } } return status; } @@ -509,12 +659,22 @@ ATCA_STATUS wpccert_public_key(const atcacert_def_t* cert_def, uint8_t* public_k } else { - memcpy(public_key, raw_public_key, 64); + memcpy(public_key, raw_public_key, ATCA_PUB_KEY_SIZE); } } else { - memcpy(public_key, &cert[cert_def->std_cert_elements[STDCERT_PUBLIC_KEY].offset], 64); + if (CERTTYPE_X509_FULL_STORED == cert_def->type) + { +#if ATCACERT_INTEGRATION_EN + cal_buffer pk_buf = CAL_BUF_INIT(ATCA_PUB_KEY_SIZE, public_key); + status = (NULL != cert_def->parsed) ? atcac_get_subj_public_key(*cert_def->parsed, &pk_buf) : ATCACERT_E_ERROR; +#endif + } + else + { + memcpy(public_key, &cert[cert_def->std_cert_elements[STDCERT_PUBLIC_KEY].offset], ATCA_PUB_KEY_SIZE); + } } return ATCA_SUCCESS; diff --git a/app/wpc/wpccert_client.h b/app/wpc/wpccert_client.h index 65f0c1ff1..9db6cfa83 100644 --- a/app/wpc/wpccert_client.h +++ b/app/wpc/wpccert_client.h @@ -39,8 +39,9 @@ extern "C" uint8_t wpccert_get_slots_populated(void); uint8_t wpccert_get_slot_count(void); -ATCA_STATUS wpccert_get_slot_info(uint16_t * dig_handle, const atcacert_def_t** def, uint8_t slot); - +ATCA_STATUS wpccert_get_slot_info(uint16_t * dig_handle, const atcacert_def_t** def, uint8_t** mfg, \ + uint8_t* root_dgst, uint8_t slot); +ATCA_STATUS wpccert_read_cert_size(ATCADevice device, const atcacert_def_t* cert_def, size_t* cert_size); ATCA_STATUS wpccert_read_cert(ATCADevice device, const atcacert_def_t *cert_def, uint8_t *cert, size_t *cert_size); ATCA_STATUS wpccert_write_cert(ATCADevice device, const atcacert_def_t* cert_def, const uint8_t* cert, size_t cert_size); diff --git a/app/wpc/zcust_def_1_signer.c b/app/wpc/zcust_def_1_signer.c index 1bdd577c3..fae764bae 100644 --- a/app/wpc/zcust_def_1_signer.c +++ b/app/wpc/zcust_def_1_signer.c @@ -1,92 +1,92 @@ #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, + 0x3F, 0x5E, 0x70, 0xD7, 0x41, 0x6C, 0xFA, 0x6B, 0xB4, 0xC1, 0x1E, 0x30, 0xF9, 0x7C, 0x61, 0xCC, + 0xA9, 0x01, 0x99, 0x7B, 0x94, 0x56, 0xA8, 0xE6, 0xB7, 0x3E, 0xA0, 0xC1, 0x83, 0xD6, 0xDD, 0xB9, }; -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, +const uint8_t g_template_1_signer[325] = { + 0x30, 0x82, 0x01, 0x41, 0x30, 0x81, 0xe8, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x74, 0x5a, + 0xeb, 0xf8, 0xc5, 0x5d, 0xf8, 0xd3, 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, + 0x50, 0x43, 0x43, 0x41, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x38, 0x30, 0x39, 0x30, + 0x33, 0x33, 0x36, 0x32, 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, + 0x04, 0x03, 0x0c, 0x07, 0x30, 0x30, 0x34, 0x45, 0x2d, 0x30, 0x31, 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, + 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x1c, 0xe0, 0x33, 0x1c, 0x9e, 0xac, 0x9d, 0x13, 0x36, 0xe8, + 0xdf, 0x95, 0x4d, 0x21, 0x98, 0xbd, 0xd6, 0x36, 0x6e, 0x6a, 0x07, 0x79, 0x1d, 0x9b, 0x8d, 0x7a, + 0x72, 0x62, 0x61, 0xd1, 0xef, 0x62, 0xeb, 0x2f, 0xf2, 0x81, 0xd5, 0x81, 0x4d, 0x80, 0x94, 0x09, + 0x4a, 0x21, 0xcb, 0xc8, 0x7e, 0x27, 0x3f, 0x08, 0x22, 0xb5, 0x91, 0x54, 0x43, 0xcb, 0xc4, 0x84, + 0xfd, 0x74, 0x26, 0x45, 0x3e, 0xab, 0xa3, 0x27, 0x30, 0x25, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, + 0x13, 0x01, 0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 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, 0x48, 0x00, 0x30, 0x45, + 0x02, 0x20, 0x2c, 0xe9, 0x17, 0x01, 0x39, 0xd3, 0xc9, 0xf2, 0xbf, 0xb6, 0x6a, 0x6b, 0x9f, 0xda, + 0x3a, 0x6f, 0x16, 0xf7, 0xc5, 0x29, 0x51, 0x10, 0x01, 0x85, 0x0b, 0xdf, 0xfe, 0xba, 0xc5, 0xc4, + 0x15, 0x8f, 0x02, 0x21, 0x00, 0xb7, 0x9d, 0x64, 0xbd, 0xa1, 0xd5, 0x1c, 0x96, 0xca, 0x37, 0x20, + 0x30, 0x64, 0xb6, 0x6f, 0xd6, 0x6d, 0x9d, 0xb8, 0x65, 0x15, 0x89, 0x43, 0xa1, 0x6e, 0x2d, 0x9c, + 0x48, 0x6e, 0x00, 0xf1, 0x7e, }; 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, + 0x0e, 0x9e, 0xb4, 0xba, 0x54, 0xd5, 0x4f, 0x8b, 0xbc, 0x47, 0xa3, 0x6d, 0xfd, 0x6a, 0xeb, 0x1f, + 0x58, 0x37, 0x9b, 0xcc, 0x31, 0x1d, 0xd5, 0xd9, 0x90, 0x1a, 0x3b, 0x96, 0x71, 0xd6, 0xc3, 0x67, + 0x04, 0x5e, 0xbb, 0x96, 0xf9, 0x15, 0xd5, 0x0e, 0x6f, 0x36, 0xf9, 0xa0, 0x25, 0xac, 0xd0, 0x87, + 0xab, 0x8e, 0xc9, 0x58, 0x2c, 0x53, 0x1e, 0xf6, 0xfd, 0x17, 0xfd, 0x2b, 0xf1, 0x66, 0x4b, 0x7b, }; const atcacert_cert_element_t g_cert_elements_1_signer[3] = { { .id = "IssueDate", - .device_loc ={ - .zone = DEVZONE_DATA, - .slot = 4, + .device_loc = { + .zone = DEVZONE_DATA, + .slot = 4, .is_genkey = 0, - .offset = 12, - .count = 13 + .offset = 12, + .count = 13 }, - .cert_loc ={ + .cert_loc = { .offset = 57, - .count = 13 + .count = 13 }, - .transforms ={ + .transforms = { TF_NONE, TF_NONE } }, { .id = "subject", - .device_loc ={ - .zone = DEVZONE_DATA, - .slot = 4, + .device_loc = { + .zone = DEVZONE_DATA, + .slot = 4, .is_genkey = 0, - .offset = 25, - .count = 7 + .offset = 25, + .count = 7 }, - .cert_loc ={ + .cert_loc = { .offset = 100, - .count = 7 + .count = 7 }, - .transforms ={ + .transforms = { TF_NONE, TF_NONE } }, { .id = "qiPolicy", - .device_loc ={ - .zone = DEVZONE_DATA, - .slot = 4, + .device_loc = { + .zone = DEVZONE_DATA, + .slot = 4, .is_genkey = 0, - .offset = 32, - .count = 4 + .offset = 32, + .count = 4 }, - .cert_loc ={ - .offset = 238, - .count = 4 + .cert_loc = { + .offset = 235, + .count = 4 }, - .transforms ={ + .transforms = { TF_NONE, TF_NONE } @@ -94,76 +94,76 @@ const atcacert_cert_element_t g_cert_elements_1_signer[3] = { }; 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 + .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 + .issue_date_format = DATEFMT_RFC5280_UTC, + .expire_date_format = DATEFMT_RFC5280_GEN, + .tbs_cert_loc = { + .offset = 4, + .count = 235 }, - .expire_years = 0, - .public_key_dev_loc = { - .zone = DEVZONE_DATA, - .slot = 9, - .is_genkey = 0, - .offset = 0, - .count = 72 + .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 + .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 + .std_cert_elements = { + { // STDCERT_PUBLIC_KEY + .offset = 134, + .count = 64 }, - { // STDCERT_SIGNATURE - .offset = 254, - .count = 64 + { // STDCERT_SIGNATURE + .offset = 251, + .count = 64 }, - { // STDCERT_ISSUE_DATE - .offset = 57, - .count = 13 + { // STDCERT_ISSUE_DATE + .offset = 57, + .count = 13 }, - { // STDCERT_EXPIRE_DATE - .offset = 0, - .count = 0 + { // STDCERT_EXPIRE_DATE + .offset = 0, + .count = 0 }, - { // STDCERT_SIGNER_ID - .offset = 0, - .count = 0 + { // STDCERT_SIGNER_ID + .offset = 0, + .count = 0 }, - { // STDCERT_CERT_SN - .offset = 13, - .count = 9 + { // STDCERT_CERT_SN + .offset = 13, + .count = 9 }, - { // STDCERT_AUTH_KEY_ID - .offset = 0, - .count = 0 + { // STDCERT_AUTH_KEY_ID + .offset = 0, + .count = 0 }, - { // STDCERT_SUBJ_KEY_ID - .offset = 0, - .count = 0 + { // STDCERT_SUBJ_KEY_ID + .offset = 0, + .count = 0 }, }, - .cert_elements = g_cert_elements_1_signer, + .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 + .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_2_device.c b/app/wpc/zcust_def_2_device.c index 34588f1db..e02f1414d 100644 --- a/app/wpc/zcust_def_2_device.c +++ b/app/wpc/zcust_def_2_device.c @@ -1,62 +1,62 @@ #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, +const uint8_t g_template_2_device[315] = { + 0x30, 0x82, 0x01, 0x37, 0x30, 0x81, 0xdd, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x49, 0xf6, + 0x93, 0xea, 0x68, 0xcf, 0x5e, 0xcf, 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, + 0x30, 0x34, 0x45, 0x2d, 0x30, 0x31, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x34, 0x30, 0x38, + 0x30, 0x39, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, + 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x10, 0x31, 0x0e, 0x30, 0x0c, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x05, 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, 0xc2, 0x17, 0x11, 0x4d, 0xcb, 0xee, 0x59, 0x85, 0x9c, + 0x08, 0xa3, 0x40, 0x18, 0x41, 0x3c, 0xa5, 0xf8, 0xb0, 0x23, 0xe6, 0xc4, 0x13, 0x82, 0x17, 0xe8, + 0x1c, 0x8b, 0xb6, 0x11, 0x11, 0xd4, 0x6c, 0x50, 0x54, 0x76, 0xbc, 0xca, 0x64, 0x41, 0x95, 0xd0, + 0x15, 0x2b, 0x73, 0x52, 0xa8, 0x2e, 0x4c, 0x5e, 0x8a, 0x2d, 0x73, 0x8f, 0x20, 0xe1, 0xc6, 0x62, + 0x79, 0x5c, 0x12, 0x60, 0x01, 0x82, 0x60, 0xa3, 0x1b, 0x30, 0x19, 0x30, 0x17, 0x06, 0x05, 0x67, + 0x81, 0x14, 0x01, 0x02, 0x01, 0x01, 0xff, 0x04, 0x0b, 0x04, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x4f, 0x74, 0xef, 0xe5, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0x9c, 0x8b, 0x2b, 0xa7, 0x95, 0xdc, 0x8d, 0xcc, + 0x57, 0xbf, 0x7e, 0x45, 0xb5, 0x97, 0x9a, 0xdc, 0xe0, 0x7b, 0x6b, 0x50, 0x47, 0x43, 0x4e, 0xac, + 0x56, 0xb3, 0x74, 0xc0, 0x42, 0x41, 0x59, 0x8c, 0x02, 0x21, 0x00, 0xbe, 0x81, 0x84, 0x32, 0xac, + 0x49, 0xd1, 0x8c, 0x00, 0x84, 0xde, 0x31, 0xc7, 0x3c, 0x3e, 0x8c, 0x1e, 0x17, 0x75, 0x32, 0x98, + 0x92, 0xbc, 0xaf, 0xb5, 0x9b, 0x45, 0xe6, 0xbe, 0x76, 0x14, 0x5a, }; const atcacert_cert_element_t g_cert_elements_2_device[2] = { { .id = "issuer", - .device_loc ={ - .zone = DEVZONE_DATA, - .slot = 5, + .device_loc = { + .zone = DEVZONE_DATA, + .slot = 5, .is_genkey = 0, - .offset = 25, - .count = 7 + .offset = 25, + .count = 7 }, - .cert_loc ={ + .cert_loc = { .offset = 47, - .count = 7 + .count = 7 }, - .transforms ={ + .transforms = { TF_NONE, TF_NONE } }, { .id = "RSID", - .device_loc ={ - .zone = DEVZONE_DATA, - .slot = 5, + .device_loc = { + .zone = DEVZONE_DATA, + .slot = 5, .is_genkey = 0, - .offset = 1, - .count = 9 + .offset = 1, + .count = 9 }, - .cert_loc ={ - .offset = 220, - .count = 9 + .cert_loc = { + .offset = 219, + .count = 9 }, - .transforms ={ + .transforms = { TF_NONE, TF_NONE } @@ -64,76 +64,76 @@ const atcacert_cert_element_t g_cert_elements_2_device[2] = { }; 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 + .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 + .issue_date_format = DATEFMT_RFC5280_GEN, + .expire_date_format = DATEFMT_RFC5280_GEN, + .tbs_cert_loc = { + .offset = 4, + .count = 224 }, - .expire_years = 0, - .public_key_dev_loc = { - .zone = DEVZONE_DATA, - .slot = 0, - .is_genkey = 1, - .offset = 0, - .count = 64 + .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 + .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 + .std_cert_elements = { + { // STDCERT_PUBLIC_KEY + .offset = 135, + .count = 64 }, - { // STDCERT_SIGNATURE - .offset = 241, - .count = 64 + { // STDCERT_SIGNATURE + .offset = 240, + .count = 64 }, - { // STDCERT_ISSUE_DATE - .offset = 58, - .count = 15 + { // STDCERT_ISSUE_DATE + .offset = 58, + .count = 15 }, - { // STDCERT_EXPIRE_DATE - .offset = 0, - .count = 0 + { // STDCERT_EXPIRE_DATE + .offset = 0, + .count = 0 }, - { // STDCERT_SIGNER_ID - .offset = 0, - .count = 0 + { // STDCERT_SIGNER_ID + .offset = 0, + .count = 0 }, - { // STDCERT_CERT_SN - .offset = 14, - .count = 8 + { // STDCERT_CERT_SN + .offset = 14, + .count = 8 }, - { // STDCERT_AUTH_KEY_ID - .offset = 0, - .count = 0 + { // STDCERT_AUTH_KEY_ID + .offset = 0, + .count = 0 }, - { // STDCERT_SUBJ_KEY_ID - .offset = 0, - .count = 0 + { // STDCERT_SUBJ_KEY_ID + .offset = 0, + .count = 0 }, }, - .cert_elements = g_cert_elements_2_device, + .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 + .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_3_device.c b/app/wpc/zcust_def_3_device.c new file mode 100644 index 000000000..132e6308c --- /dev/null +++ b/app/wpc/zcust_def_3_device.c @@ -0,0 +1,59 @@ +#include "atcacert/atcacert_def.h" + +const uint8_t g_cert_def_3_signer[328] = +{ +0x30, 0x82, 0x01, 0x44, 0x30, 0x81, 0xEB, 0xA0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x7A, 0xCD, +0xDA, 0x5E, 0xB9, 0x65, 0xD1, 0xD2, 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, 0x34, 0x30, 0x38, 0x32, 0x30, 0x31, +0x31, 0x34, 0x39, 0x35, 0x32, 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, 0x30, 0x31, 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, 0x39, 0x76, 0x92, 0x68, 0x13, 0x4E, 0x4A, 0x48, 0xF9, 0x3D, +0x35, 0x01, 0x99, 0x4E, 0xFC, 0x92, 0xC4, 0x5A, 0x74, 0xE0, 0x7A, 0x76, 0x84, 0xEE, 0x63, 0xB5, +0x1A, 0x47, 0x56, 0x68, 0x25, 0x18, 0xDD, 0xB0, 0x22, 0xAA, 0x66, 0x9F, 0x55, 0x87, 0xE9, 0xCA, +0x16, 0x37, 0xAB, 0x6E, 0xE6, 0x62, 0x8C, 0x97, 0x29, 0x2E, 0x56, 0xED, 0x9F, 0x22, 0x0F, 0xA5, +0xB8, 0x35, 0xE1, 0x21, 0xBD, 0x47, 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, +0x2C, 0xA6, 0x30, 0x0A, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x04, 0x03, 0x02, 0x03, 0x48, +0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0x99, 0xFC, 0xDB, 0xFD, 0x29, 0x26, 0xB7, 0x84, 0x1F, 0xE3, +0x54, 0xB3, 0x9D, 0x94, 0xC2, 0xC4, 0xAA, 0xAE, 0x6B, 0x47, 0x0B, 0x9A, 0x12, 0x69, 0x6E, 0x52, +0x92, 0xA9, 0xC2, 0xB9, 0x4E, 0x73, 0x02, 0x20, 0x5D, 0x6E, 0xE8, 0x53, 0x59, 0x2F, 0xAA, 0xE7, +0xDE, 0x3B, 0xA3, 0xD7, 0x17, 0x5F, 0xE1, 0x87, 0x73, 0x5A, 0x87, 0x21, 0x8C, 0x3F, 0xC2, 0xD8, +0x7C, 0x4C, 0xC9, 0xAA, 0xD0, 0xB0, 0xC1, 0x52, +}; + +const uint8_t g_cert_def_3_root_digest[32] = +{ +0x04, 0x23, 0x8E, 0x18, 0x12, 0x88, 0x70, 0x90, 0xFB, 0xFD, 0x29, 0x19, 0xCA, 0xEA, 0x50, 0x98, +0x32, 0xD6, 0x7E, 0x60, 0xE5, 0x64, 0xE9, 0x0C, 0x0D, 0xC0, 0x9B, 0xF8, 0x46, 0x69, 0x97, 0x06, +}; + +#if ATCACERT_INTEGRATION_EN +static struct atcac_x509_ctx* parsed; +#endif + +const atcacert_def_t g_cert_def_3_device = { + .type = CERTTYPE_X509_FULL_STORED, + .private_key_slot = 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 = 1, + .is_genkey = 0, + .offset = 0, + .count = 320 + }, + .ca_cert_def = NULL, +#if ATCACERT_INTEGRATION_EN + .parsed = &parsed +#endif +}; diff --git a/app/wpc/zcust_def_3_device.h b/app/wpc/zcust_def_3_device.h new file mode 100644 index 000000000..7b9679a23 --- /dev/null +++ b/app/wpc/zcust_def_3_device.h @@ -0,0 +1,16 @@ +#ifndef ZCUST_DEF_3_DEVICE_H +#define ZCUST_DEF_3_DEVICE_H + +#include "atcacert/atcacert_def.h" + +#ifdef __cplusplus +extern "C" { +#endif +extern const uint8_t g_cert_def_3_signer[328]; +extern const uint8_t g_cert_def_3_root_digest[32]; +extern const atcacert_def_t g_cert_def_3_device; +#ifdef __cplusplus +} +#endif + +#endif diff --git a/cryptoauthlib-manual.pdf b/cryptoauthlib-manual.pdf index cfa1ed518..6050583a9 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 c2afa2fe7..51bf9b563 100644 --- a/harmony/config/cryptoauthlib.py +++ b/harmony/config/cryptoauthlib.py @@ -33,9 +33,9 @@ calHalTracker = {} _HAL_FILES = ["atca_hal.c", "atca_hal.h"] -_CORE_PATHS = ['crypto/**/*', 'crypto/*', 'jwt/*', '*'] -_CA_PATHS = ['atcacert/*', 'calib/*', 'host/*'] -_TA_PATHS = ['atcacert/*', 'talib/*'] +_CORE_PATHS = ['atcacert/*', 'crypto/**/*', 'crypto/*', 'jwt/*', '*'] +_CA_PATHS = ['calib/*', 'host/*'] +_TA_PATHS = ['talib/*'] _SHA206_PATHS = ['api_206a/*'] _EXCL_FILES = ['atca_utils_sizes.c'] _WOLFCRYPTO_FILES = ['wolfssl/*'] @@ -776,13 +776,29 @@ def instantiateComponent(calComponent): calCryptoSwSha1EnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sw_sha"]) # Crypto SW SHA256 - calCryptoSwSha2EnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha2", calSwShaEnabledSymbol) + calCryptoSwSha2EnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha256", 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 SHA384 + calCryptoSwSha2EnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha384", calSwShaEnabledSymbol) + calCryptoSwSha2EnabledSymbol.setLabel("Support Crypto Sw SHA384?") + calCryptoSwSha2EnabledSymbol.setDescription("Enable support for Software SHA384") + calCryptoSwSha2EnabledSymbol.setVisible(True) + calCryptoSwSha2EnabledSymbol.setDefaultValue(False) + calCryptoSwSha2EnabledSymbol.setDependencies(handleParentSymbolChange, ["cal_sw_sha"]) + + # Crypto SW SHA512 + calCryptoSwSha2EnabledSymbol = calComponent.createBooleanSymbol("cal_sw_sha512", calSwShaEnabledSymbol) + calCryptoSwSha2EnabledSymbol.setLabel("Support Crypto Sw SHA512?") + calCryptoSwSha2EnabledSymbol.setDescription("Enable support for Software SHA512") + calCryptoSwSha2EnabledSymbol.setVisible(True) + calCryptoSwSha2EnabledSymbol.setDefaultValue(False) + 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?") diff --git a/harmony/templates/atca_config.h.ftl b/harmony/templates/atca_config.h.ftl index 611d3ed26..aa65ac6a2 100644 --- a/harmony/templates/atca_config.h.ftl +++ b/harmony/templates/atca_config.h.ftl @@ -316,7 +316,7 @@ <#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) + <#lt>#define ATCAB_AES_EXTRAS_EN (ATCAB_AES_EN) <#if cal_crypto_aes_cbc_encrypt == false> <#lt>#define ATCAB_AES_CBC_ENCRYPT_EN (FEATURE_DISABLED) @@ -374,12 +374,24 @@ <#lt>#define ATCAC_SHA1_EN (FEATURE_ENABLED) -<#if cal_sw_sha2 == false> +<#if cal_sw_sha256 == false> <#lt>#define ATCAC_SHA256_EN (FEATURE_DISABLED) <#else> <#lt>#define ATCAC_SHA256_EN (FEATURE_ENABLED) +<#if cal_sw_sha384 == false> + <#lt>#define ATCAC_SHA384_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_SHA384_EN (FEATURE_ENABLED) + + +<#if cal_sw_sha512 == false> + <#lt>#define ATCAC_SHA512_EN (FEATURE_DISABLED) +<#else> + <#lt>#define ATCAC_SHA512_EN (FEATURE_ENABLED) + + <#if cal_sw_sha2_hmac == false> <#lt>#define ATCAC_SHA256_HMAC_EN (FEATURE_DISABLED) <#else> diff --git a/harmony/templates/pkcs11_config.h.ftl b/harmony/templates/pkcs11_config.h.ftl index afe2783d0..52c172666 100644 --- a/harmony/templates/pkcs11_config.h.ftl +++ b/harmony/templates/pkcs11_config.h.ftl @@ -62,6 +62,11 @@ #define PKCS11_USE_STATIC_CONFIG 1 #endif +/** Enable RSA Support in PKCS11 */ +#ifndef PKCS11_RSA_SUPPORT_ENABLE +#define PKCS11_RSA_SUPPORT_ENABLE 0 +#endif + /** Maximum number of slots allowed in the system - if static memory this will always be the number of slots */ #ifndef PKCS11_MAX_SLOTS_ALLOWED @@ -180,4 +185,8 @@ void pkcs11_config_init_public(pkcs11_object_ptr pObject, const char * label, si void pkcs11_config_init_cert(pkcs11_object_ptr pObject, const char * label, size_t len); void pkcs11_config_init_secret(pkcs11_object_ptr pObject, const char* label, size_t len, size_t keylen); +#if ATCA_TA_SUPPORT +void pkcs11_config_set_key_size(pkcs11_object_ptr pObject); +#endif + #endif /* PKCS11_CONFIG_H_ */ diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 5d4567fb8..9fe500555 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -281,7 +281,7 @@ if (ATCA_TA_SUPPORT) add_subdirectory(talib) endif() -set_property(TARGET cryptoauth PROPERTY C_STANDARD 99) +set_target_properties(cryptoauth PROPERTIES C_STANDARD 99 VERSION ${VERSION} SOVERSION ${VERSION_MAJOR}) if(HAS_MALLOC) set(ATCA_PLATFORM_MALLOC malloc CACHE STRING "" FORCE) diff --git a/lib/README.md b/lib/README.md new file mode 100644 index 000000000..c030f570c --- /dev/null +++ b/lib/README.md @@ -0,0 +1,12 @@ +atcab +========================= + +atcab API reference +------------------------- + + +| Hardware Feature | atcab_ | +| --------------------------- | ------------------------------- | +| SHA256 | [atcab_sha_start] | +| SHA256 | [atcab_sha_update] | +| SHA256 | [atcab_sha_end] | \ No newline at end of file diff --git a/lib/atca_compiler.h b/lib/atca_compiler.h index d1569b5cb..3823b49cb 100644 --- a/lib/atca_compiler.h +++ b/lib/atca_compiler.h @@ -47,6 +47,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) ((((x) & 0x000000FFUL) << 24U) | (((x) & 0x0000FF00UL) << 8U) | (((x) & 0x00FF0000UL) >> 8U) | (((x) & 0xFF000000UL) >> 24U)) #define ATCA_UINT64_HOST_TO_BE(x) ((uint64_t)ATCA_UINT32_HOST_TO_BE((uint32_t)(x)) << 32 + (uint64_t)ATCA_UINT32_HOST_TO_BE((uint32_t)((x) >> 32))) #define ATCA_UINT64_BE_TO_HOST(x) ((uint64_t)ATCA_UINT32_BE_TO_HOST((uint32_t)(x)) << 32 + (uint64_t)ATCA_UINT32_BE_TO_HOST((uint32_t)((x) >> 32))) +#define ATCA_UINT64_HOST_TO_LE(x) (x) #define SHARED_LIB_EXPORT #define SHARED_LIB_IMPORT extern @@ -64,6 +65,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) (x) #define ATCA_UINT64_HOST_TO_BE(x) (x) #define ATCA_UINT64_BE_TO_HOST(x) (x) +#define ATCA_UINT64_HOST_TO_LE(x) __builtin_bswap64(x) #define ATCA_PLATFORM_BE #else #define ATCA_UINT16_HOST_TO_LE(x) (x) @@ -75,6 +77,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) __builtin_bswap32(x) #define ATCA_UINT64_HOST_TO_BE(x) __builtin_bswap64(x) #define ATCA_UINT64_BE_TO_HOST(x) __builtin_bswap64(x) +#define ATCA_UINT64_HOST_TO_LE(x) (x) #endif #ifdef WIN32 @@ -100,6 +103,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) (x) #define ATCA_UINT64_HOST_TO_BE(x) (x) #define ATCA_UINT64_BE_TO_HOST(x) (x) +#define ATCA_UINT64_HOST_TO_LE(x) __builtin_bswap64(x) #define ATCA_NO_PRAGMA_PACK #define ATCA_PLATFORM_BE #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ @@ -112,6 +116,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) (x) #define ATCA_UINT64_HOST_TO_BE(x) (x) #define ATCA_UINT64_BE_TO_HOST(x) (x) +#define ATCA_UINT64_HOST_TO_LE(x) __builtin_bswap64(x) #define ATCA_PLATFORM_BE #else #define ATCA_UINT16_HOST_TO_BE(x) __builtin_bswap16(x) @@ -123,6 +128,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) __builtin_bswap32(x) #define ATCA_UINT64_HOST_TO_BE(x) __builtin_bswap64(x) #define ATCA_UINT64_BE_TO_HOST(x) __builtin_bswap64(x) +#define ATCA_UINT64_HOST_TO_LE(x) (x) #endif #ifdef WIN32 @@ -160,6 +166,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) _byteswap_ulong(x) #define ATCA_UINT64_HOST_TO_BE(x) _byteswap_uint64(x) #define ATCA_UINT64_BE_TO_HOST(x) _byteswap_uint64(x) +#define ATCA_UINT64_HOST_TO_LE(x) (x) /* coverity[cert_dcl37_c_violation:SUPPRESS]*/ /* coverity[misra_c_2012_rule_21_1_violation:SUPPRESS]*/ /* coverity[misra_c_2012_rule_21_2_violation:SUPPRESS]*/ @@ -184,6 +191,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) (x) #define ATCA_UINT64_HOST_TO_BE(x) (x) #define ATCA_UINT64_BE_TO_HOST(x) (x) +#define ATCA_UINT64_HOST_TO_LE(x) (((uint64_t)__rev((uint32_t)x) << 32) | (uint64_t)__rev((uint32_t)(x >> 32))) #define ATCA_PLATFORM_BE #else #define ATCA_UINT16_HOST_TO_LE(x) (x) @@ -193,6 +201,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) __rev(x) #define ATCA_UINT64_HOST_TO_BE(x) (((uint64_t)__rev((uint32_t)x) << 32) | (uint64_t)__rev((uint32_t)(x >> 32))) #define ATCA_UINT64_BE_TO_HOST(x) (((uint64_t)__rev((uint32_t)x) << 32) | (uint64_t)__rev((uint32_t)(x >> 32))) +#define ATCA_UINT64_HOST_TO_LE(x) (x) #endif #define SHARED_LIB_EXPORT @@ -211,6 +220,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) (x) #define ATCA_UINT64_HOST_TO_BE(x) (x) #define ATCA_UINT64_BE_TO_HOST(x) (x) +#define ATCA_UINT64_HOST_TO_LE(x) (((uint64_t)__REV((uint32_t)x) << 32) | (uint64_t)__REV((uint32_t)(x >> 32))) #define ATCA_PLATFORM_BE #else #define ATCA_UINT16_HOST_TO_LE(x) (x) @@ -220,6 +230,7 @@ #define ATCA_UINT32_BE_TO_HOST(x) __REV(x) #define ATCA_UINT64_HOST_TO_BE(x) (((uint64_t)__REV((uint32_t)x) << 32) | (uint64_t)__REV((uint32_t)(x >> 32))) #define ATCA_UINT64_BE_TO_HOST(x) (((uint64_t)__REV((uint32_t)x) << 32) | (uint64_t)__REV((uint32_t)(x >> 32))) +#define ATCA_UINT64_HOST_TO_LE(x) (x) #endif #define SHARED_LIB_EXPORT diff --git a/lib/atca_config.h.in b/lib/atca_config.h.in index d1d623ae7..c26f69ffa 100644 --- a/lib/atca_config.h.in +++ b/lib/atca_config.h.in @@ -74,6 +74,9 @@ selected plus however additional slots one would like */ #cmakedefine ATCA_TFLEX_SUPPORT #cmakedefine ATCA_TNG_LEGACY_SUPPORT +/** Define WPC to be supported. */ +#cmakedefine ATCA_WPC_SUPPORT + /** Define Software Crypto Library to Use - if none are defined use the cryptoauthlib version where applicable */ #cmakedefine ATCA_MBEDTLS diff --git a/lib/atca_config_check.h b/lib/atca_config_check.h index 5c8612632..a7511e1a2 100644 --- a/lib/atca_config_check.h +++ b/lib/atca_config_check.h @@ -36,7 +36,9 @@ /** Library Configuration File - All build attributes should be included in atca_config.h */ +#ifndef LIBRARY_BUILD_EN #include "atca_config.h" +#endif /* Configuration Macros to detect device classes */ #if defined(ATCA_ATSHA204A_SUPPORT) || defined(ATCA_ATSHA206A_SUPPORT) || defined(ATCA_SHA104_SUPPORT) || defined(ATCA_SHA105_SUPPORT) @@ -110,7 +112,7 @@ /* 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_INVALID_MSG(c, s, m) #define ATCA_CHECK_VALID_MSG(c, m) if (1) #endif @@ -133,7 +135,7 @@ #ifndef ATCA_NO_HEAP #define ATCA_HEAP -#endif +#endif /** \def ATCA_UNUSED_VAR_CHECK * Enables removal of compiler warning due to unused variables @@ -696,10 +698,29 @@ * * 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) +#define ATCAC_SHA256_EN (FEATURE_ENABLED) +#endif + +/** \def ATCAC_SHA384_EN + * + * Enable ATCAC_SHA384_EN to enable sha384 host side api + * + * Disabled by default. Enable ATCAC_SHA512_EN to use SHA384 + **/ +#ifndef ATCAC_SHA384_EN +#define ATCAC_SHA384_EN (FEATURE_DISABLED) +#endif + +/** \def ATCAC_SHA512_EN + * + * Enable ATCAC_SHA512_EN to enable sha512 host side api + * + * Disabled by default. Use FEATURE_ENABLED to enable this feature + **/ +#ifndef ATCAC_SHA512_EN +#define ATCAC_SHA512_EN (FEATURE_DISABLED) #endif /** \def ATCAC_SHA256_HMAC diff --git a/lib/atca_debug.h b/lib/atca_debug.h index 44e254660..c2f3aba6f 100644 --- a/lib/atca_debug.h +++ b/lib/atca_debug.h @@ -2,7 +2,10 @@ #define ATCA_DEBUG_H #include "atca_status.h" + +#ifndef LIBRARY_BUILD_EN #include "atca_config.h" +#endif ATCA_STATUS atca_trace(ATCA_STATUS status); diff --git a/lib/atca_helpers.h b/lib/atca_helpers.h index 85342fb10..528cf6020 100644 --- a/lib/atca_helpers.h +++ b/lib/atca_helpers.h @@ -38,6 +38,16 @@ extern "C" { #endif +#define IS_ADD_SAFE_UINT16_T(a,b) (((UINT16_MAX - (a)) >= (b)) ? true : false) +#define IS_ADD_SAFE_UINT32_T(a,b) (((UINT32_MAX - (a)) >= (b)) ? true : false) +#define IS_ADD_SAFE_UINT64_T(a,b) (((UINT64_MAX - (a)) >= (b)) ? true : false) +#define IS_ADD_SAFE_SIZE_T(a,b) (((SIZE_MAX - (a)) >= (b)) ? true : false) + +#define IS_MUL_SAFE_UINT16_T(a,b) ((((a) <= UINT16_MAX / (b))) ? true : false) +#define IS_MUL_SAFE_UINT32_T(a,b) ((((a) <= UINT32_MAX / (b))) ? true : false) +#define IS_MUL_SAFE_UINT64_T(a,b) ((((a) <= UINT64_MAX / (b))) ? true : false) +#define IS_MUL_SAFE_SIZE_T(a,b) ((((a) <= SIZE_MAX / (b))) ? true : false) + ATCA_STATUS atcab_bin2hex(const uint8_t* bin, size_t bin_size, char* hex, size_t* hex_size); ATCA_STATUS atcab_bin2hex_(const uint8_t* bin, size_t bin_size, char* hex, size_t* hex_size, bool is_pretty, bool is_space, bool is_upper); ATCA_STATUS atcab_hex2bin(const char* ascii_hex, size_t ascii_hex_len, uint8_t* binary, size_t* bin_len); diff --git a/lib/atca_iface.c b/lib/atca_iface.c index 0019112d1..84f75960f 100644 --- a/lib/atca_iface.c +++ b/lib/atca_iface.c @@ -44,12 +44,12 @@ ATCA_STATUS initATCAIface(ATCAIfaceCfg *cfg, ATCAIface ca_iface) { ATCA_STATUS status; - +#if ATCA_CHECK_PARAMS_EN if (cfg == NULL || ca_iface == NULL) { return ATCA_BAD_PARAM; } - +#endif ca_iface->mIfaceCFG = cfg; status = ATCA_TRACE(atinit(ca_iface), "atinit"); @@ -167,10 +167,12 @@ ATCA_STATUS atinit(ATCAIface ca_iface) */ ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t word_address, uint8_t *txdata, int txlength) { +#if ATCA_CHECK_PARAMS_EN if (NULL == ca_iface) { return ATCA_BAD_PARAM; } +#endif if ((NULL != ca_iface->hal) && (NULL != ca_iface->hal->halsend)) { @@ -193,10 +195,12 @@ ATCA_STATUS atsend(ATCAIface ca_iface, uint8_t word_address, uint8_t *txdata, in */ ATCA_STATUS atreceive(ATCAIface ca_iface, uint8_t word_address, uint8_t *rxdata, uint16_t *rxlength) { +#if ATCA_CHECK_PARAMS_EN if (NULL == ca_iface) { return ATCA_BAD_PARAM; } +#endif if ((NULL != ca_iface->hal) && (NULL != ca_iface->hal->halreceive)) { @@ -218,11 +222,12 @@ ATCA_STATUS atreceive(ATCAIface ca_iface, uint8_t word_address, uint8_t *rxdata, */ ATCA_STATUS atcontrol(ATCAIface ca_iface, uint8_t option, void* param, size_t paramlen) { +#if ATCA_CHECK_PARAMS_EN if (NULL == ca_iface) { return ATCA_BAD_PARAM; } - +#endif if ((NULL != ca_iface->hal) && (NULL != ca_iface->hal->halcontrol)) { @@ -244,11 +249,12 @@ ATCA_STATUS atcontrol(ATCAIface ca_iface, uint8_t option, void* param, size_t pa */ ATCA_STATUS atwake(ATCAIface ca_iface) { +#if ATCA_CHECK_PARAMS_EN if (NULL == ca_iface) { return ATCA_BAD_PARAM; } - +#endif if ((NULL != ca_iface->hal) && (NULL != ca_iface->hal->halcontrol)) { @@ -280,10 +286,12 @@ ATCA_STATUS atwake(ATCAIface ca_iface) */ ATCA_STATUS atidle(ATCAIface ca_iface) { +#if ATCA_CHECK_PARAMS_EN if (NULL == ca_iface) { return ATCA_BAD_PARAM; } +#endif if ((NULL != ca_iface->hal) && (NULL != ca_iface->hal->halcontrol)) { @@ -306,10 +314,12 @@ ATCA_STATUS atidle(ATCAIface ca_iface) */ ATCA_STATUS atsleep(ATCAIface ca_iface) { +#if ATCA_CHECK_PARAMS_EN if (NULL == ca_iface) { return ATCA_BAD_PARAM; } +#endif if ((NULL != ca_iface->hal) && (NULL != ca_iface->hal->halcontrol)) { @@ -482,6 +492,7 @@ ATCA_STATUS ifacecfg_set_address( ATCAKitType kitiface /**< [in] Optional parameter to set the kit iface type */ ) { + (void)kitiface; ATCA_STATUS status = ATCA_BAD_PARAM; if (NULL != cfg) @@ -564,6 +575,7 @@ ATCA_STATUS releaseATCAIface(ATCAIface ca_iface) { ca_iface->hal_data = NULL; } +#ifdef ATCA_HAL_CUSTOM if (ATCA_CUSTOM_IFACE == ca_iface->mIfaceCFG->iface_type) { #ifdef ATCA_HEAP @@ -571,6 +583,7 @@ ATCA_STATUS releaseATCAIface(ATCAIface ca_iface) #endif ca_iface->hal = NULL; } +#endif } return status; } diff --git a/lib/atca_iface.h b/lib/atca_iface.h index 736a25ba5..421f3b1d4 100644 --- a/lib/atca_iface.h +++ b/lib/atca_iface.h @@ -43,10 +43,12 @@ extern "C" { #include #include -#include "atca_config.h" #include "atca_devtypes.h" #include "atca_status.h" +#ifndef LIBRARY_BUILD_EN +#include "atca_config.h" +#endif #ifdef ATCA_STRICT_C99 #define ATCA_IFACECFG_NAME(x) (x) diff --git a/lib/atca_status.h b/lib/atca_status.h index d9f542d64..5d75883a8 100644 --- a/lib/atca_status.h +++ b/lib/atca_status.h @@ -30,7 +30,6 @@ #define ATCA_STATUS_H #include -#include "atca_config.h" #include "atca_compiler.h" #include diff --git a/lib/atca_utils_sizes.c b/lib/atca_utils_sizes.c index 9d28f97e6..961c6048a 100644 --- a/lib/atca_utils_sizes.c +++ b/lib/atca_utils_sizes.c @@ -127,11 +127,21 @@ SIZE_OF_API_S(atcac_sha1_ctx) SIZE_OF_API_T(atcac_sha1_ctx_t) #endif -#if ATCAC_SHA256_EN || ATCA_CRYPTO_SHA2_EN +#if ATCAC_SHA256_EN || ATCA_CRYPTO_SHA256_EN SIZE_OF_API_S(atcac_sha2_256_ctx) SIZE_OF_API_T(atcac_sha2_256_ctx_t) #endif +#if ATCAC_SHA384_EN || ATCA_CRYPTO_SHA384_EN +SIZE_OF_API_S(atcac_sha2_384_ctx) +SIZE_OF_API_T(atcac_sha2_384_ctx_t) +#endif + +#if ATCAC_SHA512_EN || ATCA_CRYPTO_SHA512_EN +SIZE_OF_API_S(atcac_sha2_512_ctx) +SIZE_OF_API_T(atcac_sha2_512_ctx_t) +#endif + #if ATCAC_SHA256_HMAC_EN || ATCA_CRYPTO_SHA2_HMAC_EN SIZE_OF_API_S(atcac_hmac_ctx) SIZE_OF_API_T(atcac_hmac_ctx_t) diff --git a/lib/atca_version.h b/lib/atca_version.h index 81acb791c..4912f5a19 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 "20240626" +#define ATCA_LIBRARY_VERSION_DATE "20240926" #define ATCA_LIBRARY_VERSION_MAJOR 3 #define ATCA_LIBRARY_VERSION_MINOR 7 -#define ATCA_LIBRARY_VERSION_BUILD 5 +#define ATCA_LIBRARY_VERSION_BUILD 6 #endif /* ATCA_VERSION_H */ diff --git a/lib/atcacert/atcacert_client.c b/lib/atcacert/atcacert_client.c index 1a765795a..e769ab96f 100644 --- a/lib/atcacert/atcacert_client.c +++ b/lib/atcacert/atcacert_client.c @@ -38,7 +38,7 @@ #include "calib/calib_basic.h" #endif -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) #include "talib/talib_basic.h" #include "talib/talib_internal.h" #endif diff --git a/lib/atcacert/atcacert_def.c b/lib/atcacert/atcacert_def.c index 0eceb53c7..ec8085675 100644 --- a/lib/atcacert/atcacert_def.c +++ b/lib/atcacert/atcacert_def.c @@ -144,6 +144,9 @@ ATCA_STATUS atcacert_get_device_locs(ATCADevice device, ATCA_STATUS ret = 0; size_t i; size_t cfg_rd_size = ATCA_BLOCK_SIZE; +#ifdef ATCA_CA2_SUPPORT + bool is_ca2_devcie = atcab_is_ca2_device(atcab_get_device_type_ext(device)); +#endif if (cert_def == NULL || device_locs == NULL || device_locs_count == NULL) { @@ -188,14 +191,23 @@ ATCA_STATUS atcacert_get_device_locs(ATCADevice device, return ATCACERT_E_BAD_CERT; // Cert def is in an invalid state } + for (i = 0; i < cert_def->cert_elements_count; i++) { + size_t tmp_block_size = block_size; +#ifdef ATCA_CA2_SUPPORT + if((true == is_ca2_devcie) + && (DEVZONE_CONFIG == cert_def->cert_elements[i].device_loc.zone)) + { + tmp_block_size = ATCA_CA2_CONFIG_SLOT_SIZE; + } +#endif ret = atcacert_merge_device_loc( device_locs, device_locs_count, device_locs_max_count, &cert_def->cert_elements[i].device_loc, - block_size); + tmp_block_size); if (ret != ATCACERT_E_SUCCESS) { return ret; @@ -217,12 +229,13 @@ ATCA_STATUS atcacert_get_device_locs(ATCADevice device, .count = 13 }; - if (true == (atcab_is_ca2_device(atcab_get_device_type_ext(device)))) +#ifdef ATCA_CA2_SUPPORT + if (true == is_ca2_devcie) { //! Set Ca2 device config zone size cfg_rd_size = ATCA_CA2_CONFIG_SLOT_SIZE; } - +#endif ret = atcacert_merge_device_loc( device_locs, device_locs_count, @@ -568,6 +581,7 @@ ATCA_STATUS atcacert_cert_build_finish(atcacert_build_state_t* build_state) uint8_t sn[32] = { 0 }; size_t sn_size = build_state->cert_def->std_cert_elements[STDCERT_CERT_SN].count; uint8_t public_key[64] = { 0 }; + cal_buffer pubkey = CAL_BUF_INIT(sizeof(public_key), public_key); if (sizeof(sn) < sn_size) { @@ -580,7 +594,7 @@ ATCA_STATUS atcacert_cert_build_finish(atcacert_build_state_t* build_state) build_state->cert_def, build_state->cert, *build_state->cert_size, - public_key); + &pubkey); if (ret != ATCACERT_E_SUCCESS) { return ret; @@ -658,6 +672,7 @@ ATCA_STATUS atcacert_get_device_data(const atcacert_def_t* cert_def, unsigned int i = 0u; uint8_t temp_buf[256] = { 0 }; // Must be at least 72 bytes size_t temp_buf_size = sizeof(temp_buf); + cal_buffer buffer = CAL_BUF_INIT(ATCA_ECCP256_PUBKEY_SIZE, temp_buf); if (cert_def == NULL || cert == NULL || device_loc == NULL || device_data == NULL) { @@ -678,7 +693,7 @@ ATCA_STATUS atcacert_get_device_data(const atcacert_def_t* cert_def, // Subject public key if (atcacert_is_device_loc_overlap(&cert_def->public_key_dev_loc, device_loc)) { - ret = atcacert_get_subj_public_key(cert_def, cert, cert_size, temp_buf); + ret = atcacert_get_subj_public_key(cert_def, cert, cert_size, &buffer); if (ret != ATCACERT_E_SUCCESS) { return ret; @@ -810,20 +825,19 @@ ATCA_STATUS atcacert_get_subject(const atcacert_def_t* cert_def, ATCA_STATUS atcacert_get_subj_public_key(const atcacert_def_t* cert_def, const uint8_t* cert, size_t cert_size, - uint8_t subj_public_key[64]) + cal_buffer* subj_public_key) { ATCA_STATUS status = ATCACERT_E_BAD_PARAMS; UNUSED_VAR(cert); UNUSED_VAR(cert_size); - if (NULL != cert_def && NULL != subj_public_key) + if (NULL != cert_def && NULL != subj_public_key && NULL != subj_public_key->buf) { #if ATCACERT_INTEGRATION_EN if (CERTTYPE_X509_FULL_STORED == cert_def->type) { - cal_buffer pk_buf = CAL_BUF_INIT(64U, subj_public_key); - status = (NULL != cert_def->parsed) ? atcac_get_subj_public_key(*cert_def->parsed, &pk_buf) : ATCACERT_E_ERROR; + status = (NULL != cert_def->parsed) ? atcac_get_subj_public_key(*cert_def->parsed, subj_public_key) : ATCACERT_E_ERROR; } else #endif @@ -832,7 +846,7 @@ ATCA_STATUS atcacert_get_subj_public_key(const atcacert_def_t* cert_def, if (NULL != cert) { //For ECC608, always EC256 supported, hence pubkey size is max 64 - status = atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_PUBLIC_KEY], cert, cert_size, subj_public_key, 64); + status = atcacert_get_cert_element(cert_def, &cert_def->std_cert_elements[STDCERT_PUBLIC_KEY], cert, cert_size, subj_public_key->buf, subj_public_key->len); } #endif } @@ -1438,6 +1452,7 @@ ATCA_STATUS atcacert_gen_cert_sn(const atcacert_def_t* cert_def, uint8_t comp_cert[ATCACERT_COMP_CERT_MAX_SIZE] = { 0 }; atcacert_tm_utc_t issue_date; uint8_t expire_years; + cal_buffer pubkey = CAL_BUF_INIT(sizeof(public_key), public_key); if (cert_def == NULL || cert == NULL) { @@ -1484,7 +1499,7 @@ ATCA_STATUS atcacert_gen_cert_sn(const atcacert_def_t* cert_def, sn_size = cert_def->std_cert_elements[STDCERT_CERT_SN].count; // Get public key - ret = atcacert_get_subj_public_key(cert_def, cert, cert_size, public_key); + ret = atcacert_get_subj_public_key(cert_def, cert, cert_size, &pubkey); if (ret != ATCACERT_E_SUCCESS) { break; diff --git a/lib/atcacert/atcacert_def.h b/lib/atcacert/atcacert_def.h index 09ab63d57..726a87367 100644 --- a/lib/atcacert/atcacert_def.h +++ b/lib/atcacert/atcacert_def.h @@ -383,15 +383,14 @@ ATCA_STATUS atcacert_set_subj_public_key(const atcacert_def_t* cert_def, * \param[in] cert_def Certificate definition for the certificate. * \param[in] cert Certificate to get element from. * \param[in] cert_size Size of the certificate (cert) in bytes. - * \param[out] subj_public_key Subject public key is returned in this buffer. Formatted at X and Y - * integers concatenated together. 64 bytes. + * \param[out] subj_public_key Subject public key is returned in the buffer pointed by subj_public_key * * \return ATCACERT_E_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcacert_get_subj_public_key(const atcacert_def_t * cert_def, const uint8_t * cert, size_t cert_size, - uint8_t subj_public_key[64]); + cal_buffer* subj_public_key); /** diff --git a/lib/calib/calib_packet.c b/lib/calib/calib_packet.c new file mode 100644 index 000000000..81c7a657e --- /dev/null +++ b/lib/calib/calib_packet.c @@ -0,0 +1,74 @@ +/** + * \file + * \brief CryptoAuthLib API for packet allocation. + * + * The APIs are used for allocating packets in heap or bss according to + * atcab heap availability. Corresponding memory free is done + * + * \note List of devices that support this command - ATSHA204A, ATECC108A, + * ATECC508A, ATECC608A/B + * + * \copyright (c) 2024 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 "calib_packet.h" + +#ifdef ATCA_NO_HEAP +ATCAPacket* calib_packet_alloc(void) +{ + static ATCAPacket packet; // Static variable, allocated in BSS segment + + return &packet; +} +#else +ATCAPacket* calib_packet_alloc(void) +{ + ATCAPacket* packet = (ATCAPacket*)hal_malloc(sizeof(ATCAPacket)); // Allocate memory on the heap + + if (NULL == packet) + { + // Handle memory allocation failure + return NULL; + } + return packet; +} +#endif + +#ifdef ATCA_NO_HEAP +void calib_packet_free(ATCAPacket* packet) +{ + if (NULL != packet) + { + (void)memset(packet, 0x00, sizeof(ATCAPacket)); + } +} +#else +void calib_packet_free(ATCAPacket* packet) +{ + if (NULL != packet) + { + hal_free(packet); + } +} +#endif diff --git a/lib/calib/calib_packet.h b/lib/calib/calib_packet.h new file mode 100644 index 000000000..5f8179658 --- /dev/null +++ b/lib/calib/calib_packet.h @@ -0,0 +1,53 @@ +/** + * \file + * \brief Defines packet allocation functions + * + * The APIs are used for allocating packets in heap or bss according to + * atcab heap availability. Corresponding memory free is done + * + * This supports the ATECC device family. + * + * \copyright (c) 2024 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_PACKET_H +#define CALIB_PACKET_H + +#include "calib_command.h" +#include "atca_device.h" +#include "atca_config.h" + +#ifdef __cplusplus +extern "C" { +#endif + +ATCAPacket* calib_packet_alloc(void); + +void calib_packet_free(ATCAPacket* packet); + +#ifdef __cplusplus +} +#endif + +#endif /* CALIB_PACKET_H */ \ No newline at end of file diff --git a/lib/calib/calib_read.c b/lib/calib/calib_read.c index f2b6bbd6c..762dddc35 100644 --- a/lib/calib/calib_read.c +++ b/lib/calib/calib_read.c @@ -60,10 +60,16 @@ */ 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) { - ATCAPacket packet; + ATCAPacket * packet = calib_packet_alloc(); ATCA_STATUS status; uint16_t addr; + if(NULL == packet) + { + (void)ATCA_TRACE(ATCA_ALLOC_FAILURE, "calib_packet_alloc - failed"); + return ATCA_ALLOC_FAILURE; + } + do { // Check the input parameters @@ -84,27 +90,27 @@ ATCA_STATUS calib_read_zone(ATCADevice device, uint8_t zone, uint16_t slot, uint zone = zone | ATCA_ZONE_READWRITE_32; } - (void)memset(&packet, 0x00, sizeof(ATCAPacket)); + (void)memset(packet, 0x00, sizeof(ATCAPacket)); // build a read command - packet.param1 = zone; - packet.param2 = addr; + packet->param1 = zone; + packet->param2 = addr; - if ((status = atRead(atcab_get_device_type_ext(device), &packet)) != ATCA_SUCCESS) + if ((status = atRead(atcab_get_device_type_ext(device), packet)) != ATCA_SUCCESS) { (void)ATCA_TRACE(status, "atRead - failed"); break; } - if ((status = atca_execute_command(&packet, device)) != ATCA_SUCCESS) + if ((status = atca_execute_command(packet, device)) != ATCA_SUCCESS) { (void)ATCA_TRACE(status, "calib_read_zone - execution failed"); break; } - (void)memcpy(data, &packet.data[1], len); - } while (false); - + (void)memcpy(data, &packet->data[1], len); + } while (false); + calib_packet_free(packet); return status; } diff --git a/lib/cmake/pkcs11.cmake b/lib/cmake/pkcs11.cmake index e610cb7dc..de0622ab7 100644 --- a/lib/cmake/pkcs11.cmake +++ b/lib/cmake/pkcs11.cmake @@ -13,6 +13,7 @@ option(PKCS11_TOKEN_INIT_SUPPORT "Enable device initialization using pkcs 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) option(PKCS11_AUTH_TERMINATE_BEFORE_LOGIN "Enable auth terminate before c_login" OFF) +option(PKCS11_RSA_SUPPORT_ENABLE "Enable RSA support" OFF) 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") diff --git a/lib/cmake/wolfssl.cmake b/lib/cmake/wolfssl.cmake index f52140bd0..d3b0fa417 100644 --- a/lib/cmake/wolfssl.cmake +++ b/lib/cmake/wolfssl.cmake @@ -26,6 +26,7 @@ set(WOLFSSL_LIB_SRC ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/aes.c ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/rsa.c ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/sha.c ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/sha256.c + ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/sha512.c ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/sp_int.c ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/tfm.c ${CMAKE_BINARY_DIR}/downloaded/wolfssl/wolfcrypt/src/wc_encrypt.c diff --git a/lib/crypto/atca_crypto_sw.h b/lib/crypto/atca_crypto_sw.h index 65a634271..47177bd10 100644 --- a/lib/crypto/atca_crypto_sw.h +++ b/lib/crypto/atca_crypto_sw.h @@ -41,6 +41,10 @@ extern "C" { #define ATCA_SHA1_DIGEST_SIZE (20U) #define ATCA_SHA2_256_DIGEST_SIZE (32U) #define ATCA_SHA2_256_BLOCK_SIZE (64U) +#define ATCA_SHA2_384_DIGEST_SIZE (48U) +#define ATCA_SHA2_384_BLOCK_SIZE (128U) +#define ATCA_SHA2_512_DIGEST_SIZE (64U) +#define ATCA_SHA2_512_BLOCK_SIZE (128U) #if ATCA_HOSTLIB_EN ATCA_STATUS atcac_sw_random(uint8_t* data, size_t data_size); @@ -67,8 +71,8 @@ ATCA_STATUS atcac_sw_sha1_finish(struct atcac_sha1_ctx* ctx, uint8_t digest[ATCA #endif /* ATCAC_SHA1_EN || ATCA_CRYPTO_SHA1_EN */ -#if ATCAC_SHA256_EN || ATCA_CRYPTO_SHA2_EN -#if ATCA_CRYPTO_SHA2_EN +#if ATCAC_SHA256_EN || ATCA_CRYPTO_SHA256_EN +#if ATCA_CRYPTO_SHA256_EN typedef struct atcac_sha2_256_ctx { uint32_t pad[48]; @@ -85,8 +89,47 @@ void atcac_sha256_ctx_free(struct atcac_sha2_256_ctx * ctx); ATCA_STATUS atcac_sw_sha2_256_init(struct atcac_sha2_256_ctx* ctx); ATCA_STATUS atcac_sw_sha2_256_update(struct atcac_sha2_256_ctx* ctx, const uint8_t* data, size_t data_size); ATCA_STATUS atcac_sw_sha2_256_finish(struct atcac_sha2_256_ctx* ctx, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]); -#endif /* ATCAC_SHA256_EN || ATCA_CRYPTO_SHA2_EN */ +#endif /* ATCAC_SHA256_EN || ATCA_CRYPTO_SHA256_EN */ +#if ATCAC_SHA384_EN || ATCA_CRYPTO_SHA384_EN +#if ATCA_CRYPTO_SHA384_EN +typedef struct atcac_sha2_384_ctx +{ + uint64_t pad[48]; +} atcac_sha2_384_ctx_t; +#else +struct atcac_sha2_384_ctx; +#endif + +#if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) +struct atcac_sha2_384_ctx * atcac_sha384_ctx_new(void); +void atcac_sha384_ctx_free(struct atcac_sha2_384_ctx * ctx); +#endif + +ATCA_STATUS atcac_sw_sha2_384_init(struct atcac_sha2_384_ctx* ctx); +ATCA_STATUS atcac_sw_sha2_384_update(struct atcac_sha2_384_ctx* ctx, const uint8_t* data, size_t data_size); +ATCA_STATUS atcac_sw_sha2_384_finish(struct atcac_sha2_384_ctx* ctx, uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE]); +#endif /* ATCAC_SHA384_EN || ATCA_CRYPTO_SHA384_EN */ + +#if ATCAC_SHA512_EN || ATCA_CRYPTO_SHA512_EN +#if ATCA_CRYPTO_SHA512_EN +typedef struct atcac_sha2_512_ctx +{ + uint64_t pad[48]; +} atcac_sha2_512_ctx_t; +#else +struct atcac_sha2_512_ctx; +#endif + +#if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) +struct atcac_sha2_512_ctx * atcac_sha512_ctx_new(void); +void atcac_sha512_ctx_free(struct atcac_sha2_512_ctx * ctx); +#endif + +ATCA_STATUS atcac_sw_sha2_512_init(struct atcac_sha2_512_ctx* ctx); +ATCA_STATUS atcac_sw_sha2_512_update(struct atcac_sha2_512_ctx* ctx, const uint8_t* data, size_t data_size); +ATCA_STATUS atcac_sw_sha2_512_finish(struct atcac_sha2_512_ctx* ctx, uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE]); +#endif /* ATCAC_SHA512_EN || ATCA_CRYPTO_SHA512_EN */ #if ATCAC_SHA256_HMAC_EN || ATCA_CRYPTO_SHA2_HMAC_EN #if ATCA_CRYPTO_SHA2_HMAC_EN @@ -112,8 +155,17 @@ ATCA_STATUS atcac_sha256_hmac_finish(struct atcac_hmac_ctx* ctx, uint8_t* digest #endif /* ATCAC_SHA256_HMAC_EN || ATCA_CRYPTO_SHA2_HMAC_EN */ -#if ATCAC_AES_CMAC_EN +#if ATCAC_AES_CMAC_EN || ATCA_CRYPTO_AES_CMAC_EN +#if ATCA_CRYPTO_AES_CMAC_EN +/* Dummy structure for memory reservation */ +typedef struct atcac_aes_cmac_ctx +{ + void* ctx_ptr; +}atcac_aes_cmac_ctx_t; +#else struct atcac_aes_cmac_ctx; +#endif + #if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) struct atcac_aes_cmac_ctx * atcac_aes_cmac_ctx_new(void); void atcac_aes_cmac_ctx_free(struct atcac_aes_cmac_ctx * ctx); @@ -122,11 +174,20 @@ void atcac_aes_cmac_ctx_free(struct atcac_aes_cmac_ctx * ctx); ATCA_STATUS atcac_aes_cmac_init(struct atcac_aes_cmac_ctx* ctx, const uint8_t* key, const uint8_t key_len); ATCA_STATUS atcac_aes_cmac_update(struct atcac_aes_cmac_ctx* ctx, const uint8_t* data, const size_t data_size); ATCA_STATUS atcac_aes_cmac_finish(struct atcac_aes_cmac_ctx* ctx, uint8_t* cmac, size_t* cmac_size); -#endif /* ATCAC_AES_CMAC_EN */ +#endif /* ATCAC_AES_CMAC_EN || ATCA_CRYPTO_AES_CMAC_EN */ -#if ATCAC_AES_GCM_EN +#if ATCAC_AES_GCM_EN || ATCA_CRYPTO_AES_GCM_EN +#if ATCA_CRYPTO_AES_GCM_EN +/* Dummy structure for memory reservation */ +typedef struct atcac_aes_gcm_ctx +{ + void* ctx_ptr; +}atcac_aes_gcm_ctx_t; +#else struct atcac_aes_gcm_ctx; +#endif + #if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) struct atcac_aes_gcm_ctx * atcac_aes_gcm_ctx_new(void); void atcac_aes_gcm_ctx_free(struct atcac_aes_gcm_ctx * ctx); @@ -152,7 +213,7 @@ ATCA_STATUS atcac_aes_gcm_decrypt_update(struct atcac_aes_gcm_ctx* ctx, const ui ATCA_STATUS atcac_aes_gcm_decrypt_finish(struct atcac_aes_gcm_ctx* ctx, const uint8_t* tag, size_t tag_len, bool* is_verified); -#endif /* ATCAC_AES_GCM_EN */ +#endif /* ATCAC_AES_GCM_EN || ATCA_CRYPTO_AES_GCM_EN */ #if ATCAC_PKEY_EN struct atcac_pk_ctx; diff --git a/lib/crypto/atca_crypto_sw_aes_cmac.c b/lib/crypto/atca_crypto_sw_aes_cmac.c new file mode 100644 index 000000000..6d75994ed --- /dev/null +++ b/lib/crypto/atca_crypto_sw_aes_cmac.c @@ -0,0 +1,84 @@ +/** + * \file + * \brief Common Wrapper for host side AES-CMAC implementations that feature + * update APIs rather than an all at once 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. + */ + +#include "atca_crypto_sw.h" + +#if ATCA_CRYPTO_AES_CMAC_EN + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-CMAC operations + * \brief Initialize context for performing CMAC in software. + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_cmac_init( + struct atcac_aes_cmac_ctx* ctx, /**< [in] pointer to a aes-cmac context */ + const uint8_t* key, /**< [in] key value to use */ + const uint8_t key_len /**< [in] length of the key */ + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(key); + UNUSED_VAR(key_len); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-CMAC operations + * \brief Update CMAC context with input data + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_cmac_update( + struct atcac_aes_cmac_ctx* ctx, /**< [in] pointer to a aes-cmac context */ + const uint8_t* data, /**< [in] input data */ + const size_t data_size /**< [in] length of input data */ + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(data); + UNUSED_VAR(data_size); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-CMAC operations + * \brief Finish CMAC calculation and clear the CMAC context + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_cmac_finish( + struct atcac_aes_cmac_ctx* ctx, /**< [in] pointer to a aes-cmac context */ + uint8_t* cmac, /**< [out] cmac value */ + size_t* cmac_size /**< [inout] length of cmac */ + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(cmac); + UNUSED_VAR(cmac_size); + return ATCA_UNIMPLEMENTED; +} + +#endif \ No newline at end of file diff --git a/lib/crypto/atca_crypto_sw_aes_gcm.c b/lib/crypto/atca_crypto_sw_aes_gcm.c index a298c8605..843b18da1 100644 --- a/lib/crypto/atca_crypto_sw_aes_gcm.c +++ b/lib/crypto/atca_crypto_sw_aes_gcm.c @@ -79,3 +79,181 @@ ATCA_STATUS atcac_aes_gcm_decrypt( } #endif + +#if ATCA_CRYPTO_AES_GCM_EN + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-GCM operations + * \brief Initialize an AES-GCM context + * + * \param[in] ctx AES-GCM Context + * \param[in] key AES Key + * \param[in] key_len Length of the AES key - should be 16 or 32 + * \param[in] iv Initialization vector input + * \param[in] iv_len Length of the initialization vector + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_gcm_encrypt_start( + struct atcac_aes_gcm_ctx * ctx, + const uint8_t * key, + const uint8_t key_len, + const uint8_t * iv, + const uint8_t iv_len + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(key); + UNUSED_VAR(key_len); + UNUSED_VAR(iv); + UNUSED_VAR(iv_len); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-GCM operations + * \brief Initialize an AES-GCM context for decryption + * + * \param[in] ctx AES-GCM Context + * \param[in] key AES Key + * \param[in] key_len Length of the AES key - should be 16 or 32 + * \param[in] iv Initialization vector input + * \param[in] iv_len Length of the initialization vector + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_gcm_decrypt_start( + struct atcac_aes_gcm_ctx* ctx, + const uint8_t* key, + const uint8_t key_len, + const uint8_t* iv, + const uint8_t iv_len + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(key); + UNUSED_VAR(key_len); + UNUSED_VAR(iv); + UNUSED_VAR(iv_len); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-GCM operations + * \brief Update the GCM context with additional authentication data (AAD) + * + * \param[in] ctx AES-GCM Context + * \param[in] aad Additional Authentication Data + * \param[in] aad_len Length of AAD + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_gcm_aad_update( + struct atcac_aes_gcm_ctx* ctx, + const uint8_t* aad, + const size_t aad_len + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(aad); + UNUSED_VAR(aad_len); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-GCM operations + * \brief Encrypt a data using the initialized context + * + * \param[in] ctx AES-GCM Context + * \param[in] plaintext Data to be encrypted + * \param[in] pt_len Plain text Length + * \param[out] ciphertext Encrypted data + * \param[out] ct_len Cipher text length + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_gcm_encrypt_update( + struct atcac_aes_gcm_ctx* ctx, + const uint8_t* plaintext, + const size_t pt_len, + uint8_t* ciphertext, + size_t* ct_len + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(plaintext); + UNUSED_VAR(pt_len); + UNUSED_VAR(ciphertext); + UNUSED_VAR(ct_len); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-GCM operations + * \brief Decrypt ciphertext using the initialized context + * + * \param[in] ctx AES-GCM Context + * \param[in] ciphertext Encrypted data + * \param[in] ct_len Ciphertext length + * \param[out] plaintext Data to be encrypted + * \param[out] pt_len Plaintext Length + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_gcm_decrypt_update( + struct atcac_aes_gcm_ctx* ctx, + const uint8_t* ciphertext, + const size_t ct_len, + uint8_t* plaintext, + size_t* pt_len + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(ciphertext); + UNUSED_VAR(ct_len); + UNUSED_VAR(plaintext); + UNUSED_VAR(pt_len); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-GCM operations + * \brief Get the AES-GCM tag and free the context + * + * \param[in] ctx AES-GCM Context + * \param[out] tag AES-GCM tag + * \param[in] tag_len tag length + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_gcm_encrypt_finish( + struct atcac_aes_gcm_ctx* ctx, + uint8_t* tag, + size_t tag_len + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(tag); + UNUSED_VAR(tag_len); + return ATCA_UNIMPLEMENTED; +} + +/** NOTE: Use third party libraries like openSSL/WolfSSL/mbedTLS to enable AES-GCM operations + * \brief Compare the AES-GCM tag and free the context + * + * \param[in] ctx AES-GCM Context + * \param[out] tag AES-GCM tag + * \param[in] tag_len tag length + * \param[out] is_verified verification status + * + * \return ATCA_UNIMPLEMENTED + */ +ATCA_STATUS atcac_aes_gcm_decrypt_finish( + struct atcac_aes_gcm_ctx* ctx, + const uint8_t* tag, + size_t tag_len, + bool* is_verified + ) +{ + UNUSED_VAR(ctx); + UNUSED_VAR(tag); + UNUSED_VAR(tag_len); + UNUSED_VAR(is_verified); + return ATCA_UNIMPLEMENTED; +} + +#endif diff --git a/lib/crypto/atca_crypto_sw_sha2.c b/lib/crypto/atca_crypto_sw_sha2.c index 943645806..d52c0caaa 100644 --- a/lib/crypto/atca_crypto_sw_sha2.c +++ b/lib/crypto/atca_crypto_sw_sha2.c @@ -29,24 +29,24 @@ #include "atca_crypto_sw_sha2.h" #include "cal_internal.h" +#ifdef __COVERITY__ +#pragma coverity compliance block \ + (deviate "CERT EXP39-C" "Type casting of pointer is required for using sha_routines") \ + (deviate "MISRA C-2012 Rule 11.3" "Type casting of pointer is required for using sha_routines") +#endif + #if ATCA_CRYPTO_SHA2_EN #include "hashes/sha2_routines.h" +#endif +#if ATCA_CRYPTO_SHA256_EN /** \brief initializes the SHA256 software * \param[in] ctx ptr to context data structure * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS atcac_sw_sha2_256_init(struct atcac_sha2_256_ctx* ctx) { - if (sizeof(sw_sha256_ctx) > sizeof(atcac_sha2_256_ctx_t)) - { - // atcac_sha2_256_ctx_t isn't large enough for this implementation - return ATCA_ASSERT_FAILURE; - } - sw_sha256_init((sw_sha256_ctx*)ctx); - - return ATCA_SUCCESS; + return sw_sha256_init((sw_sha256_ctx*)ctx); } /** \brief updates the running hash with the next block of data, called iteratively for the entire @@ -54,30 +54,94 @@ ATCA_STATUS atcac_sw_sha2_256_init(struct atcac_sha2_256_ctx* ctx) \param[in] ctx ptr to SHA context data structure \param[in] data ptr to next block of data to hash \param[in] data_size size amount of data to hash in the given block, in bytes - \return ATCA_SUCCESS + * \return ATCA_SUCCESS on success, otherwise an error code. */ - ATCA_STATUS atcac_sw_sha2_256_update(struct atcac_sha2_256_ctx* ctx, const uint8_t* data, size_t data_size) { - sw_sha256_update((sw_sha256_ctx*)ctx, data, (uint32_t)data_size); - - return ATCA_SUCCESS; + return sw_sha256_update((sw_sha256_ctx*)ctx, data, (uint32_t)(data_size & UINT32_MAX)); } /** \brief completes the final SHA256 calculation and returns the final digest/hash * \param[in] ctx ptr to context data structure * \param[out] digest receives the computed digest of the SHA 256 - * \return ATCA_SUCCESS + * \return ATCA_SUCCESS on success, otherwise an error code. */ ATCA_STATUS atcac_sw_sha2_256_finish(struct atcac_sha2_256_ctx* ctx, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]) { - sw_sha256_final((sw_sha256_ctx*)ctx, digest); + return sw_sha256_final((sw_sha256_ctx*)ctx, digest); +} +#endif - return ATCA_SUCCESS; +#if ATCA_CRYPTO_SHA384_EN +/** \brief initializes the SHA384 software + * \param[in] ctx ptr to context data structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_init(struct atcac_sha2_384_ctx* ctx) +{ + return sw_sha384_init((sw_sha512_ctx*)ctx); +} + +/** \brief updates the running hash with the next block of data, called iteratively for the entire + stream of data to be hashed using the SHA384 software + \param[in] ctx ptr to SHA context data structure + \param[in] data ptr to next block of data to hash + \param[in] data_size size amount of data to hash in the given block, in bytes + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_update(struct atcac_sha2_384_ctx* ctx, const uint8_t* data, size_t data_size) +{ + return sw_sha384_update((sw_sha512_ctx*)ctx, data, (uint32_t)(data_size & UINT32_MAX)); } +/** \brief completes the final SHA384 calculation and returns the final digest/hash + * \param[in] ctx ptr to context data structure + * \param[out] digest receives the computed digest of the SHA 384 + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_finish(struct atcac_sha2_384_ctx* ctx, uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE]) +{ + return sw_sha384_final((sw_sha512_ctx*)ctx, digest); +} +#endif + +#if ATCA_CRYPTO_SHA512_EN +/** \brief initializes the SHA512 software + * \param[in] ctx ptr to context data structure + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_init(struct atcac_sha2_512_ctx* ctx) +{ + return sw_sha512_init((sw_sha512_ctx*)ctx); +} + +/** \brief updates the running hash with the next block of data, called iteratively for the entire + stream of data to be hashed using the SHA512 software + \param[in] ctx ptr to SHA context data structure + \param[in] data ptr to next block of data to hash + \param[in] data_size size amount of data to hash in the given block, in bytes + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_update(struct atcac_sha2_512_ctx* ctx, const uint8_t* data, size_t data_size) +{ + return sw_sha512_update((sw_sha512_ctx*)ctx, data, (uint32_t)(data_size & UINT32_MAX)); +} + +/** \brief completes the final SHA512 calculation and returns the final digest/hash + * \param[in] ctx ptr to context data structure + * \param[out] digest receives the computed digest of the SHA 512 + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_finish(struct atcac_sha2_512_ctx* ctx, uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE]) +{ + return sw_sha512_final((sw_sha512_ctx*)ctx, digest); +} +#endif + #if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) + +#if ATCA_CRYPTO_SHA256_EN struct atcac_sha2_256_ctx * atcac_sha256_ctx_new(void) { return (struct atcac_sha2_256_ctx*)hal_malloc(sizeof(atcac_sha2_256_ctx_t)); @@ -88,7 +152,28 @@ void atcac_sha256_ctx_free(struct atcac_sha2_256_ctx * ctx) } #endif -#endif /* ATCA_CRYPTO_SHA2_EN */ +#if ATCA_CRYPTO_SHA384_EN +struct atcac_sha2_384_ctx * atcac_sha384_ctx_new(void) +{ + return (struct atcac_sha2_384_ctx*)hal_malloc(sizeof(atcac_sha2_384_ctx_t)); +} +void atcac_sha384_ctx_free(struct atcac_sha2_384_ctx * ctx) +{ + hal_free(ctx); +} +#endif + +#if ATCA_CRYPTO_SHA512_EN +struct atcac_sha2_512_ctx * atcac_sha512_ctx_new(void) +{ + return (struct atcac_sha2_512_ctx*)hal_malloc(sizeof(atcac_sha2_512_ctx_t)); +} +void atcac_sha512_ctx_free(struct atcac_sha2_512_ctx * ctx) +{ + hal_free(ctx); +} +#endif /* ATCA_CRYPTO_SHA512_EN*/ +#endif /* ATCA_BUILD_SHARED_LIBS || ATCA_HEAP */ #if ATCAC_SHA256_EN /** \brief single call convenience function which computes Hash of given data using SHA256 software @@ -120,6 +205,67 @@ ATCA_STATUS atcac_sw_sha2_256(const uint8_t* data, size_t data_size, uint8_t dig } #endif /* ATCAC_SHA256_EN */ + +#if ATCAC_SHA384_EN +/** \brief single call convenience function which computes Hash of given data using SHA384 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. + */ +ATCA_STATUS atcac_sw_sha2_384(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE]) +{ + ATCA_STATUS ret; + atcac_sha2_384_ctx_t ctx; + + ret = atcac_sw_sha2_384_init(&ctx); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_384_update(&ctx, data, data_size); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_384_finish(&ctx, digest); + + return ret; +} +#endif /* ATCAC_SHA384_EN*/ + +#if ATCAC_SHA512_EN +/** \brief single call convenience function which computes Hash of given data using SHA512 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. + */ +ATCA_STATUS atcac_sw_sha2_512(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE]) +{ + ATCA_STATUS ret; + atcac_sha2_512_ctx_t ctx; + + ret = atcac_sw_sha2_512_init(&ctx); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_512_update(&ctx, data, data_size); + if (ret != ATCA_SUCCESS) + { + return ret; + } + + ret = atcac_sw_sha2_512_finish(&ctx, digest); + + return ret; +} +#endif /* ATCAC_SHA512_EN*/ + #if ATCA_CRYPTO_SHA2_HMAC_EN /** \brief Initialize context for performing HMAC (sha256) in software. * diff --git a/lib/crypto/atca_crypto_sw_sha2.h b/lib/crypto/atca_crypto_sw_sha2.h index 9938a4026..1d4a5ee3e 100644 --- a/lib/crypto/atca_crypto_sw_sha2.h +++ b/lib/crypto/atca_crypto_sw_sha2.h @@ -44,7 +44,9 @@ extern "C" { #endif +#if ATCAC_SHA256_EN ATCA_STATUS atcac_sw_sha2_256(const uint8_t * data, size_t data_size, uint8_t digest[ATCA_SHA2_256_DIGEST_SIZE]); +#endif ATCA_STATUS atcac_sha256_hmac_ctr_iteration(struct atcac_hmac_ctx* ctx, uint8_t iteration, uint16_t length, const uint8_t* label, size_t label_len, const uint8_t * data, size_t data_len, @@ -53,6 +55,14 @@ ATCA_STATUS atcac_sha256_hmac_ctr_iteration(struct atcac_hmac_ctx* ctx, uint8_t ATCA_STATUS atcac_sha256_hmac_counter(uint8_t * key, size_t key_len, const uint8_t* label, size_t label_len, const uint8_t* data, size_t data_len, uint8_t* digest, size_t diglen); +#if ATCAC_SHA384_EN +ATCA_STATUS atcac_sw_sha2_384(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE]); +#endif + +#if ATCAC_SHA512_EN +ATCA_STATUS atcac_sw_sha2_512(const uint8_t* data, size_t data_size, uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE]); +#endif + #ifdef __cplusplus } #endif diff --git a/lib/crypto/crypto_hw_config_check.h b/lib/crypto/crypto_hw_config_check.h index 0ef7499a4..ecf50ec23 100644 --- a/lib/crypto/crypto_hw_config_check.h +++ b/lib/crypto/crypto_hw_config_check.h @@ -34,7 +34,7 @@ #include "calib/calib_config_check.h" #endif -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) #include "talib/talib_config_check.h" #endif diff --git a/lib/crypto/crypto_sw_config_check.h b/lib/crypto/crypto_sw_config_check.h index b2851fbcd..345ed8e65 100644 --- a/lib/crypto/crypto_sw_config_check.h +++ b/lib/crypto/crypto_sw_config_check.h @@ -56,10 +56,29 @@ * * 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) +#define ATCAC_SHA256_EN (FEATURE_ENABLED) +#endif + +/** \def ATCAC_SHA384_EN + * + * Enable ATCAC_SHA384_EN to enable sha384 host side api + * + * Disabled by default. Enable ATCAC_SHA512_EN to use SHA384 + **/ +#ifndef ATCAC_SHA384_EN +#define ATCAC_SHA384_EN (FEATURE_DISABLED) +#endif + +/** \def ATCAC_SHA512_EN + * + * Enable ATCAC_SHA512_EN to enable sha512 host side api + * + * Disabled by default. Use FEATURE_ENABLED to enable this feature + **/ +#ifndef ATCAC_SHA512_EN +#define ATCAC_SHA512_EN (FEATURE_DISABLED) #endif /** \def ATCAC_SHA256_HMAC @@ -135,14 +154,40 @@ #define ATCA_CRYPTO_SHA1_EN (ATCAC_SHA1_EN && !ATCA_HOSTLIB_EN) #endif -/** \def ATCAC_SHA256_EN +/** \def ATCA_CRYPTO_SHA256_EN * - * Enable ATCAC_SHA256_EN to enable sha256 host side api + * Enable ATCA_CRYPTO_SHA256_EN to enable SHA2 host side api + * + **/ +#ifndef ATCA_CRYPTO_SHA256_EN +#define ATCA_CRYPTO_SHA256_EN ((ATCAC_SHA256_EN) && !ATCA_HOSTLIB_EN) +#endif + +/** \def ATCA_CRYPTO_SHA384_EN + * + * Enable ATCA_CRYPTO_SHA384_EN to enable SHA384 host side api + * + **/ +#ifndef ATCA_CRYPTO_SHA384_EN +#define ATCA_CRYPTO_SHA384_EN ((ATCAC_SHA384_EN) && !ATCA_HOSTLIB_EN) +#endif + +/** \def ATCA_CRYPTO_SHA512_EN + * + * Enable ATCA_CRYPTO_SHA512_EN to enable SHA2512 host side api + * + **/ +#ifndef ATCA_CRYPTO_SHA512_EN +#define ATCA_CRYPTO_SHA512_EN ((ATCAC_SHA512_EN) && !ATCA_HOSTLIB_EN) +#endif + +/** \def ATCA_CRYPTO_SHA2_EN + * + * Enable ATCAC_SHA2_EN to enable sha2 host side api * - * Supported API's: atcab_write **/ #ifndef ATCA_CRYPTO_SHA2_EN -#define ATCA_CRYPTO_SHA2_EN (ATCAC_SHA256_EN && !ATCA_HOSTLIB_EN) +#define ATCA_CRYPTO_SHA2_EN (ATCA_CRYPTO_SHA256_EN || ATCA_CRYPTO_SHA384_EN || ATCA_CRYPTO_SHA512_EN) #endif /** \def ATCA_CRYPTO_SHA2_HMAC_EN @@ -205,4 +250,25 @@ #define ATCAC_AES_GCM_EN (ATCA_HOSTLIB_EN) #endif /* ATCAC_AES_GCM_EN */ +/** \def ATCA_CRYPTO_AES_GCM_EN + * Enable ATCA_CRYPTO_AES_GCM_EN to enable AES GCM host side api + */ +#ifndef ATCA_CRYPTO_AES_GCM_EN +#define ATCA_CRYPTO_AES_GCM_EN (!ATCA_HOSTLIB_EN) +#endif /* ATCA_CRYPTO_AES_GCM_EN */ + +/** \def ATCAC_AES_CMAC_EN + * Indicates if this module is a provider of an AES-CMAC implementation + */ +#ifndef ATCAC_AES_CMAC_EN +#define ATCAC_AES_CMAC_EN (ATCA_HOSTLIB_EN) +#endif /* ATCAC_AES_CMAC_EN */ + +/** \def ATCA_CRYPTO_AES_CMAC_EN + * Enable ATCA_CRYPTO_AES_CMAC_EN to enable AES CMAC host side api + */ +#ifndef ATCA_CRYPTO_AES_CMAC_EN +#define ATCA_CRYPTO_AES_CMAC_EN (!ATCA_HOSTLIB_EN) +#endif /* ATCA_CRYPTO_AES_CMAC_EN */ + #endif /* CRYPTO_CONFIG_CHECK_H */ diff --git a/lib/crypto/hashes/sha2_routines.c b/lib/crypto/hashes/sha2_routines.c index d6051af9c..3593f7a6e 100644 --- a/lib/crypto/hashes/sha2_routines.c +++ b/lib/crypto/hashes/sha2_routines.c @@ -1,6 +1,6 @@ /** * \file - * \brief Software implementation of the SHA256 algorithm. + * \brief Software implementation of the SHA256, SHA384 and SHA512 algorithm. * * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. * @@ -28,20 +28,34 @@ #include "cryptoauthlib.h" #include "sha2_routines.h" -#define rotate_right(value, places) ((value >> places) | (value << (32 - places))) +#ifdef __COVERITY__ +#pragma coverity compliance block \ + (deviate "CERT INT30-C" "Wrap doesnt affect functionality for SHA") +#endif -#if ATCA_CRYPTO_SHA2_EN +#define rotate_right(value, places) (((value) >> (places)) | ((value) << (32U - (places)))) +#define rotate_right_64bit(value, places) (((value) >> (places)) | ((value) << (64U - (places)))) + +#if ATCA_CRYPTO_SHA256_EN /** * \brief Processes whole blocks (64 bytes) of data. * * \param[in] ctx SHA256 hash context * \param[in] blocks Raw blocks to be processed * \param[in] block_count Number of 64-byte blocks to process + * + * \return ATCA_SUCCESS on success, otherwise an error code. */ -static void sw_sha256_process(sw_sha256_ctx* ctx, const uint8_t* blocks, uint32_t block_count) +static ATCA_STATUS sw_sha256_process(sw_sha256_ctx* ctx, const uint8_t* blocks, uint32_t block_count) { - int i = 0; - uint32_t block = 0; + ATCA_STATUS status = ATCA_BAD_PARAM; + uint16_t i = 0u; + uint32_t block = 0u; + + if((NULL == ctx) || (NULL == blocks)) + { + return status; + } union { @@ -50,72 +64,73 @@ static void sw_sha256_process(sw_sha256_ctx* ctx, const uint8_t* blocks, uint32_ } w_union; static const uint32_t k[] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 + 0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU, 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, + 0xd807aa98U, 0x12835b01U, 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U, 0xc19bf174U, + 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU, 0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, + 0x983e5152U, 0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U, 0x06ca6351U, 0x14292967U, + 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU, 0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U, + 0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U, 0xd6990624U, 0xf40e3585U, 0x106aa070U, + 0x19a4c116U, 0x1e376c08U, 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU, 0x682e6ff3U, + 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U, 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U }; + (void)memset(&w_union, 0, sizeof(w_union)); + // Loop through all the blocks to process for (block = 0; block < block_count; block++) { - uint32_t w_index; - uint32_t word_value; - uint32_t s0, s1; - uint32_t t1, t2; - uint32_t maj, ch; - uint32_t rotate_register[8]; + uint32_t w_index = 0U; + uint32_t word_value = 0U; + uint32_t s0, s1 = 0U; + uint32_t t1, t2 = 0U; + uint32_t maj, ch = 0U; + uint32_t rotate_register[8] = {0U}; const uint8_t* cur_msg_block = &blocks[block * SHA256_BLOCK_SIZE]; // Swap word bytes - for (i = 0; i < SHA256_BLOCK_SIZE; i += 4) + for (i = 0U; i < SHA256_BLOCK_SIZE; i += 4U) { - w_union.w_byte[i + 3] = cur_msg_block[i + 0]; - w_union.w_byte[i + 2] = cur_msg_block[i + 1]; - w_union.w_byte[i + 1] = cur_msg_block[i + 2]; - w_union.w_byte[i + 0] = cur_msg_block[i + 3]; - w_union.w_word[i / 4] = ATCA_UINT32_HOST_TO_LE(w_union.w_word[i / 4]); + w_union.w_byte[i + 3U] = cur_msg_block[i + 0U]; + w_union.w_byte[i + 2U] = cur_msg_block[i + 1U]; + w_union.w_byte[i + 1U] = cur_msg_block[i + 2U]; + w_union.w_byte[i + 0U] = cur_msg_block[i + 3U]; + w_union.w_word[i / 4U] = ATCA_UINT32_HOST_TO_LE(w_union.w_word[i / 4U]); } - - w_index = 16; + w_index = 16u; while (w_index < SHA256_BLOCK_SIZE) { // right rotate for 32-bit variable in C: (value >> places) | (value << 32 - places) - word_value = w_union.w_word[w_index - 15]; - s0 = rotate_right(word_value, 7) ^ rotate_right(word_value, 18) ^ (word_value >> 3); + word_value = w_union.w_word[w_index - 15U]; + s0 = rotate_right(word_value, 7U) ^ rotate_right(word_value, 18U) ^ (word_value >> 3U); - word_value = w_union.w_word[w_index - 2]; - s1 = rotate_right(word_value, 17) ^ rotate_right(word_value, 19) ^ (word_value >> 10); + word_value = w_union.w_word[w_index - 2U]; + s1 = rotate_right(word_value, 17U) ^ rotate_right(word_value, 19U) ^ (word_value >> 10U); - w_union.w_word[w_index] = w_union.w_word[w_index - 16] + s0 + w_union.w_word[w_index - 7] + s1; + w_union.w_word[w_index] = w_union.w_word[w_index - 16U] + s0 + w_union.w_word[w_index - 7U] + s1; w_index++; } // Initialize hash value for this chunk. - for (i = 0; i < 8; i++) + for (i = 0U; i < 8U; i++) { rotate_register[i] = ctx->hash[i]; } // hash calculation loop - for (i = 0; i < SHA256_BLOCK_SIZE; i++) + for (i = 0U; i < SHA256_BLOCK_SIZE; i++) { - s0 = rotate_right(rotate_register[0], 2) - ^ rotate_right(rotate_register[0], 13) - ^ rotate_right(rotate_register[0], 22); + s0 = rotate_right(rotate_register[0], 2U) + ^ rotate_right(rotate_register[0], 13U) + ^ rotate_right(rotate_register[0], 22U); maj = (rotate_register[0] & rotate_register[1]) ^ (rotate_register[0] & rotate_register[2]) ^ (rotate_register[1] & rotate_register[2]); t2 = s0 + maj; - s1 = rotate_right(rotate_register[4], 6) - ^ rotate_right(rotate_register[4], 11) - ^ rotate_right(rotate_register[4], 25); + s1 = rotate_right(rotate_register[4], 6U) + ^ rotate_right(rotate_register[4], 11U) + ^ rotate_right(rotate_register[4], 25U); ch = (rotate_register[4] & rotate_register[5]) ^ (~rotate_register[4] & rotate_register[6]); t1 = rotate_register[7] + s1 + ch + k[i] + w_union.w_word[i]; @@ -131,32 +146,181 @@ static void sw_sha256_process(sw_sha256_ctx* ctx, const uint8_t* blocks, uint32_ } // Add the hash of this block to current result. - for (i = 0; i < 8; i++) + for (i = 0U; i < 8U; i++) { ctx->hash[i] += rotate_register[i]; } } + + return (status = ATCA_SUCCESS); } +#endif +#if ATCA_CRYPTO_SHA512_EN +/** + * \brief Processes whole blocks (128 bytes) of data. + * + * \param[in] ctx SHA512 hash context + * \param[in] blocks Raw blocks to be processed + * \param[in] block_count Number of 128-byte blocks to process + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +static ATCA_STATUS sw_sha512_process(sw_sha512_ctx* ctx, const uint8_t* blocks, uint32_t block_count) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + uint16_t i = 0u; + uint32_t block = 0u; + + if((NULL == ctx) || (NULL == blocks)) + { + return status; + } + + union + { + uint64_t w_dword[SHA512_BLOCK_SIZE]; + uint8_t w_byte[SHA512_BLOCK_SIZE * sizeof(uint64_t)]; + } w_union; + + static const uint64_t k[] = { + 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL, + 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL, + 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL, + 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL, + 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL, + 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL, + 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL, + 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL, + 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL, + 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL, + 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL, + 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL, + 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL, + 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL, + 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL, + 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL, + 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL, + 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL, + 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL, + 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL + }; + + (void)memset(&w_union, 0, sizeof(w_union)); + + // Loop through all the blocks to process + for (block = 0; block < block_count; block++) + { + uint32_t w_index =0U; + uint64_t word_value =0U; + uint64_t s0, s1 = 0U; + uint64_t t1, t2 = 0U; + uint64_t maj, ch = 0U ; + uint64_t rotate_register[8] = {0U}; + const uint8_t* cur_msg_block = &blocks[block * SHA512_BLOCK_SIZE]; + + // Swap word bytes + for (i = 0U; i < SHA512_BLOCK_SIZE; i += 8U) + { + w_union.w_byte[i + 7U] = cur_msg_block[i + 0U]; + w_union.w_byte[i + 6U] = cur_msg_block[i + 1U]; + w_union.w_byte[i + 5U] = cur_msg_block[i + 2U]; + w_union.w_byte[i + 4U] = cur_msg_block[i + 3U]; + w_union.w_byte[i + 3U] = cur_msg_block[i + 4U]; + w_union.w_byte[i + 2U] = cur_msg_block[i + 5U]; + w_union.w_byte[i + 1U] = cur_msg_block[i + 6U]; + w_union.w_byte[i + 0U] = cur_msg_block[i + 7U]; + w_union.w_dword[i / 8U] = ATCA_UINT64_HOST_TO_LE(w_union.w_dword[i / 8U]); + } + + w_index = 16u; + while (w_index < 80u) + { + // right rotate for 64-bit variable in C: (value >> places) | (value << 64 - places) + word_value = w_union.w_dword[w_index - 15u]; + s0 = (rotate_right_64bit(word_value, 1U)) ^ (rotate_right_64bit(word_value, 8U)) ^ (word_value >> 7U); + + word_value = w_union.w_dword[w_index - 2u]; + s1 = (rotate_right_64bit(word_value, 19U)) ^ (rotate_right_64bit(word_value, 61U)) ^ (word_value >> 6U); + + w_union.w_dword[w_index] = w_union.w_dword[w_index - 16u] + s0 + w_union.w_dword[w_index - 7u] + s1; + + w_index++; + } + + // Initialize hash value for this chunk. + for (i = 0U; i < 8U; i++) + { + rotate_register[i] = ctx->hash[i]; + } + + // hash calculation loop + for (i = 0U; i < 80U; i++) + { + s0 = (rotate_right_64bit(rotate_register[0], 28U)) + ^ (rotate_right_64bit(rotate_register[0], 34U)) + ^ (rotate_right_64bit(rotate_register[0], 39U)); + maj = (rotate_register[0] & rotate_register[1]) + ^ (rotate_register[0] & rotate_register[2]) + ^ (rotate_register[1] & rotate_register[2]); + t2 = s0 + maj; + s1 = (rotate_right_64bit(rotate_register[4], 14U)) + ^ (rotate_right_64bit(rotate_register[4], 18U)) + ^ (rotate_right_64bit(rotate_register[4], 41U)); + ch = (rotate_register[4] & rotate_register[5]) + ^ (~rotate_register[4] & rotate_register[6]); + t1 = rotate_register[7] + s1 + ch + k[i] + w_union.w_dword[i]; + + rotate_register[7] = rotate_register[6]; + rotate_register[6] = rotate_register[5]; + rotate_register[5] = rotate_register[4]; + rotate_register[4] = rotate_register[3] + t1; + rotate_register[3] = rotate_register[2]; + rotate_register[2] = rotate_register[1]; + rotate_register[1] = rotate_register[0]; + rotate_register[0] = t1 + t2; + } + + // Add the hash of this block to current result. + for (i = 0U; i < 8U; i++) + { + ctx->hash[i] += rotate_register[i]; + } + } + + return (status = ATCA_SUCCESS); +} +#endif + +#if ATCA_CRYPTO_SHA256_EN /** * \brief Intialize the software SHA256. * * \param[in] ctx SHA256 hash context + * + * \return ATCA_SUCCESS on success, otherwise an error code. */ - -void sw_sha256_init(sw_sha256_ctx* ctx) +ATCA_STATUS sw_sha256_init(sw_sha256_ctx* ctx) { + ATCA_STATUS status = ATCA_BAD_PARAM; static const uint32_t hash_init[] = { - 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, - 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 + 0x6a09e667U, 0xbb67ae85U, 0x3c6ef372U, 0xa54ff53aU, + 0x510e527fU, 0x9b05688cU, 0x1f83d9abU, 0x5be0cd19U }; int i; + if(NULL == ctx) + { + return status; + } + (void)memset(ctx, 0, sizeof(*ctx)); for (i = 0; i < 8; i++) { ctx->hash[i] = hash_init[i]; } + + return (status = ATCA_SUCCESS); } /** @@ -166,16 +330,26 @@ void sw_sha256_init(sw_sha256_ctx* ctx) * \param[in] ctx SHA256 hash context * \param[in] msg Raw blocks to be processed * \param[in] msg_size The size of the message passed + * + * \return ATCA_SUCCESS on success, otherwise an error code. */ -void sw_sha256_update(sw_sha256_ctx* ctx, const uint8_t* msg, uint32_t msg_size) +ATCA_STATUS sw_sha256_update(sw_sha256_ctx* ctx, const uint8_t* msg, uint32_t msg_size) { + ATCA_STATUS status = ATCA_BAD_PARAM; uint32_t block_count; + + if(NULL == ctx) + { + return status; + } + uint32_t rem_size = SHA256_BLOCK_SIZE - ctx->block_size; uint32_t copy_size = msg_size > rem_size ? rem_size : msg_size; if (0u == msg_size || NULL == msg) { - return; + status = ATCA_SUCCESS; + return status; } // Copy data into current block @@ -184,81 +358,434 @@ void sw_sha256_update(sw_sha256_ctx* ctx, const uint8_t* msg, uint32_t msg_size) if (ctx->block_size + msg_size < SHA256_BLOCK_SIZE) { // Not enough data to finish off the current block + // This data will be processed in sw_sha256_final ctx->block_size += msg_size; - return; + status = ATCA_SUCCESS; + return status; } // Process the current block - sw_sha256_process(ctx, ctx->block, 1); + if(ATCA_SUCCESS != (status = sw_sha256_process(ctx, ctx->block, 1))) + { + return status; + } // Process any additional blocks msg_size -= copy_size; // Adjust to the remaining message bytes block_count = msg_size / SHA256_BLOCK_SIZE; - sw_sha256_process(ctx, &msg[copy_size], block_count); + if(ATCA_SUCCESS != (status = sw_sha256_process(ctx, &msg[copy_size], block_count))) + { + return status; + } // Save any remaining data - ctx->total_msg_size += (block_count + 1) * SHA256_BLOCK_SIZE; + ctx->total_msg_size += (block_count + 1U) * SHA256_BLOCK_SIZE; ctx->block_size = msg_size % SHA256_BLOCK_SIZE; (void)memcpy(ctx->block, &msg[copy_size + block_count * SHA256_BLOCK_SIZE], (size_t)ctx->block_size); + + return status; } /** \brief completes the final SHA256 calculation and returns the final digest/hash * \param[in] ctx ptr to context data structure * \param[out] digest receives the computed digest of the SHA 256 + * + * \return ATCA_SUCCESS on success, otherwise an error code. */ -void sw_sha256_final(sw_sha256_ctx* ctx, uint8_t digest[SHA256_DIGEST_SIZE]) +ATCA_STATUS sw_sha256_final(sw_sha256_ctx* ctx, uint8_t digest[SHA256_DIGEST_SIZE]) { - int32_t i, j; - uint32_t msg_size_bits; - uint32_t pad_zero_count; + ATCA_STATUS status = ATCA_BAD_PARAM; + int32_t i, j; + uint32_t msg_size_bits = 0U; + uint32_t pad_zero_count = 0u; + int32_t byte_cnt = (int32_t)(sizeof(uint32_t)); + + if(NULL == ctx) + { + return status; + } // Calculate the total message size in bits ctx->total_msg_size += ctx->block_size; - msg_size_bits = ctx->total_msg_size * 8; + + if(true == IS_MUL_SAFE_UINT32_T(ctx->total_msg_size, 8U)) + { + msg_size_bits = ctx->total_msg_size * 8U; + } // Calculate the number of padding zero bytes required between the 1 bit byte and the 64 bit message size in bits. - pad_zero_count = (SHA256_BLOCK_SIZE - ((ctx->block_size + 9) % SHA256_BLOCK_SIZE)) % SHA256_BLOCK_SIZE; + pad_zero_count = (SHA256_BLOCK_SIZE - ((ctx->block_size + 9U) % SHA256_BLOCK_SIZE)) % SHA256_BLOCK_SIZE; // Append a single 1 bit ctx->block[ctx->block_size++] = 0x80; // Add padding zeros plus upper 4 bytes of total msg size in bits (only supporting 32bit message bit counts) - (void)memset(&ctx->block[ctx->block_size], 0, (size_t)pad_zero_count + 4); - ctx->block_size += pad_zero_count + 4; + (void)memset(&ctx->block[ctx->block_size], 0, (size_t)pad_zero_count + 4U); + + pad_zero_count +=4U; + + if(true == IS_ADD_SAFE_UINT32_T(ctx->block_size, pad_zero_count)) + { + ctx->block_size += pad_zero_count; + } // Add the total message size in bits to the end of the current block. Technically this is // supposed to be 8 bytes. This shortcut will reduce the max message size to 536,870,911 bytes. - ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 24); - ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 16); - ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 8); - ctx->block[ctx->block_size++] = (uint8_t)(msg_size_bits >> 0); + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 24U) & UINT8_MAX); + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 16U) & UINT8_MAX); + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 8U) & UINT8_MAX); + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 0U) & UINT8_MAX); - sw_sha256_process(ctx, ctx->block, ctx->block_size / SHA256_BLOCK_SIZE); + if(ATCA_SUCCESS != (status = sw_sha256_process(ctx, ctx->block, ctx->block_size / SHA256_BLOCK_SIZE))) + { + return status; + } // All blocks have been processed. // Concatenate the hashes to produce digest, MSB of every hash first. for (i = 0; i < 8; i++) { - for (j = sizeof(int32_t) - 1; j >= 0; j--, ctx->hash[i] >>= 8) + for (j = byte_cnt - 1; j >= 0; j--) { - digest[i * sizeof(int32_t) + j] = ctx->hash[i] & 0xFF; + if ((i <= (INT32_MAX / byte_cnt)) && ((i * byte_cnt) <= (INT32_MAX - j))) + { + digest[i * byte_cnt + j] = (uint8_t)(ctx->hash[i] & 0xFFu); + } + ctx->hash[i] >>= 8u; } } + + return status; } /** \brief single call convenience function which computes Hash of given data using SHA256 software * \param[in] message pointer to stream of data to hash * \param[in] len size of data stream to hash * \param[out] digest result + * + * \return ATCA_SUCCESS on success, otherwise an error code. */ -void sw_sha256(const uint8_t* message, unsigned int len, uint8_t digest[SHA256_DIGEST_SIZE]) +ATCA_STATUS sw_sha256(const uint8_t* message, unsigned int len, uint8_t digest[SHA256_DIGEST_SIZE]) { + ATCA_STATUS status; sw_sha256_ctx ctx; - sw_sha256_init(&ctx); - sw_sha256_update(&ctx, message, len); - sw_sha256_final(&ctx, digest); + if(ATCA_SUCCESS == (status = sw_sha256_init(&ctx))) + { + if(ATCA_SUCCESS == (status = sw_sha256_update(&ctx, message, len))) + { + status = sw_sha256_final(&ctx, digest); + } + } + + return status; +} +#endif + +#if ATCA_CRYPTO_SHA512_EN +/** + * \brief Intialize the software SHA512. + * + * \param[in] ctx SHA512 hash context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +ATCA_STATUS sw_sha512_init(sw_sha512_ctx* ctx) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + int i; + + if(NULL == ctx) + { + return status; + } + + static const uint64_t hash_init[] = { + 0x6a09e667f3bcc908U, 0xbb67ae8584caa73bU, 0x3c6ef372fe94f82bU, 0xa54ff53a5f1d36f1U, + 0x510e527fade682d1U, 0x9b05688c2b3e6c1fU, 0x1f83d9abfb41bd6bU, 0x5be0cd19137e2179U + }; + + (void)memset(ctx, 0, sizeof(*ctx)); + for (i = 0; i < 8; i++) + { + ctx->hash[i] = hash_init[i]; + } + + return (status = ATCA_SUCCESS); +} + +/** + * \brief updates the running hash with the next block of data, called iteratively for the entire + * stream of data to be hashed using the SHA512 software + * + * \param[in] ctx SHA512 hash context + * \param[in] msg Raw blocks to be processed + * \param[in] msg_size The size of the message passed + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS sw_sha512_update(sw_sha512_ctx* ctx, const uint8_t* msg, uint32_t msg_size) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + uint32_t block_count; + uint32_t tmp_size = 0U; + + if(NULL == ctx) + { + return status; + } + + uint32_t rem_size = SHA512_BLOCK_SIZE - ctx->block_size; + uint32_t copy_size = msg_size > rem_size ? rem_size : msg_size; + + if (0u == msg_size || NULL == msg) + { + status = ATCA_SUCCESS; + return status; + } + + // Copy data into current block + (void)memcpy(&ctx->block[ctx->block_size], msg, copy_size); + + if(true == IS_ADD_SAFE_UINT32_T(ctx->block_size, msg_size)) + { + if (ctx->block_size + msg_size < SHA512_BLOCK_SIZE) + { + // Not enough data to finish off the current block + // This data will be processed in sw_sha512_final + ctx->block_size += msg_size; + status = ATCA_SUCCESS; + return status; + } + } + + // Process the current block + if(ATCA_SUCCESS != (status = sw_sha512_process(ctx, ctx->block, 1))) + { + return status; + } + + // Process any additional blocks + msg_size -= copy_size; // Adjust to the remaining message bytes + block_count = msg_size / SHA512_BLOCK_SIZE; + if(ATCA_SUCCESS != (status = sw_sha512_process(ctx, &msg[copy_size], block_count))) + { + return status; + } + + // Save any remaining data + if(true == IS_ADD_SAFE_UINT32_T(block_count, 1U)) + { + tmp_size = block_count + 1U; + } + + if(true == IS_MUL_SAFE_UINT32_T(tmp_size, SHA512_BLOCK_SIZE)) + { + tmp_size *= SHA512_BLOCK_SIZE; + } + + if(true == IS_ADD_SAFE_UINT32_T(ctx->total_msg_size, tmp_size)) + { + ctx->total_msg_size += tmp_size; + } + + ctx->block_size = msg_size % SHA512_BLOCK_SIZE; + (void)memcpy(ctx->block, &msg[copy_size + block_count * SHA512_BLOCK_SIZE], (size_t)ctx->block_size); + + return status; +} + +/** \brief completes the final SHA512 calculation and returns the final digest/hash + * \param[in] ctx ptr to context data structure + * \param[out] digest receives the computed digest of the SHA 512 + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS sw_sha512_final(sw_sha512_ctx* ctx, uint8_t digest[SHA512_DIGEST_SIZE]) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + int32_t i, j; + uint32_t msg_size_bits = 0u; + uint32_t pad_zero_count = 0u; + int32_t byte_cnt = (int32_t)(sizeof(uint64_t)); + + if (NULL == ctx) + { + return status; + } + + // Calculate the total message size in bits + if(true == IS_ADD_SAFE_UINT32_T(ctx->total_msg_size, ctx->block_size)) + { + ctx->total_msg_size += ctx->block_size; + } + + if(true == IS_MUL_SAFE_UINT32_T(ctx->total_msg_size, 8U)) + { + msg_size_bits = ctx->total_msg_size * 8U; + } + + // Calculate the number of padding zero bytes required between the 1 bit byte and the 128 bit message size in bits. + pad_zero_count = (SHA512_BLOCK_SIZE - ((ctx->block_size + 17u) % SHA512_BLOCK_SIZE)) % SHA512_BLOCK_SIZE; + + // Append a single 1 bit + ctx->block[ctx->block_size++] = 0x80; + + // Add padding zeros plus upper 12 bytes of total msg size in bits (only supporting 32bit message bit counts) + (void)memset(&ctx->block[ctx->block_size], 0, (size_t)pad_zero_count + 12U); + + pad_zero_count += 12U; + + if(true == IS_ADD_SAFE_UINT32_T(ctx->block_size, pad_zero_count)) + { + ctx->block_size += pad_zero_count; + } + + // Add the total message size in bits to the end of the current block. Technically this is + // supposed to be 8 bytes. This shortcut will reduce the max message size to 536,870,911 bytes. + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 24) & UINT8_MAX); + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 16) & UINT8_MAX); + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 8)& UINT8_MAX); + ctx->block[ctx->block_size++] = (uint8_t)((msg_size_bits >> 0)& UINT8_MAX); + + if(ATCA_SUCCESS != (status = sw_sha512_process(ctx, ctx->block, ctx->block_size / SHA512_BLOCK_SIZE))) + { + return status; + } + + // All blocks have been processed. + // Concatenate the hashes to produce digest, MSB of every hash first. + for (i = 0; i < 8; i++) + { + for (j = byte_cnt - 1; j >= 0; j--) + { + if ((i <= (INT32_MAX / byte_cnt)) && ((i * byte_cnt) <= (INT32_MAX - j))) + { + digest[i * byte_cnt + j] = (uint8_t)(ctx->hash[i] & 0xFFu); + } + ctx->hash[i] >>= 8u; + } + } + + return status; +} + +/** \brief single call convenience function which computes Hash of given data using SHA512 software + * \param[in] message pointer to stream of data to hash + * \param[in] len size of data stream to hash + * \param[out] digest result + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS sw_sha512(const uint8_t* message, unsigned int len, uint8_t digest[SHA512_DIGEST_SIZE]) +{ + ATCA_STATUS status; + sw_sha512_ctx ctx; + + if(ATCA_SUCCESS == (status = sw_sha512_init(&ctx))) + { + if(ATCA_SUCCESS == (status = sw_sha512_update(&ctx, message, len))) + { + status = sw_sha512_final(&ctx, digest); + } + } + + return status; +} +#endif + +#if ATCA_CRYPTO_SHA384_EN +/** + * \brief Intialize the software SHA384. + * + * \param[in] ctx SHA384 hash context + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ + +ATCA_STATUS sw_sha384_init(sw_sha512_ctx* ctx) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + int i; + + if(NULL == ctx) + { + return status; + } + + static const uint64_t hash_init[] = { + 0xcbbb9d5dc1059ed8U, 0x629a292a367cd507U, 0x9159015a3070dd17U, 0x152fecd8f70e5939U, + 0x67332667ffc00b31U, 0x8eb44a8768581511U, 0xdb0c2e0d64f98fa7U, 0x47b5481dbefa4fa4U + }; + + (void)memset(ctx, 0, sizeof(*ctx)); + for (i = 0; i < 8; i++) + { + ctx->hash[i] = hash_init[i]; + } + + return (status = ATCA_SUCCESS); +} + +/** + * \brief updates the running hash with the next block of data, called iteratively for the entire + * stream of data to be hashed using the SHA384 software + * + * \param[in] ctx SHA384 hash context + * \param[in] msg Raw blocks to be processed + * \param[in] msg_size The size of the message passed + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS sw_sha384_update(sw_sha512_ctx* ctx, const uint8_t* msg, uint32_t msg_size) +{ + ATCA_STATUS status; + status = sw_sha512_update(ctx, msg, msg_size); + return status; +} + + +/** \brief completes the final SHA384 calculation and returns the final digest/hash + * \param[in] ctx ptr to context data structure + * \param[out] digest receives the computed digest of the SHA 384 + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS sw_sha384_final(sw_sha512_ctx* ctx, uint8_t digest[SHA384_DIGEST_SIZE]) +{ + ATCA_STATUS status; + uint8_t tmp_dgst[SHA512_DIGEST_SIZE] = {0u}; + + status = sw_sha512_final(ctx, tmp_dgst); + // For SHA384 copy only 48 bytes to O/P digest + (void)memcpy(digest, tmp_dgst, SHA384_DIGEST_SIZE); + + return status; +} + +/** \brief single call convenience function which computes Hash of given data using SHA384 software + * \param[in] message pointer to stream of data to hash + * \param[in] len size of data stream to hash + * \param[out] digest result + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS sw_sha384(const uint8_t* message, unsigned int len, uint8_t digest[SHA384_DIGEST_SIZE]) +{ + ATCA_STATUS status; + sw_sha512_ctx ctx; + + if(ATCA_SUCCESS == (status = sw_sha384_init(&ctx))) + { + if(ATCA_SUCCESS == (status = sw_sha384_update(&ctx, message, len))) + { + status = sw_sha384_final(&ctx, digest); + } + } + + return status; } -#endif /* ATCA_CRYPTO_SHA2_EN */ +#endif diff --git a/lib/crypto/hashes/sha2_routines.h b/lib/crypto/hashes/sha2_routines.h index 09a036b84..fe81ca639 100644 --- a/lib/crypto/hashes/sha2_routines.h +++ b/lib/crypto/hashes/sha2_routines.h @@ -1,6 +1,6 @@ /** * \file - * \brief Software implementation of the SHA256 algorithm. + * \brief Software implementation of the SHA256, SHA384 and SHA512 algorithm. * * \copyright (c) 2015-2020 Microchip Technology Inc. and its subsidiaries. * @@ -31,17 +31,34 @@ #include #ifndef SHA256_DIGEST_SIZE -#define SHA256_DIGEST_SIZE (32) +#define SHA256_DIGEST_SIZE (32U) +#endif + +#ifndef SHA512_DIGEST_SIZE +#define SHA512_DIGEST_SIZE (64U) +#endif + +#ifndef SHA384_DIGEST_SIZE +#define SHA384_DIGEST_SIZE (48U) #endif #ifndef SHA256_BLOCK_SIZE -#define SHA256_BLOCK_SIZE (64) +#define SHA256_BLOCK_SIZE (64U) +#endif + +#ifndef SHA384_BLOCK_SIZE +#define SHA384_BLOCK_SIZE (128U) +#endif + +#ifndef SHA512_BLOCK_SIZE +#define SHA512_BLOCK_SIZE (128U) #endif #ifdef __cplusplus extern "C" { #endif +#if ATCA_CRYPTO_SHA256_EN typedef struct { uint32_t total_msg_size; //!< Total number of message bytes processed @@ -49,14 +66,41 @@ typedef struct uint8_t block[SHA256_BLOCK_SIZE * 2]; //!< Unprocessed message storage uint32_t hash[8]; //!< Hash state } sw_sha256_ctx; +#endif -void sw_sha256_init(sw_sha256_ctx* ctx); +#if ATCA_CRYPTO_SHA512_EN +typedef struct +{ + uint32_t total_msg_size; //!< Total number of message bytes processed + uint32_t block_size; //!< Number of bytes in current block + uint8_t block[SHA512_BLOCK_SIZE * 2]; //!< Unprocessed message storage + uint64_t hash[8]; //!< Hash state +} sw_sha512_ctx; +#endif -void sw_sha256_update(sw_sha256_ctx* ctx, const uint8_t* message, uint32_t len); +#if ATCA_CRYPTO_SHA256_EN +// SHA256 +ATCA_STATUS sw_sha256_init(sw_sha256_ctx* ctx); +ATCA_STATUS sw_sha256_update(sw_sha256_ctx* ctx, const uint8_t* msg, uint32_t msg_size); +ATCA_STATUS sw_sha256_final(sw_sha256_ctx* ctx, uint8_t digest[SHA256_DIGEST_SIZE]); +ATCA_STATUS sw_sha256(const uint8_t * message, unsigned int len, uint8_t digest[SHA256_DIGEST_SIZE]); +#endif -void sw_sha256_final(sw_sha256_ctx * ctx, uint8_t digest[SHA256_DIGEST_SIZE]); +#if ATCA_CRYPTO_SHA384_EN +// SHA384 +ATCA_STATUS sw_sha384_init(sw_sha512_ctx* ctx); +ATCA_STATUS sw_sha384_update(sw_sha512_ctx* ctx, const uint8_t* msg, uint32_t msg_size); +ATCA_STATUS sw_sha384_final(sw_sha512_ctx * ctx, uint8_t digest[SHA384_DIGEST_SIZE]); +ATCA_STATUS sw_sha384(const uint8_t * message, unsigned int len, uint8_t digest[SHA384_DIGEST_SIZE]); +#endif -void sw_sha256(const uint8_t * message, unsigned int len, uint8_t digest[SHA256_DIGEST_SIZE]); +#if ATCA_CRYPTO_SHA512_EN +//sha512 +ATCA_STATUS sw_sha512_init(sw_sha512_ctx* ctx); +ATCA_STATUS sw_sha512_update(sw_sha512_ctx* ctx, const uint8_t* msg, uint32_t msg_size); +ATCA_STATUS sw_sha512_final(sw_sha512_ctx * ctx, uint8_t digest[SHA512_DIGEST_SIZE]); +ATCA_STATUS sw_sha512(const uint8_t * message, unsigned int len, uint8_t digest[SHA512_DIGEST_SIZE]); +#endif #ifdef __cplusplus } diff --git a/lib/cryptoauthlib.h b/lib/cryptoauthlib.h index dfd29051e..aaca7a6ae 100644 --- a/lib/cryptoauthlib.h +++ b/lib/cryptoauthlib.h @@ -69,9 +69,12 @@ #define ATCA_KEY_TYPE_ECCP256 (0u) #define ATCA_ECCP256_KEY_SIZE (32u) #define ATCA_ECCP256_PUBKEY_SIZE (64u) +#define ATCA_ECCP256_PVTKEY_SIZE (32u) #define ATCA_ECCP256_SIG_SIZE (64u) #define ATCA_ECCP256_OID_SIZE (10u) #define ATCA_ECCP256_ASN1_HDR_SIZE (27u) +#define ATCA_MAX_ECC_RSA_PB_KEY_SIZE (512u) +#define ATCA_RSA4K_ASN1_HDR_SIZE (33u) #define ATCA_ECC_UNCOMPRESSED_TYPE ((uint8_t)0x04) #define ATCA_ECC_UNCOMPRESSED_TYPE_OFFSET (1u) @@ -106,11 +109,16 @@ #include "calib/calib_basic.h" #include "calib/calib_command.h" #include "calib/calib_aes_gcm.h" +#include "calib/calib_packet.h" #endif #if ATCA_TA_SUPPORT +#ifndef LIBRARY_USAGE_EN #include "talib/talib_status.h" #include "talib/talib_basic.h" +#else +#include "ta_app.h" +#endif #endif /* Common Library Functions */ diff --git a/lib/hal/atca_hal.h b/lib/hal/atca_hal.h index a8a2a97d1..d2610cfb8 100644 --- a/lib/hal/atca_hal.h +++ b/lib/hal/atca_hal.h @@ -30,7 +30,10 @@ #define ATCA_HAL_H_ #include + +#ifndef LIBRARY_BUILD_EN #include "atca_config.h" +#endif #include "atca_status.h" #include "atca_iface.h" diff --git a/lib/hal/hal_spi_harmony.c b/lib/hal/hal_spi_harmony.c index 0ddd51709..5f4f2b377 100644 --- a/lib/hal/hal_spi_harmony.c +++ b/lib/hal/hal_spi_harmony.c @@ -37,8 +37,11 @@ #include "atca_hal.h" #include "atca_device.h" #include "definitions.h" + +#ifndef LIBRARY_USAGE_EN #include "talib/talib_defines.h" #include "talib/talib_fce.h" +#endif /** \defgroup hal_ Hardware abstraction layer (hal_) * diff --git a/lib/mbedtls/atca_mbedtls_interface.h b/lib/mbedtls/atca_mbedtls_interface.h index cd94a1600..acb7d51e8 100644 --- a/lib/mbedtls/atca_mbedtls_interface.h +++ b/lib/mbedtls/atca_mbedtls_interface.h @@ -54,10 +54,36 @@ #if defined(MBEDTLS_CONFIG_H) && !defined(MBEDTLS_SHA256_C) #define ATCAC_SHA256_EN (DEFAULT_DISABLED) #else -#define ATCAC_SHA256_EN (DEFAULT_ENABLED) +#define ATCAC_SHA256_EN (FEATURE_ENABLED) #endif #endif /* ATCAC_SHA256_EN */ +/** \def ATCAC_SHA384_EN + * Indicates if this module is a provider of a SHA384 implementation + * + * Disabled by default. Use FEATURE_ENABLED to use SHA384 + */ +#ifndef ATCAC_SHA384_EN +#if defined(MBEDTLS_CONFIG_H) && !defined(MBEDTLS_SHA384_C) +#define ATCAC_SHA384_EN (DEFAULT_DISABLED) +#else +#define ATCAC_SHA384_EN (FEATURE_DISABLED) +#endif +#endif /* ATCAC_SHA384_EN */ + +/** \def ATCAC_SHA512_EN + * Indicates if this module is a provider of a SHA512 implementation + * + * Disabled by default. Use FEATURE_ENABLED to use SHA512 + */ +#ifndef ATCAC_SHA512_EN +#if defined(MBEDTLS_CONFIG_H) && !defined(MBEDTLS_SHA512_C) +#define ATCAC_SHA512_EN (DEFAULT_DISABLED) +#else +#define ATCAC_SHA512_EN (FEATURE_DISABLED) +#endif +#endif /* ATCAC_SHA512_EN */ + /** \def ATCAC_AES_CMAC_EN * Indicates if this module is a provider of an AES-CMAC implementation */ diff --git a/lib/mbedtls/atca_mbedtls_wrap.c b/lib/mbedtls/atca_mbedtls_wrap.c index c1d6d0ca6..a969b0c02 100644 --- a/lib/mbedtls/atca_mbedtls_wrap.c +++ b/lib/mbedtls/atca_mbedtls_wrap.c @@ -32,7 +32,8 @@ #ifdef __COVERITY__ #pragma coverity compliance block \ (deviate "CERT EXP40-C" "The third party mbedtls api converts const to non constant which is out of scope of CAL") \ - (deviate "MISRA C-2012 Rule 11.8" "Third party library (mbedtls) implementation which require const to non constant") + (deviate "MISRA C-2012 Rule 11.8" "Third party library (mbedtls) implementation which require const to non constant")\ + (deviate "MISRA C-2012 Rule 11.3" "Third party library (mbedtls) implementation requires pointer type casting") #endif #ifdef ATCA_MBEDTLS @@ -78,10 +79,26 @@ struct atcac_sha1_ctx* atcac_sha1_ctx_new(void) return (struct atcac_sha1_ctx*)hal_malloc(sizeof(atcac_sha1_ctx_t)); } +#if ATCAC_SHA256_EN struct atcac_sha2_256_ctx* atcac_sha256_ctx_new(void) { return (struct atcac_sha2_256_ctx*)hal_malloc(sizeof(atcac_sha2_256_ctx_t)); } +#endif + +#if ATCAC_SHA384_EN +struct atcac_sha2_384_ctx* atcac_sha384_ctx_new(void) +{ + return (struct atcac_sha2_384_ctx*)hal_malloc(sizeof(atcac_sha2_384_ctx_t)); +} +#endif + +#if ATCAC_SHA512_EN +struct atcac_sha2_512_ctx* atcac_sha512_ctx_new(void) +{ + return (struct atcac_sha2_512_ctx*)hal_malloc(sizeof(atcac_sha2_512_ctx_t)); +} +#endif struct atcac_hmac_ctx* atcac_hmac_ctx_new(void) { @@ -118,10 +135,26 @@ void atcac_sha1_ctx_free(struct atcac_sha1_ctx* ctx) hal_free(ctx); } +#if ATCAC_SHA256_EN void atcac_sha256_ctx_free(struct atcac_sha2_256_ctx* ctx) { hal_free(ctx); } +#endif + +#if ATCAC_SHA384_EN +void atcac_sha384_ctx_free(struct atcac_sha2_384_ctx* ctx) +{ + hal_free(ctx); +} +#endif + +#if ATCAC_SHA512_EN +void atcac_sha512_ctx_free(struct atcac_sha2_512_ctx* ctx) +{ + hal_free(ctx); +} +#endif void atcac_hmac_ctx_free(struct atcac_hmac_ctx* ctx) { @@ -475,6 +508,7 @@ ATCA_STATUS atcac_sw_sha1_finish( return atca_mbedtls_md_finish((mbedtls_md_context_t*)tmp_ptr, digest, NULL); } +#if ATCAC_SHA256_EN /** \brief Initialize context for performing SHA256 hash in software. * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -516,6 +550,95 @@ ATCA_STATUS atcac_sw_sha2_256_finish( return atca_mbedtls_md_finish((mbedtls_md_context_t*)tmp_ptr, digest, NULL); } +#endif /* ATCAC_SHA256_EN */ + +#if ATCAC_SHA384_EN +/** \brief Initialize context for performing SHA384 hash in software. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_init( + struct atcac_sha2_384_ctx* ctx /**< [in] pointer to a hash context */ + ) +{ + void* tmp_ptr = ctx; + + return atca_mbedtls_md_init((mbedtls_md_context_t*)tmp_ptr, mbedtls_md_info_from_type(MBEDTLS_MD_SHA384)); +} + +/** \brief Add data to a SHA384 hash. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_update( + struct atcac_sha2_384_ctx* ctx, /**< [in] pointer to a hash context */ + const uint8_t* data, /**< [in] input data buffer */ + size_t data_size /**< [in] input data length */ + ) +{ + void* tmp_ptr = ctx; + + return atca_mbedtls_md_update((mbedtls_md_context_t*)tmp_ptr, data, data_size); +} + +/** \brief Complete the SHA384 hash in software and return the digest. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_finish( + struct atcac_sha2_384_ctx* ctx, /**< [in] pointer to a hash context */ + uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE] /**< [out] output buffer (48 bytes) */ + ) +{ + void* tmp_ptr = ctx; + + return atca_mbedtls_md_finish((mbedtls_md_context_t*)tmp_ptr, digest, NULL); +} +#endif /* ATCAC_SHA384_EN */ + +#if ATCAC_SHA512_EN +/** \brief Initialize context for performing SHA512 hash in software. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_init( + struct atcac_sha2_512_ctx* ctx /**< [in] pointer to a hash context */ + ) +{ + void* tmp_ptr = ctx; + + return atca_mbedtls_md_init((mbedtls_md_context_t*)tmp_ptr, mbedtls_md_info_from_type(MBEDTLS_MD_SHA512)); +} + +/** \brief Add data to a SHA512 hash. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_update( + struct atcac_sha2_512_ctx* ctx, /**< [in] pointer to a hash context */ + const uint8_t* data, /**< [in] input data buffer */ + size_t data_size /**< [in] input data length */ + ) +{ + void* tmp_ptr = ctx; + + return atca_mbedtls_md_update((mbedtls_md_context_t*)tmp_ptr, data, data_size); +} + +/** \brief Complete the SHA512 hash in software and return the digest. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_finish( + struct atcac_sha2_512_ctx* ctx, /**< [in] pointer to a hash context */ + uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE] /**< [out] output buffer (64 bytes) */ + ) +{ + void* tmp_ptr = ctx; + + return atca_mbedtls_md_finish((mbedtls_md_context_t*)tmp_ptr, digest, NULL); +} +#endif /* ATCAC_SHA512_EN*/ /** \brief Initialize context for performing CMAC in software. * @@ -1405,42 +1528,72 @@ ATCA_STATUS atcac_get_subj_public_key(const struct atcac_x509_ctx* cert, cal_buf const void* tmp_ptr = cert; const mbedtls_x509_crt* x509_cert = (const mbedtls_x509_crt*)(tmp_ptr); const mbedtls_pk_context *pk = (const mbedtls_pk_context *)&x509_cert->pk; - if (mbedtls_pk_get_type(pk) != MBEDTLS_PK_ECKEY) + + if (MBEDTLS_PK_ECKEY == mbedtls_pk_get_type(pk)) { - return status; + // Extract the Qx and Qy values of the EC public key + const mbedtls_ecp_keypair* ec = mbedtls_pk_ec(*pk); + if (NULL == ec) + { + return status; + } + + // Calculate the expected buffer length for both Qx and Qy + size_t expected_len = mbedtls_mpi_size(&ec->Q.X) + mbedtls_mpi_size(&ec->Q.Y); + + // Check if subj_public_key buffer is large enough + if (subj_public_key->len < expected_len) + { + return status; // Error: Buffer too small + } + + // Write the binary representation of Qx into the buffer + size_t bytes_written = 0; + int ret = mbedtls_mpi_write_binary(&ec->Q.X, subj_public_key->buf, mbedtls_mpi_size(&ec->Q.X)); + if (ret != 0) + { + return status; // Error: writing Qx to buffer failed + } + bytes_written += mbedtls_mpi_size(&ec->Q.X); + + // Write the binary representation of Qy into the buffer + ret = mbedtls_mpi_write_binary(&ec->Q.Y, subj_public_key->buf + bytes_written, mbedtls_mpi_size(&ec->Q.Y)); + if (ret != 0) + { + return status; // Error: writing Qy to buffer failed + } + + subj_public_key->len = expected_len; + status = ATCA_SUCCESS; } - // Extract the Qx and Qy values of the public key - const mbedtls_ecp_keypair* ec = mbedtls_pk_ec(*pk); - if (NULL == ec) + else { - return status; - } + // Extract the RSA public key + const mbedtls_rsa_context* rsa = mbedtls_pk_rsa(*pk); + if (NULL == rsa) + { + return status; + } - // Calculate the expected buffer length for both Qx and Qy - size_t expected_len = mbedtls_mpi_size(&ec->Q.X) + mbedtls_mpi_size(&ec->Q.Y); + // Calculate the expected buffer length for the modulus (N) + size_t expected_len = mbedtls_mpi_size(&rsa->N); - // Check if subj_public_key buffer is large enough - if (subj_public_key->len < expected_len) - { - return status; // Error: Buffer too small - } + // Check if subj_public_key buffer is large enough + if (subj_public_key->len < expected_len) + { + return status; // Error: Buffer too small + } - // Write the binary representation of Qx into the buffer - size_t bytes_written = 0; - int ret = mbedtls_mpi_write_binary(&ec->Q.X, subj_public_key->buf, mbedtls_mpi_size(&ec->Q.X)); - if (ret != 0) - { - return status; // Error: writing Qx to buffer failed - } - bytes_written += mbedtls_mpi_size(&ec->Q.X); + // Write the binary representation of the modulus (N) into the buffer + int ret = mbedtls_mpi_write_binary(&rsa->N, subj_public_key->buf, mbedtls_mpi_size(&rsa->N)); + if (ret != 0) + { + return status; // Error: writing modulus N to buffer failed + } - // Write the binary representation of Qy into the buffer - ret = mbedtls_mpi_write_binary(&ec->Q.Y, subj_public_key->buf + bytes_written, mbedtls_mpi_size(&ec->Q.Y)); - if (ret != 0) - { - return status; // Error: writing Qy to buffer failed + subj_public_key->len = expected_len; + status = ATCA_SUCCESS; } - status = ATCA_SUCCESS; } return status; } @@ -1636,6 +1789,7 @@ ATCA_STATUS atcac_get_cert_sn(const struct atcac_x509_ctx* cert, cal_buffer* cer ATCA_STATUS atcac_get_auth_key_id(const struct atcac_x509_ctx* cert, cal_buffer* auth_key_id) { ATCA_STATUS status = ATCA_BAD_PARAM; + bool akid_found = false; if (NULL != cert && NULL != auth_key_id) { @@ -1681,6 +1835,7 @@ ATCA_STATUS atcac_get_auth_key_id(const struct atcac_x509_ctx* cert, cal_buffer* { status = cal_buf_set_used(auth_key_id, auth_key_id->len); } + akid_found = true; break; } next = next->next; @@ -1691,6 +1846,12 @@ ATCA_STATUS atcac_get_auth_key_id(const struct atcac_x509_ctx* cert, cal_buffer* { mbedtls_asn1_sequence_free(extns); } + + if (false == akid_found) + { + /* No data is available */ + status = cal_buf_set_used(auth_key_id, 0U); + } #endif } return status; diff --git a/lib/mbedtls/atca_mbedtls_wrap.h b/lib/mbedtls/atca_mbedtls_wrap.h index 655435980..ee76181b1 100644 --- a/lib/mbedtls/atca_mbedtls_wrap.h +++ b/lib/mbedtls/atca_mbedtls_wrap.h @@ -63,10 +63,26 @@ typedef struct atcac_sha1_ctx mbedtls_md_context_t mctx; } atcac_sha1_ctx_t; +#if ATCAC_SHA256_EN typedef struct atcac_sha2_256_ctx { mbedtls_md_context_t mctx; } atcac_sha2_256_ctx_t; +#endif + +#if ATCAC_SHA384_EN +typedef struct atcac_sha2_384_ctx +{ + mbedtls_md_context_t mctx; +} atcac_sha2_384_ctx_t; +#endif + +#if ATCAC_SHA512_EN +typedef struct atcac_sha2_512_ctx +{ + mbedtls_md_context_t mctx; +} atcac_sha2_512_ctx_t; +#endif typedef struct atcac_hmac_ctx { diff --git a/lib/openssl/atca_openssl_interface.c b/lib/openssl/atca_openssl_interface.c index ce73dd04d..d1672563f 100644 --- a/lib/openssl/atca_openssl_interface.c +++ b/lib/openssl/atca_openssl_interface.c @@ -27,6 +27,10 @@ #include "cryptoauthlib.h" #include "crypto/atca_crypto_sw.h" +#ifdef __COVERITY__ +#pragma coverity compliance block deviate "MISRA C-2012 Rule 11.3" "Third party library (openssl) implementation requires pointer type casting" +#endif + #ifdef ATCA_OPENSSL #include #include @@ -434,6 +438,7 @@ ATCA_STATUS atcac_sw_sha1_finish( return atca_openssl_md_finish((atca_evp_ctx*)ctx, digest, &outlen); } +#if ATCAC_SHA256_EN /** \brief Initialize context for performing SHA256 hash in software. * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -471,6 +476,87 @@ ATCA_STATUS atcac_sw_sha2_256_finish( return atca_openssl_md_finish((atca_evp_ctx*)ctx, digest, &outlen); } +#endif /* ATCAC_SHA256_EN */ + +#if ATCAC_SHA384_EN +/** \brief Initialize context for performing SHA384 hash in software. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_init( + struct atcac_sha2_384_ctx* ctx /**< [in] pointer to a hash context */ + ) +{ + return atca_openssl_md_init((atca_evp_ctx*)ctx, EVP_sha384()); +} + +/** \brief Add data to a SHA384 hash. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_update( + struct atcac_sha2_384_ctx* ctx, /**< [in] pointer to a hash context */ + const uint8_t* data, /**< [in] input data buffer */ + size_t data_size /**< [in] input data length */ + ) +{ + return atca_openssl_md_update((atca_evp_ctx*)ctx, data, data_size); +} + +/** \brief Complete the SHA384 hash in software and return the digest. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_finish( + struct atcac_sha2_384_ctx* ctx, /**< [in] pointer to a hash context */ + uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE] /**< [out] output buffer (48 bytes) */ + ) +{ + unsigned int outlen = ATCA_SHA2_384_DIGEST_SIZE; + + return atca_openssl_md_finish((atca_evp_ctx*)ctx, digest, &outlen); +} +#endif /* ATCAC_SHA384_EN */ + +#if ATCAC_SHA512_EN +/** \brief Initialize context for performing SHA512 hash in software. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_init( + struct atcac_sha2_512_ctx* ctx /**< [in] pointer to a hash context */ + ) +{ + return atca_openssl_md_init((atca_evp_ctx*)ctx, EVP_sha512()); +} + +/** \brief Add data to a SHA512 hash. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_update( + struct atcac_sha2_512_ctx* ctx, /**< [in] pointer to a hash context */ + const uint8_t* data, /**< [in] input data buffer */ + size_t data_size /**< [in] input data length */ + ) +{ + return atca_openssl_md_update((atca_evp_ctx*)ctx, data, data_size); +} + +/** \brief Complete the SHA512 hash in software and return the digest. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_finish( + struct atcac_sha2_512_ctx* ctx, /**< [in] pointer to a hash context */ + uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE] /**< [out] output buffer (64 bytes) */ + ) +{ + unsigned int outlen = ATCA_SHA2_512_DIGEST_SIZE; + + return atca_openssl_md_finish((atca_evp_ctx*)ctx, digest, &outlen); +} +#endif /* ATCAC_SHA512_EN */ /** \brief Initialize context for performing CMAC in software. * @@ -764,27 +850,56 @@ ATCA_STATUS atcac_pk_public( { ATCA_STATUS status = ATCA_BAD_PARAM; - if (NULL != ctx && NULL != ctx->ptr && NULL != buf && NULL != buflen && *buflen >= 64u) + if (NULL != ctx && NULL != ctx->ptr && NULL != buf && NULL != buflen) { int ret = -1; - if (EVP_PKEY_EC == EVP_PKEY_id((EVP_PKEY*)ctx->ptr)) + EVP_PKEY * pkey = (EVP_PKEY*)ctx->ptr; + + if (EVP_PKEY_EC == EVP_PKEY_id(pkey)) { - const EC_KEY * ec_key = EVP_PKEY_get0_EC_KEY((EVP_PKEY*)ctx->ptr); + const EC_KEY * ec_key = EVP_PKEY_get0_EC_KEY(pkey); if (NULL != ec_key) { - BIGNUM * x = BN_new(); - BIGNUM * y = BN_new(); + const EC_GROUP * group = EC_KEY_get0_group(ec_key); + int field_size = EC_GROUP_get_degree(group); + int coord_size = (field_size + 7) / 8; + size_t xy_coord_size = (coord_size > 0) ? ((size_t)coord_size * 2u) : (0u); - if (1 == (ret = EC_POINT_get_affine_coordinates(EC_KEY_get0_group(ec_key), EC_KEY_get0_public_key(ec_key), x, y, NULL))) + if ((0u != xy_coord_size) && (*buflen >= xy_coord_size)) { - (void)BN_bn2bin(x, buf); - (void)BN_bn2bin(y, &buf[32]); - *buflen = 64u; + BIGNUM * x = BN_new(); + BIGNUM * y = BN_new(); + + if (1 == (ret = EC_POINT_get_affine_coordinates(group, EC_KEY_get0_public_key(ec_key), x, y, NULL))) + { + (void)BN_bn2binpad(x, buf, coord_size); + (void)BN_bn2binpad(y, &buf[coord_size], coord_size); + *buflen = xy_coord_size; + } + BN_free(x); + BN_free(y); } - BN_free(x); - BN_free(y); } } + else + { + const RSA * rsa_key = EVP_PKEY_get0_RSA(pkey); + if (NULL != rsa_key) + { + const BIGNUM * n = RSA_get0_n(rsa_key); + if (NULL != n) + { + int n_len = BN_num_bytes(n); + if (*buflen >= (size_t)n_len) + { + (void)BN_bn2bin(n, buf); + *buflen = (size_t)n_len; + ret = 1; + } + } + } + } + status = (ret > 0) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; } return status; @@ -1189,10 +1304,26 @@ struct atcac_sha1_ctx * atcac_sha1_ctx_new(void) return (struct atcac_sha1_ctx*)hal_malloc(sizeof(atcac_sha1_ctx_t)); } +#if ATCAC_SHA256_EN struct atcac_sha2_256_ctx * atcac_sha256_ctx_new(void) { return (struct atcac_sha2_256_ctx*)hal_malloc(sizeof(atcac_sha2_256_ctx_t)); } +#endif + +#if ATCAC_SHA384_EN +struct atcac_sha2_384_ctx * atcac_sha384_ctx_new(void) +{ + return (struct atcac_sha2_384_ctx*)hal_malloc(sizeof(atcac_sha2_384_ctx_t)); +} +#endif + +#if ATCAC_SHA512_EN +struct atcac_sha2_512_ctx * atcac_sha512_ctx_new(void) +{ + return (struct atcac_sha2_512_ctx*)hal_malloc(sizeof(atcac_sha2_512_ctx_t)); +} +#endif struct atcac_hmac_ctx * atcac_hmac_ctx_new(void) { @@ -1219,10 +1350,26 @@ void atcac_sha1_ctx_free(struct atcac_sha1_ctx * ctx) hal_free(ctx); } +#if ATCAC_SHA256_EN void atcac_sha256_ctx_free(struct atcac_sha2_256_ctx * ctx) { hal_free(ctx); } +#endif + +#if ATCAC_SHA384_EN +void atcac_sha384_ctx_free(struct atcac_sha2_384_ctx * ctx) +{ + hal_free(ctx); +} +#endif + +#if ATCAC_SHA512_EN +void atcac_sha512_ctx_free(struct atcac_sha2_512_ctx * ctx) +{ + hal_free(ctx); +} +#endif void atcac_hmac_ctx_free(struct atcac_hmac_ctx * ctx) { diff --git a/lib/openssl/atca_openssl_interface.h b/lib/openssl/atca_openssl_interface.h index 006dfa98a..f83e362ee 100644 --- a/lib/openssl/atca_openssl_interface.h +++ b/lib/openssl/atca_openssl_interface.h @@ -47,9 +47,27 @@ extern "C" { * Indicates if this module is a provider of a SHA256 implementation */ #ifndef ATCAC_SHA256_EN -#define ATCAC_SHA256_EN (DEFAULT_ENABLED) +#define ATCAC_SHA256_EN (FEATURE_ENABLED) #endif /* ATCAC_SHA256_EN */ +/** \def ATCAC_SHA384_EN + * Indicates if this module is a provider of a SHA384 implementation + * + * Disabled by default. Use FEATURE_ENABLED to use SHA384 + */ +#ifndef ATCAC_SHA384_EN +#define ATCAC_SHA384_EN (FEATURE_DISABLED) +#endif /* ATCAC_SHA384_EN */ + +/** \def ATCAC_SHA512_EN + * Indicates if this module is a provider of a SHA512 implementation + * + * Disabled by default. Use FEATURE_ENABLED to use SHA512 + */ +#ifndef ATCAC_SHA512_EN +#define ATCAC_SHA512_EN (FEATURE_DISABLED) +#endif /* ATCAC_SHA512_EN */ + /** \def ATCAC_AES_CMAC_EN * Indicates if this module is a provider of an AES-CMAC implementation */ @@ -95,6 +113,16 @@ typedef struct atcac_sha2_256_ctx void* ptr; } atcac_sha2_256_ctx_t; +typedef struct atcac_sha2_384_ctx +{ + void* ptr; +} atcac_sha2_384_ctx_t; + +typedef struct atcac_sha2_512_ctx +{ + void* ptr; +} atcac_sha2_512_ctx_t; + typedef struct atcac_aes_cmac_ctx { void* ptr; diff --git a/lib/pkcs11/pkcs11_cert.c b/lib/pkcs11/pkcs11_cert.c index 1c494e62c..5e8751d2f 100644 --- a/lib/pkcs11/pkcs11_cert.c +++ b/lib/pkcs11/pkcs11_cert.c @@ -62,12 +62,13 @@ static pkcs11_cert_cache pkcs11_cert_cache_list[PKCS11_MAX_CERTS_CACHED]; #if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) -static void pkcs11_cert_check_trust_data(pkcs11_object_ptr pObject, pkcs11_session_ctx_ptr pSession) +static CK_RV pkcs11_cert_check_trust_data(pkcs11_object_ptr pObject, pkcs11_session_ctx_ptr pSession) { + CK_RV rv = CKR_ARGUMENTS_BAD; if ((PKCS11_OBJECT_FLAG_TRUST_TYPE == (PKCS11_OBJECT_FLAG_TRUST_TYPE & pObject->flags)) && (NULL == pObject->data) && (NULL != pSession)) { const atcacert_def_t * cert_def = NULL; - (void)tng_get_device_cert_def_ext(pSession->slot->device_ctx, &cert_def); + rv = pkcs11_util_convert_rv(tng_get_device_cert_def_ext(pSession->slot->device_ctx, &cert_def)); if (NULL != cert_def) { @@ -85,6 +86,7 @@ static void pkcs11_cert_check_trust_data(pkcs11_object_ptr pObject, pkcs11_sessi } } } + return rv; } #endif @@ -310,13 +312,16 @@ static CK_RV pkcs11_cert_get_encoded(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr if (NULL != obj_ptr && NULL != psession) { -#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) - pkcs11_cert_check_trust_data(obj_ptr, psession); - if (CKR_OK != (rv = pkcs11_cert_load(obj_ptr, pAttribute, psession->slot->device_ctx))) + if (PKCS11_OBJECT_FLAG_TRUST_TYPE == (PKCS11_OBJECT_FLAG_TRUST_TYPE & obj_ptr->flags)) { - return rv; +#if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) + rv = pkcs11_cert_check_trust_data(obj_ptr, psession); + if (CKR_OK == rv) + { + return pkcs11_cert_load(obj_ptr, pAttribute, psession->slot->device_ctx); + } +#endif } -#else #if defined(ATCA_HEAP) && (FEATURE_ENABLED == ATCACERT_INTEGRATION_EN) rv = pkcs11_cert_load_cache(psession, obj_ptr); if (CKR_OK == rv) @@ -328,16 +333,14 @@ static CK_RV pkcs11_cert_get_encoded(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr (pkcs11_cert_cache_list[i].pObject_cert == pObject)) { return pkcs11_attrib_fill(pAttribute, pkcs11_cert_cache_list[i].cert_x509_parse.pValue, - pkcs11_cert_cache_list[i].cert_x509_parse.ulValueLen); + pkcs11_cert_cache_list[i].cert_x509_parse.ulValueLen); } } } #else return pkcs11_cert_load(obj_ptr, pAttribute, psession->slot->device_ctx); - #endif -#endif + #endif } - return rv; } @@ -348,9 +351,12 @@ static CK_RV pkcs11_cert_get_type_ca(pkcs11_object_ptr pObject, CK_ATTRIBUTE_PTR if (NULL != pObject) { + if (PKCS11_OBJECT_FLAG_TRUST_TYPE == (PKCS11_OBJECT_FLAG_TRUST_TYPE & pObject->flags)) + { #if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) - pkcs11_cert_check_trust_data(pObject, psession); + (void)pkcs11_cert_check_trust_data(pObject, psession); #endif + } if (NULL != pObject->data) { @@ -405,11 +411,16 @@ static CK_RV pkcs11_cert_get_subject(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr if (NULL != obj_ptr && NULL != psession) { + if (PKCS11_OBJECT_FLAG_TRUST_TYPE == (PKCS11_OBJECT_FLAG_TRUST_TYPE & obj_ptr->flags)) + { #if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) - pkcs11_cert_check_trust_data(obj_ptr, psession); + (void)pkcs11_cert_check_trust_data(obj_ptr, psession); #endif - - rv = pkcs11_cert_load_cache(psession, obj_ptr); + } + else + { + rv = pkcs11_cert_load_cache(psession, obj_ptr); + } if (NULL != obj_ptr->data) { @@ -559,11 +570,16 @@ static CK_RV pkcs11_cert_get_subject_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_PT if (NULL != obj_ptr) { + if (PKCS11_OBJECT_FLAG_TRUST_TYPE == (PKCS11_OBJECT_FLAG_TRUST_TYPE & obj_ptr->flags)) + { #if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) - pkcs11_cert_check_trust_data(obj_ptr, psession); + (void)pkcs11_cert_check_trust_data(obj_ptr, psession); #endif - - read_cache = pkcs11_cert_load_cache(psession, obj_ptr); + } + else + { + read_cache = pkcs11_cert_load_cache(psession, obj_ptr); + } if (NULL != obj_ptr->data) { @@ -660,11 +676,16 @@ static CK_RV pkcs11_cert_get_authority_key_id(CK_VOID_PTR pObject, CK_ATTRIBUTE_ if (NULL != obj_ptr) { + if (PKCS11_OBJECT_FLAG_TRUST_TYPE == (PKCS11_OBJECT_FLAG_TRUST_TYPE & obj_ptr->flags)) + { #if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) - pkcs11_cert_check_trust_data(obj_ptr, psession); + (void)pkcs11_cert_check_trust_data(obj_ptr, psession); #endif - - (void)pkcs11_cert_load_cache(psession, obj_ptr); + } + else + { + (void)pkcs11_cert_load_cache(psession, obj_ptr); + } if (NULL != obj_ptr->data) { @@ -817,21 +838,33 @@ static CK_RV pkcs11_cert_get_subj_key(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAtt if (NULL != obj_ptr) { CK_RV read_cache = CKR_GENERAL_ERROR; + if (PKCS11_OBJECT_FLAG_TRUST_TYPE == (PKCS11_OBJECT_FLAG_TRUST_TYPE & obj_ptr->flags)) + { #if defined(ATCA_TNGTLS_SUPPORT) || defined(ATCA_TNGLORA_SUPPORT) || defined(ATCA_TFLEX_SUPPORT) - pkcs11_cert_check_trust_data(obj_ptr, psession); + (void)pkcs11_cert_check_trust_data(obj_ptr, psession); #endif - read_cache = pkcs11_cert_load_cache(psession, obj_ptr); + } + else + { + read_cache = pkcs11_cert_load_cache(psession, obj_ptr); + } if (NULL != obj_ptr->data) { atcacert_def_t * cert_cfg = (atcacert_def_t*)obj_ptr->data; if (CKR_OK == read_cache) { - uint8_t subj_public_key[64] = { 0 }; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + uint8_t subj_public_key[PKCS11_MAX_ECC_RSA_PB_KEY_SIZE] = { 0 }; +#else + uint8_t subj_public_key[PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; +#endif + + cal_buffer subj_pubkey = CAL_BUF_INIT(sizeof(subj_public_key), subj_public_key); - if (ATCA_SUCCESS == (atcacert_get_subj_public_key(cert_def, NULL, 0, &subj_public_key))) + if (ATCA_SUCCESS == (atcacert_get_subj_public_key(cert_cfg, NULL, 0, &subj_pubkey))) { - rv = pkcs11_attrib_fill(pAttribute, subj_public_key, (CK_ULONG)sizeof(subj_public_key)); + rv = pkcs11_attrib_fill(pAttribute, subj_public_key, (CK_ULONG)subj_pubkey.len); } else { diff --git a/lib/pkcs11/pkcs11_config.c b/lib/pkcs11/pkcs11_config.c index 1d7c968d8..14020375f 100644 --- a/lib/pkcs11/pkcs11_config.c +++ b/lib/pkcs11/pkcs11_config.c @@ -56,6 +56,63 @@ typedef struct pkcs11_conf_filedata_s typedef struct pkcs11_conf_filedata_s *pkcs11_conf_filedata_ptr; +#if ATCA_TA_SUPPORT +void pkcs11_config_set_key_size(pkcs11_object_ptr pObject) +{ + CK_BYTE key_type = ((pObject->handle_info.element_CKA & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT); + CK_ULONG private_key_size = 0u; + CK_ULONG public_key_size = 0u; + + switch (key_type) + { + case TA_KEY_TYPE_ECCP224: + pObject->class_type = CKK_EC; + private_key_size = TA_ECC224_PVT_KEY_SIZE; + public_key_size = TA_ECC224_PUB_KEY_SIZE; + break; + case TA_KEY_TYPE_ECCP384: + pObject->class_type = CKK_EC; + private_key_size = TA_ECC384_PVT_KEY_SIZE; + public_key_size = TA_ECC384_PUB_KEY_SIZE; + break; + case TA_KEY_TYPE_ECCP521: + pObject->class_type = CKK_EC; + private_key_size = TA_ECC521_PVT_KEY_SIZE; + public_key_size = TA_ECC521_PUB_KEY_SIZE; + break; +#if PKCS11_RSA_SUPPORT_ENABLE + case TA_KEY_TYPE_RSA1024: + pObject->class_type = CKK_RSA; + private_key_size = TA_RSAENC_PVT_KEY_SIZE1024; + public_key_size = TA_RSAENC_PUB_KEY_SIZE1024; + break; + case TA_KEY_TYPE_RSA2048: + pObject->class_type = CKK_RSA; + private_key_size = TA_RSAENC_PVT_KEY_SIZE2048; + public_key_size = TA_RSAENC_PUB_KEY_SIZE2048; + break; + case TA_KEY_TYPE_RSA3072: + pObject->class_type = CKK_RSA; + private_key_size = TA_RSAENC_PVT_KEY_SIZE3072; + public_key_size = TA_RSAENC_PUB_KEY_SIZE3072; + break; + case TA_KEY_TYPE_RSA4096: + pObject->class_type = CKK_RSA; + private_key_size = TA_RSAENC_PVT_KEY_SIZE4096; + public_key_size = TA_RSAENC_PUB_KEY_SIZE4096; + break; +#endif + default: + pObject->class_type = CKK_EC; + private_key_size = TA_ECC256_PVT_KEY_SIZE; + public_key_size = TA_ECC256_PUB_KEY_SIZE; + break; + } + + pObject->size = (CKO_PRIVATE_KEY == pObject->class_id) ? (private_key_size) : (public_key_size); +} +#endif + void pkcs11_config_init_private(pkcs11_object_ptr pObject, const char * label, size_t len) { if (len >= (size_t)PKCS11_MAX_LABEL_SIZE) @@ -65,14 +122,22 @@ void pkcs11_config_init_private(pkcs11_object_ptr pObject, const char * label, s (void)memcpy((char*)pObject->name, label, len); pObject->name[len] = (CK_UTF8CHAR)'\0'; pObject->class_id = CKO_PRIVATE_KEY; - pObject->class_type = CKK_EC; pObject->attributes = pkcs11_key_private_attributes; pObject->count = pkcs11_key_private_attributes_count; - pObject->flags = PKCS11_OBJECT_FLAG_KEY_CACHE; + pObject->flags |= PKCS11_OBJECT_FLAG_KEY_CACHE; #if ATCA_CA_SUPPORT pObject->data = NULL; #endif - pObject->size = 16; + pObject->class_type = CKK_EC; + pObject->size = ATCA_ECCP256_PVTKEY_SIZE; + +#if ATCA_TA_SUPPORT + // Update the class type and size based on the keytype + if (0u != pObject->handle_info.element_CKA) + { + (void)pkcs11_config_set_key_size(pObject); + } +#endif } void pkcs11_config_init_public(pkcs11_object_ptr pObject, const char * label, size_t len) @@ -84,14 +149,22 @@ void pkcs11_config_init_public(pkcs11_object_ptr pObject, const char * label, si (void)memcpy((char*)pObject->name, label, len); pObject->name[len] = (CK_UTF8CHAR)'\0'; pObject->class_id = CKO_PUBLIC_KEY; - pObject->class_type = CKK_EC; pObject->attributes = pkcs11_key_public_attributes; pObject->count = pkcs11_key_public_attributes_count; - pObject->flags = PKCS11_OBJECT_FLAG_KEY_CACHE; + pObject->flags |= PKCS11_OBJECT_FLAG_KEY_CACHE; #if ATCA_CA_SUPPORT pObject->data = NULL; #endif - pObject->size = 64; + pObject->class_type = CKK_EC; + pObject->size = ATCA_ECCP256_PVTKEY_SIZE; + +#if ATCA_TA_SUPPORT + // Update the class type and size based on the keytype + if (0u != pObject->handle_info.element_CKA) + { + (void)pkcs11_config_set_key_size(pObject); + } +#endif } void pkcs11_config_init_secret(pkcs11_object_ptr pObject, const char * label, size_t len, size_t keylen) @@ -124,7 +197,6 @@ void pkcs11_config_init_cert(pkcs11_object_ptr pObject, const char * label, size (void)memcpy((char*)pObject->name, label, len); pObject->name[len] = (CK_UTF8CHAR)'\0'; pObject->class_id = CKO_CERTIFICATE; - pObject->class_type = 0; pObject->attributes = pkcs11_cert_x509public_attributes; pObject->count = pkcs11_cert_x509public_attributes_count; #if ATCA_CA_SUPPORT @@ -589,7 +661,7 @@ static CK_RV pkcs11_config_parse_freeslots(pkcs11_slot_ctx_ptr slot_ctx, char* c return CKR_GENERAL_ERROR; } - if (slot > 0 && slot < 16) + if (slot >= 0 && slot < 16) { slot_ctx->flags |= ((CK_FLAGS)1U << (uint16_t)slot); } @@ -943,7 +1015,7 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p } else { -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && TALIB_CREATE_SHARED_DATA_EN ATCA_STATUS status = talib_create_element(pSlot->device_ctx, &pObject->handle_info, &handle); rv = pkcs11_util_convert_rv(status); #endif @@ -983,8 +1055,10 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p int ret = 0x00; if (atcab_is_ca_device(pSlot->interface_config.devtype)) { +#if ATCA_CA_SUPPORT ret = snprintf(filename, sizeof(filename), "%s%lu.%u.conf", pLibCtx->config_path, pSlot->slot_id, pObject->slot); +#endif } else { @@ -1014,16 +1088,27 @@ CK_RV pkcs11_config_key(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, p CK_RV pkcs11_config_remove_object(pkcs11_lib_ctx_ptr pLibCtx, pkcs11_slot_ctx_ptr pSlot, pkcs11_object_ptr pObject) { char filename[200]; - int ret = snprintf(filename, sizeof(filename), "%s%lu.%u.conf", pLibCtx->config_path, + int ret = 0x00; + if (atcab_is_ca_device(pSlot->interface_config.devtype)) + { + ret = snprintf(filename, sizeof(filename), "%s%lu.%u.conf", pLibCtx->config_path, pSlot->slot_id, pObject->slot); + } + else + { + ret = snprintf(filename, sizeof(filename), "%s%lu.%04x.conf", pLibCtx->config_path, + pSlot->slot_id, pObject->slot); + } if (ret > 0 && ret < (int)sizeof(filename)) { (void)remove(filename); if (atcab_is_ca_device(pSlot->interface_config.devtype)) { +#if ATCA_CA_SUPPORT /* coverity[cert_int34_c_violation] shift will not affect precision since slot max can be only till 15 */ pSlot->flags |= ((CK_FLAGS)1 << pObject->slot); +#endif } } diff --git a/lib/pkcs11/pkcs11_config.h.in b/lib/pkcs11/pkcs11_config.h.in index 5ce6c237e..da55d8e70 100644 --- a/lib/pkcs11/pkcs11_config.h.in +++ b/lib/pkcs11/pkcs11_config.h.in @@ -58,6 +58,11 @@ #cmakedefine01 PKCS11_USE_STATIC_CONFIG #endif +/** Enable RSA Support in PKCS11 */ +#ifndef PKCS11_RSA_SUPPORT_ENABLE +#cmakedefine01 PKCS11_RSA_SUPPORT_ENABLE +#endif + /** Maximum number of slots allowed in the system - if static memory this will always be the number of slots */ #ifndef PKCS11_MAX_SLOTS_ALLOWED @@ -175,4 +180,8 @@ void pkcs11_config_init_public(pkcs11_object_ptr pObject, const char * label, si void pkcs11_config_init_cert(pkcs11_object_ptr pObject, const char * label, size_t len); void pkcs11_config_init_secret(pkcs11_object_ptr pObject, const char* label, size_t len, size_t keylen); +#if ATCA_TA_SUPPORT +void pkcs11_config_set_key_size(pkcs11_object_ptr pObject); +#endif + #endif /* PKCS11_CONFIG_H_ */ diff --git a/lib/pkcs11/pkcs11_encrypt.c b/lib/pkcs11/pkcs11_encrypt.c index e16b5bccc..728b5642b 100644 --- a/lib/pkcs11/pkcs11_encrypt.c +++ b/lib/pkcs11/pkcs11_encrypt.c @@ -35,7 +35,7 @@ #include "pkcs11_session.h" #include "pkcs11_util.h" #include "pkcs11_slot.h" - +#include "pkcs11_key.h" #ifdef __COVERITY__ #pragma coverity compliance block \ @@ -156,6 +156,19 @@ CK_RV pkcs11_encrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanis } break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS_OAEP: + // pMechanism->pParameter should point to CK_RSA_PKCS_OAEP_PARAMS + if ((NULL != pMechanism->pParameter) && sizeof(CK_RSA_PKCS_OAEP_PARAMS) == pMechanism->ulParameterLen) + { + rv = CKR_OK; + } + else + { + rv = CKR_ARGUMENTS_BAD; + } + break; +#endif default: rv = CKR_MECHANISM_INVALID; break; @@ -190,6 +203,9 @@ 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; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + CK_BBOOL is_private = false; +#endif rv = pkcs11_init_check(&pLibCtx, FALSE); if (CKR_OK != rv) @@ -307,6 +323,45 @@ CK_RV pkcs11_encrypt(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ULONG ulD } #endif break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS_OAEP: + if (CKR_OK == (rv = pkcs11_object_is_private(pKey, &is_private, pSession))) + { + if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + { + ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); + if (atcab_is_ta_device(dev_type)) + { + cal_buffer plaintext_buf = CAL_BUF_INIT(ulDataLen, pData); + cal_buffer ciphertext_buf = CAL_BUF_INIT(*pulEncryptedDataLen, pEncryptedData); + const pkcs11_key_info_t* key_data = pkcs11_get_object_key_type(pSession->slot->device_ctx, pKey); + + if (NULL != key_data && NULL != key_data->rsa_key_info) + { + if (true == is_private) + { + uint8_t pub_key[PKCS11_MAX_RSA_PB_KEY_SIZE]; + cal_buffer rsa_pubkey_buf = CAL_BUF_INIT(key_data->rsa_key_info->pubkey_sz, pub_key); + + if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pKey, &rsa_pubkey_buf, pSession))) + { + rv = pkcs11_util_convert_rv(talib_rsaenc_encrypt(pSession->slot->device_ctx, key_data->rsa_key_info->rsa_encrypt_mode, TA_HANDLE_INPUT_BUFFER, + &plaintext_buf, &rsa_pubkey_buf, &ciphertext_buf)); + } + } + else + { + /* Assume Public Key has been stored properly and encrypt against whatever is stored */ + rv = pkcs11_util_convert_rv(talib_rsaenc_encrypt(pSession->slot->device_ctx, key_data->rsa_key_info->rsa_encrypt_mode, pKey->slot, + &plaintext_buf, NULL, &ciphertext_buf)); + } + } + } + (void)pkcs11_unlock_device(pLibCtx); + } + } + break; +#endif default: rv = CKR_MECHANISM_INVALID; break; @@ -635,6 +690,15 @@ CK_RV pkcs11_decrypt_init(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanis } } break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS_OAEP: + // pMechanism->pParameter should point to CK_RSA_PKCS_OAEP_PARAMS + if ((NULL != pMechanism->pParameter) && sizeof(CK_RSA_PKCS_OAEP_PARAMS) == pMechanism->ulParameterLen) + { + rv = CKR_OK; + } + break; +#endif default: rv = CKR_MECHANISM_INVALID; break; @@ -792,6 +856,26 @@ CK_RV pkcs11_decrypt( } #endif break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS_OAEP: + if (atcab_is_ta_device(atcab_get_device_type_ext(pSession->slot->device_ctx))) + { + if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + { + cal_buffer ciphertext_buf = CAL_BUF_INIT(ulEncryptedDataLen, pEncryptedData); + cal_buffer plaintext_buf = CAL_BUF_INIT(*pulDataLen, pData); + const pkcs11_key_info_t* key_data = pkcs11_get_object_key_type(pSession->slot->device_ctx, pKey); + + if (NULL != key_data && NULL != key_data->rsa_key_info) + { + rv = pkcs11_util_convert_rv(talib_rsaenc_decrypt(pSession->slot->device_ctx, key_data->rsa_key_info->rsa_decrypt_mode, pKey->slot, + &ciphertext_buf, &plaintext_buf)); + } + (void)pkcs11_unlock_device(pLibCtx); + } + } + break; +#endif default: rv = CKR_MECHANISM_INVALID; break; diff --git a/lib/pkcs11/pkcs11_init.c b/lib/pkcs11/pkcs11_init.c index c6bb8d667..4ddd2b601 100644 --- a/lib/pkcs11/pkcs11_init.c +++ b/lib/pkcs11/pkcs11_init.c @@ -447,7 +447,7 @@ CK_RV pkcs11_deinit(CK_VOID_PTR pReserved) { if (CKR_OK == pkcs11_lock_device(lib_ctx)) { -#if ATCA_TA_SUPPORT +#if (ATCA_TA_SUPPORT && TALIB_AUTH_EN) /* Terminate auth session*/ pkcs11_slot_ctx_ptr pslot_ctx = (pkcs11_slot_ctx_ptr)lib_ctx->slots; diff --git a/lib/pkcs11/pkcs11_key.c b/lib/pkcs11/pkcs11_key.c index 9b4c7ff8b..383c6db77 100644 --- a/lib/pkcs11/pkcs11_key.c +++ b/lib/pkcs11/pkcs11_key.c @@ -131,6 +131,123 @@ CK_BYTE pkcs11_x962_asn1_hdr_ec521[] = { }; CK_BYTE pkcs11_key_ec_params_p521[] = { 0x06, 0x05, 0x2B, 0x81, 0x04, 0x00, 0x23 }; + +#if PKCS11_RSA_SUPPORT_ENABLE +/* ASN.1 header for RSA-1024 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsa1024[] = { + 0x30, 0x81, 0x9F, // a SEQUENCE of 159 bytes follows + 0x30, 0x0D, // a SEQUENCE of 13 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, // ID algorithm: 1.2.840.113549.1.1.1 (RSA) + 0x05, 0x00, // No paramters for this algorithm + 0x03, 0x81, 0x8D, 0x00, // a BIT STRING of 141 bytes follows (including the 0x00 padding byte) + 0x30, 0x81, 0x89, // a SEQUENCE of 137 bytes follows + 0x02, 0x81, 0x81, // a INTEGER VALUE of 129 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for RSASSA_PSS-1024 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss1024[] = { + 0x30, 0x81, 0x9D, // a SEQUENCE of 157 bytes follows + 0x30, 0x0B, // a SEQUENCE of 11 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A, // ID algorithm: 1.2.840.113549.1.1.10 (RSASSA-PSS) + 0x03, 0x81, 0x8D, 0x00, // a BIT STRING of 141 bytes follows (including the 0x00 padding byte) + 0x30, 0x81, 0x89, // a SEQUENCE of 137 bytes follows + 0x02, 0x81, 0x81, // a INTEGER VALUE of 129 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for RSA-2048 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsa2048[] = { + 0x30, 0x82, 0x01, 0x22, // a SEQUENCE of 290 bytes follows + 0x30, 0x0D, // a SEQUENCE of 13 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, // ID algorithm: 1.2.840.113549.1.1.1 (RSA) + 0x05, 0x00, // No paramters for this algorithm + 0x03, 0x82, 0x01, 0x0F, 0x00, // a BIT STRING of 271 bytes follows (including the 0x00 padding byte) + 0x30, 0x82, 0x01, 0x0A, // a SEQUENCE of 266 bytes follows + 0x02, 0x82, 0x01, 0x01, // a INTEGER VALUE of 257 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for RSASSA_PSS-2048 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss2048[] = { + 0x30, 0x82, 0x01, 0x20, // a SEQUENCE of 288 bytes follows + 0x30, 0x0B, // a SEQUENCE of 11 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A, // ID algorithm: 1.2.840.113549.1.1.10 (RSASSA-PSS) + 0x03, 0x82, 0x01, 0x0F, 0x00, // a BIT STRING of 271 bytes follows (including the 0x00 padding byte) + 0x30, 0x82, 0x01, 0x0A, // a SEQUENCE of 266 bytes follows + 0x02, 0x82, 0x01, 0x01, // a INTEGER VALUE of 257 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for RSA-3072 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsa3072[] = { + 0x30, 0x82, 0x01, 0xA2, // a SEQUENCE of 418 bytes follows + 0x30, 0x0D, // a SEQUENCE of 13 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, // ID algorithm: 1.2.840.113549.1.1.1 (RSA) + 0x05, 0x00, // No paramters for this algorithm + 0x03, 0x82, 0x01, 0x8F, 0x00, // a BIT STRING of 399 bytes follows (including the 0x00 padding byte) + 0x30, 0x82, 0x01, 0x8A, // a SEQUENCE of 394 bytes follows + 0x02, 0x82, 0x01, 0x81, // a INTEGER VALUE of 385 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for RSASSA_PSS-3072 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss3072[] = { + 0x30, 0x82, 0x01, 0xA0, // a SEQUENCE of 416 bytes follows + 0x30, 0x0B, // a SEQUENCE of 11 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A, // ID algorithm: 1.2.840.113549.1.1.10 (RSASSA-PSS) + 0x03, 0x82, 0x01, 0x8F, 0x00, // a BIT STRING of 399 bytes follows (including the 0x00 padding byte) + 0x30, 0x82, 0x01, 0x8A, // a SEQUENCE of 394 bytes follows + 0x02, 0x82, 0x01, 0x81, // a INTEGER VALUE of 385 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for RSA-4096 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsa4096[] = { + 0x30, 0x82, 0x02, 0x22, // a SEQUENCE of 546 bytes follows + 0x30, 0x0D, // a SEQUENCE of 13 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, // ID algorithm: 1.2.840.113549.1.1.1 (RSA) + 0x05, 0x00, // No paramters for this algorithm + 0x03, 0x82, 0x02, 0x0F, 0x00, // a BIT STRING of 527 bytes follows (including the 0x00 padding byte) + 0x30, 0x82, 0x02, 0x0A, // a SEQUENCE of 522 bytes follows + 0x02, 0x82, 0x02, 0x01, // a INTEGER VALUE of 513 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for RSASSA_PSS-4096 public keys */ +CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss4096[] = { + 0x30, 0x82, 0x02, 0x20, // a SEQUENCE of 544 bytes follows + 0x30, 0x0B, // a SEQUENCE of 11 bytes follows + 0x06, 0x09, // an OBJECT IDENTIFIER of 9 bytes follows + 0x2a, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x0A, // ID algorithm: 1.2.840.113549.1.1.10 (RSASSA-PSS) + 0x03, 0x82, 0x02, 0x0F, 0x00, // a BIT STRING of 527 bytes follows (including the 0x00 padding byte) + 0x30, 0x82, 0x02, 0x0A, // a SEQUENCE of 522 bytes follows + 0x02, 0x82, 0x02, 0x01, // a INTEGER VALUE of 513 bytes follows + 0x00 // Leading zero for MODULUS +}; + +/* ASN.1 header for SHA-256 Hash */ +CK_BYTE pkcs11_sha256_asn1_hdr[19] = { + 0x30, 0x31, // a SEQUENCE of 49 bytes follows + 0x30, 0x0D, // a SEQUENCE of 13 bytes follows + 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, // ID algorithm: 2.16.840.1.101.3.4.2.1 (SHA-256) + 0x05, 0x00, // No paramters for this algorithm + 0x04, 0x20 // a OCTET STRING of 32 bytes follows +}; + +/* ASN.1 Header for rsa public exponent */ +CK_BYTE pkcs11_rsa_public_exp_asn1_hdr[] = {0x02, 0x03}; // an INTEGER VALUE of 3 bytes follows + +/* Public Exponent for RSA Private and Public Keys */ +CK_BYTE pkcs11_rsa_public_exp[] = {0x01, 0x00, 0x01}; // Default value of 65537 +#endif #endif //Fixing the lookup table size to support max of 4 ECC curves @@ -151,27 +268,67 @@ const pkcs11_ecc_key_info_t ec_key_data_table[4] = { #endif }; -const pkcs11_ecc_key_info_t* pkcs11_get_object_key_type(ATCADevice device_ctx, pkcs11_object_ptr obj_ptr) +const pkcs11_rsa_key_info_t rsa_key_data_table[4] = { +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + { TA_KEY_TYPE_RSA1024, TA_RSAENC_MODE_ENCRYPT1024, TA_RSAENC_MODE_DECRYPT1024, TA_RSA1024_ASN1_HDR_SIZE, TA_RSA1024_PSS_ASN1_HDR_SIZE, + pkcs11_pbkey_asn1_hdr_rsa1024, pkcs11_pbkey_asn1_hdr_rsapss1024, pkcs11_rsa_public_exp_asn1_hdr, pkcs11_rsa_public_exp, + TA_RSAENC_PUB_KEY_SIZE1024_BITS, TA_RSAENC_PUB_KEY_SIZE1024, TA_SIGN_OTHER_KEY_TYPE_MSG_SIZE, TA_SIGN_RSA1024_SIG_SIZE }, + + { TA_KEY_TYPE_RSA2048, TA_RSAENC_MODE_ENCRYPT2048, TA_RSAENC_MODE_DECRYPT2048, TA_RSA2048_ASN1_HDR_SIZE, TA_RSA2048_PSS_ASN1_HDR_SIZE, + pkcs11_pbkey_asn1_hdr_rsa2048, pkcs11_pbkey_asn1_hdr_rsapss2048, pkcs11_rsa_public_exp_asn1_hdr, pkcs11_rsa_public_exp, + TA_RSAENC_PUB_KEY_SIZE2048_BITS, TA_RSAENC_PUB_KEY_SIZE2048, TA_SIGN_OTHER_KEY_TYPE_MSG_SIZE, TA_SIGN_RSA2048_SIG_SIZE }, + + { TA_KEY_TYPE_RSA3072, TA_RSAENC_MODE_ENCRYPT3072, TA_RSAENC_MODE_DECRYPT3072, TA_RSA3072_ASN1_HDR_SIZE, TA_RSA3072_PSS_ASN1_HDR_SIZE, + pkcs11_pbkey_asn1_hdr_rsa3072, pkcs11_pbkey_asn1_hdr_rsapss3072,pkcs11_rsa_public_exp_asn1_hdr, pkcs11_rsa_public_exp, + TA_RSAENC_PUB_KEY_SIZE3072_BITS, TA_RSAENC_PUB_KEY_SIZE3072, TA_SIGN_OTHER_KEY_TYPE_MSG_SIZE, TA_SIGN_RSA3072_SIG_SIZE }, + + { TA_KEY_TYPE_RSA4096, TA_RSAENC_MODE_ENCRYPT4096, TA_RSAENC_MODE_DECRYPT4096, TA_RSA4096_ASN1_HDR_SIZE, TA_RSA4096_PSS_ASN1_HDR_SIZE, + pkcs11_pbkey_asn1_hdr_rsa4096, pkcs11_pbkey_asn1_hdr_rsapss4096, pkcs11_rsa_public_exp_asn1_hdr, pkcs11_rsa_public_exp, + TA_RSAENC_PUB_KEY_SIZE4096_BITS, TA_RSAENC_PUB_KEY_SIZE4096, TA_SIGN_OTHER_KEY_TYPE_MSG_SIZE, TA_SIGN_RSA4096_SIG_SIZE }, +#endif +}; + +const pkcs11_key_info_t key_data_table[] = { + // ECC keys + { &ec_key_data_table[0], NULL }, +#if ATCA_TA_SUPPORT + { &ec_key_data_table[1], NULL }, + { &ec_key_data_table[2], NULL }, + { &ec_key_data_table[3], NULL }, +#if PKCS11_RSA_SUPPORT_ENABLE + // RSA keys + { NULL, &rsa_key_data_table[0] }, + { NULL, &rsa_key_data_table[1] }, + { NULL, &rsa_key_data_table[2] }, + { NULL, &rsa_key_data_table[3] }, +#endif +#endif +}; + +const pkcs11_key_info_t* pkcs11_get_object_key_type(ATCADevice device_ctx, pkcs11_object_ptr obj_ptr) { CK_BYTE key_type = 0u; ATCADeviceType dev_type = atcab_get_device_type_ext(device_ctx); if (NULL != obj_ptr) - { + { if (atcab_is_ca_device(dev_type)) { - return &ec_key_data_table[key_type]; +#if ATCA_CA_SUPPORT + key_type = ATCA_KEY_TYPE_ECCP256; + return &key_data_table[key_type]; +#endif } else if (atcab_is_ta_device(dev_type)) { #if ATCA_TA_SUPPORT key_type = ((obj_ptr->handle_info.element_CKA & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT); - if (key_type > 3u) + if (key_type >= (sizeof(key_data_table) / sizeof(key_data_table[0]))) { return NULL; } - return &ec_key_data_table[key_type]; + return &key_data_table[key_type]; #endif } else @@ -179,7 +336,7 @@ const pkcs11_ecc_key_info_t* pkcs11_get_object_key_type(ATCADevice device_ctx, p /* do nothing*/ } } - + /* If reached here means object not valid*/ return NULL; } @@ -341,16 +498,42 @@ static CK_RV pkcs11_key_get_gen_mechanism(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR } #endif +#if ATCA_CA_SUPPORT static const CK_MECHANISM_TYPE pkcs11_key_508_public_mech[] = { CKM_ECDSA, CKM_ECDSA_SHA256 }; +#endif + +#if ATCA_TA_SUPPORT +static const CK_MECHANISM_TYPE pkcs11_key_ta_public_mech[] = { + CKM_ECDSA, + CKM_ECDSA_SHA256, + CKM_RSA_PKCS, + CKM_RSA_PKCS_PSS, + CKM_RSA_PKCS_OAEP +}; +#endif +#if ATCA_CA_SUPPORT static const CK_MECHANISM_TYPE pkcs11_key_508_private_mech[] = { CKM_EC_KEY_PAIR_GEN, CKM_ECDSA, CKM_ECDSA_SHA256 }; +#endif + +#if ATCA_TA_SUPPORT +static const CK_MECHANISM_TYPE pkcs11_key_ta_private_mech[] = { + CKM_EC_KEY_PAIR_GEN, + CKM_ECDSA, + CKM_ECDSA_SHA256, + CKM_RSA_PKCS_KEY_PAIR_GEN, + CKM_RSA_PKCS, + CKM_RSA_PKCS_PSS, + CKM_RSA_PKCS_OAEP +}; +#endif #if ATCA_CA_SUPPORT static const CK_MECHANISM_TYPE pkcs11_key_508_secret_mech[] = { @@ -424,12 +607,12 @@ static CK_RV pkcs11_key_fill_ta_mech(pkcs11_object_ptr obj_ptr, CK_ATTRIBUTE_PTR switch (obj_ptr->class_id) { case CKO_PRIVATE_KEY: - rv = pkcs11_attrib_fill(pAttribute, pkcs11_key_508_private_mech, - (CK_ULONG)sizeof(pkcs11_key_508_private_mech)); + rv = pkcs11_attrib_fill(pAttribute, pkcs11_key_ta_private_mech, + (CK_ULONG)sizeof(pkcs11_key_ta_private_mech)); break; case CKO_PUBLIC_KEY: - rv = pkcs11_attrib_fill(pAttribute, pkcs11_key_508_public_mech, - (CK_ULONG)sizeof(pkcs11_key_508_public_mech)); + rv = pkcs11_attrib_fill(pAttribute, pkcs11_key_ta_public_mech, + (CK_ULONG)sizeof(pkcs11_key_ta_public_mech)); break; case CKO_SECRET_KEY: rv = pkcs11_attrib_fill(pAttribute, pkcs11_key_608_secret_mech, @@ -481,98 +664,160 @@ static CK_RV pkcs11_key_get_public_key(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAt if (NULL != obj_ptr && NULL != session_ctx) { CK_BBOOL is_private = false; - const pkcs11_ecc_key_info_t *ec_key_data = pkcs11_get_object_key_type(session_ctx->slot->device_ctx, obj_ptr); + const pkcs11_key_info_t *key_data = pkcs11_get_object_key_type(session_ctx->slot->device_ctx, obj_ptr); - if (NULL == ec_key_data) + if (NULL == key_data) { return rv; } if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private, session_ctx))) - { - if (ec_key_data->asn1_header_sz <= ((uint16_t)PKCS11_MAX_ECC_ASN1_HDR_SIZE) && (ec_key_data->pubkey_sz <= PKCS11_MAX_ECC_PB_KEY_SIZE)) - { - //Keeping to max size - CK_UTF8CHAR ec_asn1_key[PKCS11_MAX_ECC_ASN1_HDR_SIZE + PKCS11_MAX_ECC_PB_KEY_SIZE]; - (void)memcpy(ec_asn1_key, ec_key_data->ec_asn1_header, ec_key_data->asn1_header_sz); - ATCADeviceType dev_type = atcab_get_device_type_ext(session_ctx->slot->device_ctx); + { + ATCADeviceType dev_type = atcab_get_device_type_ext(session_ctx->slot->device_ctx); + CK_ULONG asn1_key_size = 0u; + CK_ULONG asn1_header_size = (CKK_EC == obj_ptr->class_type) ? key_data->ecc_key_info->asn1_header_sz : 0u; + //Keeping to max size +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + CK_UTF8CHAR asn1_key[PKCS11_MAX_ECC_RSA_ASN1_HDR_SIZE + PKCS11_MAX_ECC_RSA_PB_KEY_SIZE] = { 0 }; +#else + CK_UTF8CHAR asn1_key[PKCS11_MAX_ECC_ASN1_HDR_SIZE + PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; +#endif + CK_ULONG pubkey_size = PKCS11_MAX_ECC_RSA_PB_KEY_SIZE; - if (is_private) + if (CKK_EC == obj_ptr->class_type) + { + if (NULL == key_data->ecc_key_info) + { + return rv; + } + pubkey_size = key_data->ecc_key_info->pubkey_sz; + (void)memcpy(asn1_key, key_data->ecc_key_info->ec_asn1_header, key_data->ecc_key_info->asn1_header_sz); + } +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + else + { + CK_BYTE_PTR asn1_rsa_header = NULL; + ta_handle_info handle_info; + CK_BYTE alg_mode = 0u; + + if (NULL == key_data->rsa_key_info) + { + return rv; + } + // Update the public key size for RSA curves + pubkey_size = key_data->rsa_key_info->pubkey_sz; + if (CKR_OK == (rv = pkcs11_util_convert_rv(talib_info_get_handle_info(session_ctx->slot->device_ctx, obj_ptr->slot, &handle_info)))) + { + alg_mode = handle_info.attributes.element_CKA & TA_HANDLE_INFO_ALG_MODE_MASK; + asn1_rsa_header = ((CK_BYTE)TA_ALG_MODE_RSA_SSA_1_5 == alg_mode) ? (key_data->rsa_key_info->rsa_asn1_header) + : (key_data->rsa_key_info->rsa_pss_asn1_header); + asn1_header_size = ((CK_BYTE)TA_ALG_MODE_RSA_SSA_1_5 == alg_mode) ? (key_data->rsa_key_info->rsa_asn1_header_size) + : (key_data->rsa_key_info->rsa_pss_asn1_header_size); + (void)memcpy(asn1_key, asn1_rsa_header, asn1_header_size); + } + } +#endif + + if (true == is_private) + { + if (atcab_is_ca_device(dev_type)) { - if (atcab_is_ca_device(dev_type)) - { #if ATCA_CA_SUPPORT - rv = pkcs11_util_convert_rv(atcab_get_pubkey_ext(session_ctx->slot->device_ctx, obj_ptr->slot, - &ec_asn1_key[ec_key_data->asn1_header_sz])); - PKCS11_DEBUG("atcab_get_pubkey_ext: %x\r\n", rv); + rv = pkcs11_util_convert_rv(atcab_get_pubkey_ext(session_ctx->slot->device_ctx, obj_ptr->slot, + &asn1_key[key_data->ecc_key_info->asn1_header_sz])); + PKCS11_DEBUG("atcab_get_pubkey_ext: %x\r\n", rv); #endif - } - else if (atcab_is_ta_device(dev_type)) - { + } + else if (atcab_is_ta_device(dev_type)) + { #if ATCA_TA_SUPPORT - CK_UTF8CHAR ec_pubkey_gen[PKCS11_MAX_ECC_PB_KEY_SIZE]; - cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, ec_pubkey_gen); - if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pObject, &ec_pubkey_buf, session_ctx))) - { - (void)memcpy(&ec_asn1_key[ec_key_data->asn1_header_sz], ec_pubkey_gen, ec_key_data->pubkey_sz); - } - PKCS11_DEBUG("pkcs11_ta_get_pubkey: %x\r\n", rv); +#if PKCS11_RSA_SUPPORT_ENABLE + CK_UTF8CHAR pubkey_gen[PKCS11_MAX_RSA_PB_KEY_SIZE] = { 0 }; +#else + CK_UTF8CHAR pubkey_gen[PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; #endif - } - else + cal_buffer pubkey_buf = CAL_BUF_INIT(pubkey_size, pubkey_gen); + + if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pObject, &pubkey_buf, session_ctx))) { - rv = CKR_GENERAL_ERROR; + (void)memcpy(&asn1_key[asn1_header_size], pubkey_gen, pubkey_size); } + PKCS11_DEBUG("pkcs11_ta_get_pubkey: %x\r\n", rv); +#endif } else { - if (atcab_is_ca_device(dev_type)) - { + rv = CKR_GENERAL_ERROR; + } + } + else + { + if (atcab_is_ca_device(dev_type)) + { #if ATCA_CA_SUPPORT - rv = pkcs11_util_convert_rv(atcab_read_pubkey_ext(session_ctx->slot->device_ctx, obj_ptr->slot, - &ec_asn1_key[(ec_key_data->asn1_header_sz)])); - PKCS11_DEBUG("atcab_read_pubkey_ext: %x\r\n", rv); + rv = pkcs11_util_convert_rv(atcab_read_pubkey_ext(session_ctx->slot->device_ctx, obj_ptr->slot, + &asn1_key[key_data->ecc_key_info->asn1_header_sz])); + PKCS11_DEBUG("atcab_read_pubkey_ext: %x\r\n", rv); #endif - } - else if (atcab_is_ta_device(dev_type)) - { + } + else if (atcab_is_ta_device(dev_type)) + { #if ATCA_TA_SUPPORT - CK_UTF8CHAR ec_pubkey_rd[PKCS11_MAX_ECC_PB_KEY_SIZE]; - cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, ec_pubkey_rd); - if (CKR_OK == (rv = pkcs11_util_convert_rv(talib_read_element(session_ctx->slot->device_ctx, obj_ptr->slot, &ec_pubkey_buf)))) - { - (void)memcpy(&ec_asn1_key[ec_key_data->asn1_header_sz], ec_pubkey_rd, ec_key_data->pubkey_sz); - } - PKCS11_DEBUG("talib_read_element: %x\r\n", rv); +#if PKCS11_RSA_SUPPORT_ENABLE + CK_UTF8CHAR pubkey_rd[PKCS11_MAX_RSA_PB_KEY_SIZE] = { 0 }; +#else + CK_UTF8CHAR pubkey_rd[PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; #endif - } - else + cal_buffer pubkey_buf = CAL_BUF_INIT(pubkey_size, pubkey_rd); + if (CKR_OK == (rv = pkcs11_util_convert_rv(talib_read_element(session_ctx->slot->device_ctx, obj_ptr->slot, &pubkey_buf)))) { - rv = CKR_GENERAL_ERROR; + (void)memcpy(&asn1_key[asn1_header_size], pubkey_rd, pubkey_size); } + PKCS11_DEBUG("talib_read_element: %x\r\n", rv); +#endif } - if (CKR_OK == rv) + else { - rv = pkcs11_attrib_fill(pAttribute, ec_asn1_key, (CK_ULONG)sizeof(ec_asn1_key)); + rv = CKR_GENERAL_ERROR; } + } + if (CKR_OK == rv) + { + if (CKK_EC == obj_ptr->class_type) + { + asn1_key_size = asn1_header_size + pubkey_size; + } + #if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE else { - (void)pkcs11_attrib_empty(pObject, pAttribute, NULL); - PKCS11_DEBUG("Couldnt generate public key\r\n", rv); - rv = CKR_OK; + CK_BYTE rsa_pubexp_hdr_size = (CK_BYTE)sizeof(pkcs11_rsa_public_exp_asn1_hdr); + CK_BYTE rsa_pubkey_exp_size = (CK_BYTE)sizeof(pkcs11_rsa_public_exp); + + (void)memcpy(&asn1_key[asn1_header_size + pubkey_size], pkcs11_rsa_public_exp_asn1_hdr, rsa_pubexp_hdr_size); + (void)memcpy(&asn1_key[asn1_header_size + pubkey_size + rsa_pubexp_hdr_size], pkcs11_rsa_public_exp, rsa_pubkey_exp_size); + asn1_key_size = asn1_header_size + pubkey_size + rsa_pubexp_hdr_size + rsa_pubkey_exp_size; } + #endif + + rv = pkcs11_attrib_fill(pAttribute, asn1_key, asn1_key_size); } else { - rv = CKR_KEY_SIZE_RANGE; + (void)pkcs11_attrib_empty(pObject, pAttribute, NULL); + PKCS11_DEBUG("Couldnt generate public key\r\n", rv); + rv = CKR_OK; } } + else + { + rv = CKR_KEY_SIZE_RANGE; + } } else { rv = CKR_ARGUMENTS_BAD; } - + return rv; } @@ -583,11 +828,11 @@ static CK_RV pkcs11_key_get_ec_params(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAtt CK_RV rv = CKR_ARGUMENTS_BAD; if (NULL != obj_ptr && NULL != psession) { - const pkcs11_ecc_key_info_t *ec_key_data = pkcs11_get_object_key_type(psession->slot->device_ctx, obj_ptr); + const pkcs11_key_info_t *ec_key_data = pkcs11_get_object_key_type(psession->slot->device_ctx, obj_ptr); if (NULL != ec_key_data) { - rv = pkcs11_attrib_fill(pAttribute, ec_key_data->curve_oid, (CK_ULONG)(ec_key_data->oid_size)); + rv = pkcs11_attrib_fill(pAttribute, ec_key_data->ecc_key_info->curve_oid, (CK_ULONG)(ec_key_data->ecc_key_info->oid_size)); } else { @@ -602,24 +847,24 @@ static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr { pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; CK_RV rv = CKR_ARGUMENTS_BAD; - + if (NULL != obj_ptr && NULL != psession) { - const pkcs11_ecc_key_info_t *ec_key_data = pkcs11_get_object_key_type(psession->slot->device_ctx, obj_ptr); + const pkcs11_key_info_t *ec_key_data = pkcs11_get_object_key_type(psession->slot->device_ctx, obj_ptr); if (NULL == ec_key_data) { return rv; } - + //EC point attribute length need to be set before fetching the actual attribute data //Hence by default, return value is CKR_OK - rv = CKR_OK; + rv = CKR_OK; - if (ec_key_data->pubkey_sz <= PKCS11_MAX_ECC_PB_KEY_SIZE) + if (ec_key_data->ecc_key_info->pubkey_sz <= PKCS11_MAX_ECC_PB_KEY_SIZE) { CK_UTF8CHAR ec_asn1_key[PKCS11_X962_ASN1_HEADER_SZ + PKCS11_MAX_ECC_PB_KEY_SIZE]; - (void)memcpy(ec_asn1_key, ec_key_data->ec_x962_asn1_header, PKCS11_X962_ASN1_HEADER_SZ); + (void)memcpy(ec_asn1_key, ec_key_data->ecc_key_info->ec_x962_asn1_header, PKCS11_X962_ASN1_HEADER_SZ); if (NULL != pAttribute->pValue) { @@ -627,7 +872,7 @@ static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr ATCADeviceType dev_type = atcab_get_device_type_ext(psession->slot->device_ctx); if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private, psession))) - { + { if (is_private) { if (atcab_is_ca_device(dev_type)) @@ -641,10 +886,10 @@ static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr { #if ATCA_TA_SUPPORT CK_UTF8CHAR ec_pubkey_gen[PKCS11_MAX_ECC_PB_KEY_SIZE]; - cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, ec_pubkey_gen); + cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->ecc_key_info->pubkey_sz, ec_pubkey_gen); if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pObject, &ec_pubkey_buf, psession))) { - (void)memcpy(&ec_asn1_key[PKCS11_X962_ASN1_HEADER_SZ], ec_pubkey_gen, ec_key_data->pubkey_sz); + (void)memcpy(&ec_asn1_key[PKCS11_X962_ASN1_HEADER_SZ], ec_pubkey_gen, ec_key_data->ecc_key_info->pubkey_sz); } PKCS11_DEBUG("pkcs11_ta_get_pubkey: %x\r\n", rv); #endif @@ -667,10 +912,10 @@ static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr { #if ATCA_TA_SUPPORT CK_UTF8CHAR ec_pubkey_rd[PKCS11_MAX_ECC_PB_KEY_SIZE]; - cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, ec_pubkey_rd); + cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->ecc_key_info->pubkey_sz, ec_pubkey_rd); if (CKR_OK == (rv = pkcs11_util_convert_rv(talib_read_element(psession->slot->device_ctx, obj_ptr->slot, &ec_pubkey_buf)))) { - (void)memcpy(&ec_asn1_key[PKCS11_X962_ASN1_HEADER_SZ], ec_pubkey_rd, ec_key_data->pubkey_sz); + (void)memcpy(&ec_asn1_key[PKCS11_X962_ASN1_HEADER_SZ], ec_pubkey_rd, ec_key_data->ecc_key_info->pubkey_sz); } PKCS11_DEBUG("talib_read_element: %x\r\n", rv); #endif @@ -686,7 +931,7 @@ static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr if (CKR_OK == rv) { - rv = pkcs11_attrib_fill(pAttribute, ec_asn1_key, (CK_ULONG)sizeof(ec_asn1_key)); + rv = pkcs11_attrib_fill(pAttribute, ec_asn1_key, (ec_key_data->ecc_key_info->pubkey_sz + PKCS11_X962_ASN1_HEADER_SZ)); } else { @@ -708,6 +953,113 @@ static CK_RV pkcs11_key_get_ec_point(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttr return rv; } +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE +static CK_RV pkcs11_key_get_public_exponent(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute, pkcs11_session_ctx_ptr psession) +{ + ((void)psession); + pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; + CK_RV rv = CKR_ARGUMENTS_BAD; + + if (NULL != obj_ptr && NULL != psession) + { + if (CKK_RSA == obj_ptr->class_type) + { + rv = pkcs11_attrib_fill(pAttribute, pkcs11_rsa_public_exp, (CK_ULONG)(sizeof(pkcs11_rsa_public_exp))); + } + else + { + (void)pkcs11_attrib_empty(pObject, pAttribute, NULL); + } + } + else + { + return CKR_ARGUMENTS_BAD; + } + + return rv; +} + +static CK_RV pkcs11_key_get_modulus_bits(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute, pkcs11_session_ctx_ptr psession) +{ + ((void)psession); + pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; + CK_RV rv = CKR_ARGUMENTS_BAD; + + if (NULL != obj_ptr && NULL != psession) + { + if (CKK_RSA == obj_ptr->class_type) + { + const pkcs11_key_info_t *rsa_key_data = pkcs11_get_object_key_type(psession->slot->device_ctx, obj_ptr); + + if (NULL == rsa_key_data) + { + return rv; + } + rv = pkcs11_attrib_fill(pAttribute, &rsa_key_data->rsa_key_info->rsa_modulus_bits, sizeof(CK_ULONG)); + } + else + { + (void)pkcs11_attrib_empty(pObject, pAttribute, NULL); + } + } + else + { + return CKR_ARGUMENTS_BAD; + } + + return rv; +} + +static CK_RV pkcs11_key_get_modulus(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute, pkcs11_session_ctx_ptr psession) +{ + ((void)psession); + pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; + CK_RV rv = CKR_ARGUMENTS_BAD; + + if (NULL != obj_ptr && NULL != psession) + { + if (CKK_RSA == obj_ptr->class_type) + { + CK_BBOOL is_private; + CK_BYTE pubkey_buffer[PKCS11_MAX_RSA_PB_KEY_SIZE]; + const pkcs11_key_info_t *rsa_key_data = pkcs11_get_object_key_type(psession->slot->device_ctx, obj_ptr); + + if (NULL == rsa_key_data || NULL == rsa_key_data->rsa_key_info) + { + return rv; + } + + if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private, psession))) + { + cal_buffer rsa_pubkey_buf = CAL_BUF_INIT(rsa_key_data->rsa_key_info->pubkey_sz, pubkey_buffer); + + if (is_private) + { + rv = pkcs11_ta_get_pubkey(pObject, &rsa_pubkey_buf, psession); + PKCS11_DEBUG("pkcs11_ta_get_pubkey: %x\r\n", rv); + } + else + { + rv = pkcs11_util_convert_rv(talib_read_element(psession->slot->device_ctx, obj_ptr->slot, &rsa_pubkey_buf)); + PKCS11_DEBUG("talib_read_element: %x\r\n", rv); + } + } + + if (CKR_OK == rv) + { + rv = pkcs11_attrib_fill(pAttribute, pubkey_buffer, rsa_key_data->rsa_key_info->pubkey_sz); + } + } + else + { + (void)pkcs11_attrib_empty(pObject, pAttribute, NULL); + } + } + + return rv; +} +#endif + static CK_RV pkcs11_key_get_secret(CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute, pkcs11_session_ctx_ptr pSession) { ((void)pSession); @@ -807,76 +1159,109 @@ static CK_RV pkcs11_key_calc_key_id(const pkcs11_session_ctx_ptr pSession, const if (NULL != obj_ptr && NULL != pSession) { - const pkcs11_ecc_key_info_t *ec_key_data = pkcs11_get_object_key_type(pSession->slot->device_ctx, obj_ptr); + const pkcs11_key_info_t *key_data = pkcs11_get_object_key_type(pSession->slot->device_ctx, obj_ptr); - if (NULL == ec_key_data) + if (NULL == key_data) { return rv; } - if (ec_key_data->pubkey_sz <= PKCS11_MAX_ECC_PB_KEY_SIZE) - { - if (CKR_OK == (rv = pkcs11_object_is_private(pObject, &is_private, pSession))) - { - CK_BYTE pubkey_buffer[ATCA_ECC_UNCOMPRESSED_TYPE_OFFSET + PKCS11_MAX_ECC_PB_KEY_SIZE]; + if (CKR_OK == (rv = pkcs11_object_is_private(pObject, &is_private, pSession))) + { +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + CK_UTF8CHAR pubkey_buffer[PKCS11_MAX_ECC_RSA_PB_KEY_SIZE] = { 0 }; +#else + CK_UTF8CHAR pubkey_buffer[PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; +#endif + CK_ULONG pubkey_size = sizeof(pubkey_buffer); + ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); + + if (CKK_EC == obj_ptr->class_type) + { + if (NULL == key_data->ecc_key_info) + { + return rv; + } + pubkey_size = key_data->ecc_key_info->pubkey_sz; pubkey_buffer[0] = ATCA_ECC_UNCOMPRESSED_TYPE; - ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); + } +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + else + { + if (NULL == key_data->rsa_key_info) + { + return rv; + } + pubkey_size = key_data->rsa_key_info->pubkey_sz; + } +#endif - if (TRUE == is_private) + if (TRUE == is_private) + { + if (atcab_is_ca_device(dev_type)) { - if (atcab_is_ca_device(dev_type)) - { #if ATCA_CA_SUPPORT - rv = pkcs11_util_convert_rv(atcab_get_pubkey_ext(pSession->slot->device_ctx, pObject->slot, &pubkey_buffer[1])); + rv = pkcs11_util_convert_rv(atcab_get_pubkey_ext(pSession->slot->device_ctx, pObject->slot, &pubkey_buffer[1])); #endif - } - else if (atcab_is_ta_device(dev_type)) - { + } + else if (atcab_is_ta_device(dev_type)) + { #if ATCA_TA_SUPPORT - CK_UTF8CHAR ec_pubkey_gen[PKCS11_MAX_ECC_PB_KEY_SIZE]; - cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, ec_pubkey_gen); - if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pObject, &ec_pubkey_buf, pSession))) - { - (void)memcpy(&pubkey_buffer[1], ec_pubkey_gen, ec_key_data->pubkey_sz); - } - PKCS11_DEBUG("pkcs11_ta_get_pubkey: %x\r\n", rv); +#if PKCS11_RSA_SUPPORT_ENABLE + CK_UTF8CHAR pubkey_gen[PKCS11_MAX_RSA_PB_KEY_SIZE] = { 0 }; +#else + CK_UTF8CHAR pubkey_gen[PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; #endif - } - else + cal_buffer pubkey_buf = CAL_BUF_INIT(pubkey_size, pubkey_gen); + CK_BYTE_PTR pubkey_buf_ptr = (CKK_EC == obj_ptr->class_type) ? &pubkey_buffer[1] : &pubkey_buffer[0]; + + if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pObject, &pubkey_buf, pSession))) { - rv = CKR_GENERAL_ERROR; + (void)memcpy(pubkey_buf_ptr, pubkey_gen, pubkey_size); } + PKCS11_DEBUG("pkcs11_ta_get_pubkey: %x\r\n", rv); +#endif } else { - if (atcab_is_ca_device(dev_type)) - { + rv = CKR_GENERAL_ERROR; + } + } + else + { + if (atcab_is_ca_device(dev_type)) + { #if ATCA_CA_SUPPORT - rv = pkcs11_util_convert_rv(atcab_read_pubkey_ext(pSession->slot->device_ctx, obj_ptr->slot, &pubkey_buffer[1])); - PKCS11_DEBUG("atcab_read_pubkey_ext: %x\r\n", rv); + rv = pkcs11_util_convert_rv(atcab_read_pubkey_ext(pSession->slot->device_ctx, obj_ptr->slot, &pubkey_buffer[1])); + PKCS11_DEBUG("atcab_read_pubkey_ext: %x\r\n", rv); #endif - } - else if (atcab_is_ta_device(dev_type)) - { + } + else if (atcab_is_ta_device(dev_type)) + { #if ATCA_TA_SUPPORT - CK_UTF8CHAR ec_pubkey_rd[PKCS11_MAX_ECC_PB_KEY_SIZE]; - cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, ec_pubkey_rd); - if (CKR_OK == (rv = pkcs11_util_convert_rv(talib_read_element(pSession->slot->device_ctx, obj_ptr->slot, &ec_pubkey_buf)))) - { - (void)memcpy(&pubkey_buffer[1], ec_pubkey_rd, ec_key_data->pubkey_sz); - } - PKCS11_DEBUG("talib_read_element: %x\r\n", rv); +#if PKCS11_RSA_SUPPORT_ENABLE + CK_UTF8CHAR pubkey_rd[PKCS11_MAX_RSA_PB_KEY_SIZE] = { 0 }; +#else + CK_UTF8CHAR pubkey_rd[PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; #endif - } - else + cal_buffer pubkey_buf = CAL_BUF_INIT(pubkey_size, pubkey_rd); + CK_BYTE_PTR pubkey_buf_ptr = (CKK_EC == obj_ptr->class_type) ? &pubkey_buffer[1] : &pubkey_buffer[0]; + + if (CKR_OK == (rv = pkcs11_util_convert_rv(talib_read_element(pSession->slot->device_ctx, obj_ptr->slot, &pubkey_buf)))) { - rv = CKR_GENERAL_ERROR; + (void)memcpy(pubkey_buf_ptr, pubkey_rd, pubkey_size); } + PKCS11_DEBUG("talib_read_element: %x\r\n", rv); +#endif } - if (CKR_OK == rv) + else { - rv = pkcs11_util_convert_rv(atcac_sw_sha1(pubkey_buffer, sizeof(pubkey_buffer), key_id_buffer)); - } + rv = CKR_GENERAL_ERROR; + } + } + if (CKR_OK == rv) + { + rv = pkcs11_util_convert_rv(atcac_sw_sha1(pubkey_buffer, (CKK_EC == obj_ptr->class_type) ? (ATCA_ECC_UNCOMPRESSED_TYPE_OFFSET + pubkey_size) : (pubkey_size), key_id_buffer)); } } else @@ -895,7 +1280,7 @@ static CK_RV pkcs11_key_load_key_id_cache(const pkcs11_session_ctx_ptr pSession, { CK_RV rv = CKR_ARGUMENTS_BAD; - if ((NULL != pkcs11_key_cache_item) && (pObject->class_type == CKK_EC)) + if ((NULL != pkcs11_key_cache_item) && (pObject->class_type == CKK_EC || pObject->class_type == CKK_RSA)) { CK_ULONG i; @@ -1081,6 +1466,14 @@ const pkcs11_attrib_model pkcs11_key_public_attributes[] = { { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, /** DER - encoding of ANSI X9.62 ECPoint value Q */ { CKA_EC_POINT, pkcs11_key_get_ec_point }, +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + /** Big integer - Modulus n */ + { CKA_MODULUS, pkcs11_key_get_modulus }, + /** CK_ULONG - Length in bits of modulus n */ + { CKA_MODULUS_BITS, pkcs11_key_get_modulus_bits }, + /** Big integer - Public exponent e */ + { CKA_PUBLIC_EXPONENT, pkcs11_key_get_public_exponent }, +#endif }; const CK_ULONG pkcs11_key_public_attributes_count = (CK_ULONG)(PKCS11_UTIL_ARRAY_SIZE(pkcs11_key_public_attributes)); @@ -1180,49 +1573,28 @@ const pkcs11_attrib_model pkcs11_key_private_attributes[] = { { CKA_EC_POINT, pkcs11_key_get_ec_point }, /** The value of the private key should remain private. A NULL function pointer is interpreted as a sensitive attribute. */ { CKA_VALUE, NULL_PTR }, +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + /** Big integer - Modulus n */ + { CKA_MODULUS, pkcs11_key_get_modulus }, + /** Big integer - Public exponent e */ + { CKA_PUBLIC_EXPONENT, pkcs11_key_get_public_exponent }, + /** Big integer - Private exponent d */ + { CKA_PRIVATE_EXPONENT, NULL_PTR }, + /** Big integer - Prime p */ + { CKA_PRIME_1, NULL_PTR }, + /** Big integer - Prime q */ + { CKA_PRIME_2, NULL_PTR }, + /** Big integer - Private exponent d modulo p-1 */ + { CKA_EXPONENT_1, NULL_PTR }, + /** Big integer - Private exponent d modulo q-1 */ + { CKA_EXPONENT_2, NULL_PTR }, + /** Big integer - CRT coefficient q-1 mod p */ + { CKA_COEFFICIENT, NULL_PTR }, +#endif }; const CK_ULONG pkcs11_key_private_attributes_count = (CK_ULONG)(PKCS11_UTIL_ARRAY_SIZE(pkcs11_key_private_attributes)); - -#if 0 -/** - * CKO_PRIVATE_KEY (Type: CKK_RSA) - RSA Private Key Object Model - */ -const pkcs11_attrib_model pkcs11_key_rsa_private_attributes[] = { - /** Big integer Modulus n */ - { CKA_MODULUS, NULL_PTR }, - /** Big integer Public exponent e */ - { CKA_PUBLIC_EXPONENT, NULL_PTR }, - /** Big integer Private exponent d */ - { CKA_PRIVATE_EXPONENT, NULL_PTR }, - /** Big integer Prime p */ - { CKA_PRIME_1, NULL_PTR }, - /** Big integer Prime q */ - { CKA_PRIME_2, NULL_PTR }, - /** Big integer Private exponent d modulo p - 1 */ - { CKA_EXPONENT_1, NULL_PTR }, - /** Big integer Private exponent d modulo q - 1 */ - { CKA_EXPONENT_2, NULL_PTR }, - /** Big integer CRT coefficient q - 1 mod p */ - { CKA_COEFFICIENT, NULL_PTR }, -}; - -/** - * CKO_PRIVATE_KEY (Type: CKK_EC) - EC/ECDSA Public Key Object Model - */ -const pkcs11_attrib_model pkcs11_key_ec_private_attributes[] = { - /** DER - encoding of an ANSI X9.62 Parameters value - Parameters ::= CHOICE { - ecParameters ECParameters, - namedCurve CURVES.&id({CurveNames}), - implicitlyCA NULL } */ - { CKA_EC_PARAMS, pkcs11_key_get_ec_params }, - /** DER - encoding of ANSI X9.62 ECPoint value Q */ - { CKA_EC_POINT, pkcs11_key_get_ec_point }, -}; -#endif - /** * CKO_SECRET_KEY - Secret Key Object Base Model */ @@ -1308,7 +1680,7 @@ const pkcs11_attrib_model pkcs11_key_secret_attributes[] = { const CK_ULONG pkcs11_key_secret_attributes_count = (CK_ULONG)(PKCS11_UTIL_ARRAY_SIZE(pkcs11_key_secret_attributes)); - +#if ATCA_CA_SUPPORT static CK_RV pkcs11_key_privwrite_ca(CK_VOID_PTR pSession, pkcs11_object_ptr pObject, CK_VOID_PTR pValue, CK_ULONG ulValueLen) { @@ -1319,7 +1691,6 @@ static CK_RV pkcs11_key_privwrite_ca(CK_VOID_PTR pSession, pkcs11_object_ptr pOb pkcs11_session_ctx_ptr session_ctx = (pkcs11_session_ctx_ptr)pSession; if (atcab_is_ca_device(atcab_get_device_type_ext(session_ctx->slot->device_ctx))) { -#if ATCA_CA_SUPPORT uint8_t key_buf[36] = { 0 }; uint8_t num_in[32] = { 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1339,21 +1710,14 @@ static CK_RV pkcs11_key_privwrite_ca(CK_VOID_PTR pSession, pkcs11_object_ptr pOb Production devices should never have this feature enabled. */ rv = pkcs11_util_convert_rv(calib_priv_write(session_ctx->slot->device_ctx, pObject->slot, key_buf, write_key_id, session_ctx->slot->read_key, num_in)); -#endif - } - else - { -#if ATCA_TA_SUPPORT - cal_buffer sValue = CAL_BUF_INIT(ulValueLen, pValue); - rv = pkcs11_util_convert_rv(talib_write_element(session_ctx->slot->device_ctx, pObject->slot, &sValue)); -#endif } } return rv; } +#endif -CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute, const pkcs11_ecc_key_info_t *ec_key_info) +CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute) { pkcs11_object_ptr obj_ptr = (pkcs11_object_ptr)pObject; CK_RV rv = CKR_ARGUMENTS_BAD; @@ -1361,65 +1725,90 @@ CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_P if ((NULL != obj_ptr) && (NULL != pAttribute) && (NULL != pAttribute->pValue) && (NULL != pSession)) { pkcs11_session_ctx_ptr session_ctx = (pkcs11_session_ctx_ptr)pSession; - if (obj_ptr->class_id == CKO_PUBLIC_KEY && pAttribute->type == CKA_EC_POINT) + if (obj_ptr->class_id == CKO_PUBLIC_KEY && (pAttribute->type == CKA_EC_POINT || pAttribute->type == CKA_MODULUS)) { - const pkcs11_ecc_key_info_t *ec_key_data = pkcs11_get_object_key_type(session_ctx->slot->device_ctx, obj_ptr); + const pkcs11_key_info_t *key_data = pkcs11_get_object_key_type(session_ctx->slot->device_ctx, obj_ptr); - if (NULL != ec_key_data) + if (NULL != key_data) { + CK_BBOOL is_private; + /* coverity[misra_c_2012_rule_21_16_violation:FALSE] CK_VOID_PTR is a pointer type */ - if (0 == memcmp(ec_key_data->ec_x962_asn1_header, pAttribute->pValue, PKCS11_X962_ASN1_HEADER_SZ)) + if ((CKK_EC == obj_ptr->class_type) && (0 != memcmp((CK_BYTE_PTR)key_data->ecc_key_info->ec_x962_asn1_header, (CK_BYTE_PTR)pAttribute->pValue, PKCS11_X962_ASN1_HEADER_SZ))) { - CK_BBOOL is_private; + return CKR_ARGUMENTS_BAD; + } - if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private, session_ctx))) + if (CKR_OK == (rv = pkcs11_object_is_private(obj_ptr, &is_private, session_ctx))) + { + if (is_private) { - if (is_private) + /* Assume it is paired with the private key that is already stored */ + rv = CKR_OK; + } + else + { + ATCADeviceType device_type = atcab_get_device_type_ext(session_ctx->slot->device_ctx); + + /* Actually write the public key into the slot */ + if (atcab_is_ca_device(device_type)) { - /* Assume it is paired with the private key that is already stored */ - rv = CKR_OK; +#if ATCA_CA_SUPPORT + rv = pkcs11_util_convert_rv(atcab_write_pubkey_ext(session_ctx->slot->device_ctx, obj_ptr->slot, + &(((uint8_t*)pAttribute->pValue)[PKCS11_X962_ASN1_HEADER_SZ]))); +#endif } - else + else if (atcab_is_ta_device(device_type)) { - ATCADeviceType device_type = atcab_get_device_type_ext(session_ctx->slot->device_ctx); - /* Actually write the public key into the slot */ - if (atcab_is_ca_device(device_type)) - { - rv = pkcs11_util_convert_rv(atcab_write_pubkey_ext(session_ctx->slot->device_ctx, obj_ptr->slot, - &(((uint8_t*)pAttribute->pValue)[PKCS11_X962_ASN1_HEADER_SZ]))); - } - else if (atcab_is_ta_device(device_type)) - { - if (ec_key_data->asn1_header_sz <= ((uint16_t)PKCS11_MAX_ECC_ASN1_HDR_SIZE) && (ec_key_data->pubkey_sz <= PKCS11_MAX_ECC_PB_KEY_SIZE)) - { #if ATCA_TA_SUPPORT - CK_UTF8CHAR ec_pubkey[PKCS11_MAX_ECC_ASN1_HDR_SIZE + PKCS11_MAX_ECC_PB_KEY_SIZE]; - (void)memcpy(ec_pubkey, &(((CK_BYTE_PTR)pAttribute->pValue)[0]), pAttribute->ulValueLen); - cal_buffer ec_pbkey_buf = CAL_BUF_INIT(ec_key_info->pubkey_sz, ec_pubkey); - rv = pkcs11_util_convert_rv(talib_write_element(session_ctx->slot->device_ctx, obj_ptr->slot, &ec_pbkey_buf)); +#if PKCS11_RSA_SUPPORT_ENABLE + CK_UTF8CHAR pubkey[PKCS11_MAX_RSA_PB_KEY_SIZE] = { 0 }; +#else + CK_UTF8CHAR pubkey[PKCS11_MAX_ECC_PB_KEY_SIZE] = { 0 }; #endif - } + + cal_buffer pbkey_buf = {0u, pubkey}; + + if (CKK_EC == obj_ptr->class_type) + { + pbkey_buf.len = key_data->ecc_key_info->pubkey_sz; } +#if PKCS11_RSA_SUPPORT_ENABLE else { - rv = CKR_KEY_SIZE_RANGE; + pbkey_buf.len = key_data->rsa_key_info->pubkey_sz; } +#endif + (void)memcpy(pubkey, &(((CK_BYTE_PTR)pAttribute->pValue)[0]), pAttribute->ulValueLen); + rv = pkcs11_util_convert_rv(talib_write_element(session_ctx->slot->device_ctx, obj_ptr->slot, &pbkey_buf)); +#endif + } + else + { + rv = CKR_KEY_SIZE_RANGE; } } } } } - else if (obj_ptr->class_id == CKO_PRIVATE_KEY && pAttribute->type == CKA_VALUE) + else if (obj_ptr->class_id == CKO_PRIVATE_KEY && (pAttribute->type == CKA_VALUE || pAttribute->type == CKA_MODULUS)) { +#if ATCA_CA_SUPPORT if (atcab_is_ca_device(atcab_get_device_type_ext(session_ctx->slot->device_ctx))) { rv = pkcs11_key_privwrite_ca(pSession, obj_ptr, pAttribute->pValue, pAttribute->ulValueLen); } + else +#endif + { + rv = CKR_OK; + } } else if (obj_ptr->class_id == CKO_SECRET_KEY && pAttribute->type == CKA_VALUE) { if (atcab_is_ca_device(atcab_get_device_type_ext(session_ctx->slot->device_ctx)) && ((pAttribute->ulValueLen % 32u) != 0u)) { +#if ATCA_CA_SUPPORT uint8_t buf[64] = { 0 }; uint16_t buflen = (uint16_t)((0u != (pAttribute->ulValueLen / 32u)) ? 64u : 32u); if (pAttribute->ulValueLen > 64u) @@ -1428,6 +1817,7 @@ CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_P } (void)memcpy(buf, pAttribute->pValue, pAttribute->ulValueLen); rv = pkcs11_util_convert_rv(atcab_write_bytes_zone_ext(session_ctx->slot->device_ctx, ATCA_ZONE_DATA, obj_ptr->slot, 0, buf, buflen)); +#endif } else { @@ -1597,9 +1987,10 @@ CK_RV pkcs11_key_generate_pair pkcs11_object_ptr pPublic = NULL; pkcs11_object_ptr pPrivate = NULL; CK_ULONG i; - CK_ULONG ecKeyTableIdx = 0; - CK_BBOOL OidMatched = false; CK_RV rv = CKR_OK; + CK_BBOOL isRsa = false; + CK_ULONG keyTableIdx = 0; + CK_BBOOL matched = false; rv = pkcs11_init_check(&pLibCtx, FALSE); if (CKR_OK != rv) @@ -1620,11 +2011,13 @@ CK_RV pkcs11_key_generate_pair return rv; } - if (CKM_EC_KEY_PAIR_GEN != pMechanism->mechanism) + if ((CKM_EC_KEY_PAIR_GEN != pMechanism->mechanism) && (CKM_RSA_PKCS_KEY_PAIR_GEN != pMechanism->mechanism)) { return CKR_MECHANISM_INVALID; } + isRsa = (CKM_RSA_PKCS_KEY_PAIR_GEN == pMechanism->mechanism) ? true : false; + /* Look for supported/mandatory attributes */ for (i = 0; i < ulPrivateKeyAttributeCount; i++) { @@ -1644,6 +2037,20 @@ CK_RV pkcs11_key_generate_pair } } +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + if (true == isRsa) + { + for (i = 0; i < ulPublicKeyAttributeCount; i++) + { + if (CKA_MODULUS_BITS == pPublicKeyTemplate[i].type) + { + pData = &pPublicKeyTemplate[i]; + break; + } + } + } +#endif + if (NULL == pLabel || pLabel->ulValueLen > (CK_ULONG)PKCS11_MAX_LABEL_SIZE) { PKCS11_DEBUG("pLabel is NULL\r\n"); @@ -1662,9 +2069,7 @@ CK_RV pkcs11_key_generate_pair return CKR_TEMPLATE_INCONSISTENT; } - /* Must create two new objects - a public and private key */ - rv = pkcs11_object_alloc(pSession->slot->slot_id, &pPrivate); if (CKR_OK == rv) @@ -1683,31 +2088,66 @@ CK_RV pkcs11_key_generate_pair if (CKR_OK == rv) { pPrivate->class_id = CKO_PRIVATE_KEY; - CK_ULONG ecKeyTableSz = sizeof(ec_key_data_table) / sizeof(ec_key_data_table[0]); - for (i = 0; i < ecKeyTableSz; i++) + if(false == isRsa) { - /* coverity[misra_c_2012_rule_21_16_violation:FALSE] CK_VOID_PTR is a pointer type */ - if (0 == memcmp(ec_key_data_table[i].curve_oid, pData->pValue, pData->ulValueLen)) + CK_BYTE keyTableSz = (CK_BYTE)(sizeof(ec_key_data_table) / sizeof(ec_key_data_table[0])); + for (i = 0; i < keyTableSz; i++) { - //Key OID matched and we got the private key type - ecKeyTableIdx = i; - OidMatched = true; - break; + /* coverity[misra_c_2012_rule_21_16_violation:FALSE] CK_VOID_PTR is a pointer type */ + if (0 == memcmp((CK_BYTE_PTR)ec_key_data_table[i].curve_oid, (CK_BYTE_PTR)pData->pValue, pData->ulValueLen)) + { + //Key OID matched and we got the private key type + keyTableIdx = i; + matched = true; + break; + } } } +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + else + { + CK_BYTE keyTableSz = (CK_BYTE)(sizeof(rsa_key_data_table) / sizeof(rsa_key_data_table[0])); + for (i = 0; i < keyTableSz; i++) + { + if (rsa_key_data_table[i].rsa_modulus_bits == *((CK_ULONG_PTR)pData->pValue)) + { + //Modulus size in bits matched and we got the private key type + keyTableIdx = i; + matched = true; + break; + } + } + } +#endif - if (false == OidMatched) + if (false == matched) { rv = CKR_TEMPLATE_INCONSISTENT; } +#if ATCA_TA_SUPPORT else { -#if ATCA_TA_SUPPORT - (void)talib_handle_init_private_key(&pPrivate->handle_info, ec_key_data_table[ecKeyTableIdx].ec_key_type, - TA_ALG_MODE_ECC_ECDSA, TA_PROP_SIGN_INT_EXT_DIGEST, - TA_PROP_NO_KEY_AGREEMENT); +#if PKCS11_RSA_SUPPORT_ENABLE + if (true == isRsa) + { + if (TA_KEY_TYPE_RSA1024 == rsa_key_data_table[keyTableIdx].rsa_key_type) + { + rv = CKR_DEVICE_ERROR; + } + else + { + (void)talib_handle_init_private_key(&pPrivate->handle_info, rsa_key_data_table[keyTableIdx].rsa_key_type, TA_ALG_MODE_RSA_SSA_1_5, TA_PROP_SIGN_INT_EXT_DIGEST, TA_PROP_KEY_AGREEMENT_OUT_BUFF); + } + } + else #endif - + { + (void)talib_handle_init_private_key(&pPrivate->handle_info, ec_key_data_table[keyTableIdx].ec_key_type, TA_ALG_MODE_ECC_ECDSA, TA_PROP_SIGN_INT_EXT_DIGEST, TA_PROP_KEY_AGREEMENT_OUT_BUFF); + } + } +#endif + if (CKR_OK == rv) + { rv = pkcs11_config_key(pLibCtx, pSession->slot, pPrivate, pLabel); } } @@ -1718,13 +2158,24 @@ CK_RV pkcs11_key_generate_pair pPublic->flags = pPrivate->flags; (void)memcpy(pPublic->name, pLabel->pValue, pLabel->ulValueLen); pPublic->class_id = CKO_PUBLIC_KEY; - pPublic->class_type = CKK_EC; pPublic->attributes = pkcs11_key_public_attributes; pPublic->count = pkcs11_key_public_attributes_count; - pPublic->size = ec_key_data_table[ecKeyTableIdx].pubkey_sz; #if ATCA_CA_SUPPORT pPublic->config = &((pkcs11_slot_ctx_ptr)pSession->slot)->cfg_zone; #endif +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + if (true == isRsa) + { + pPublic->class_type = CKK_RSA; + pPublic->size = rsa_key_data_table[keyTableIdx].pubkey_sz; + } + else +#endif + { + pPublic->class_type = CKK_EC; + pPublic->size = ec_key_data_table[keyTableIdx].pubkey_sz; + } + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) { ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); @@ -1776,7 +2227,7 @@ CK_RV pkcs11_key_generate_pair return rv; } -#ifdef ATCA_NO_HEAP +#if defined(ATCA_NO_HEAP) && ATCA_CA_SUPPORT static uint8_t pkcs11_key_cache[32]; static uint8_t pkcs11_key_used(uint8_t * key, size_t keylen) @@ -1795,6 +2246,7 @@ static uint8_t pkcs11_key_used(uint8_t * key, size_t keylen) } #endif +#if ATCA_CA_SUPPORT 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) { @@ -1821,11 +2273,10 @@ static CK_RV pkcs11_key_derive_ca(pkcs11_session_ctx_ptr pSession, pkcs11_object else { ATCA_STATUS status = ATCA_SUCCESS; + pkcs11_lib_ctx_ptr pLibCtx = pkcs11_get_context(); + if (atcab_is_ca_device(atcab_get_device_type_ext(pSession->slot->device_ctx))) { - - #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; @@ -1878,15 +2329,51 @@ static CK_RV pkcs11_key_derive_ca(pkcs11_session_ctx_ptr pSession, pkcs11_object status = ATCA_GEN_FAIL; } (void)pkcs11_unlock_both(pLibCtx); - } - #endif } - else + rv = pkcs11_util_convert_rv(status); + } + } + + return rv; +} +#endif + +#if ATCA_TA_SUPPORT +static CK_RV pkcs11_key_derive_ta(pkcs11_session_ctx_ptr pSession, pkcs11_object_ptr pBaseKey, pkcs11_object_ptr pSecretKey, + CK_ECDH1_DERIVE_PARAMS_PTR pEcdhParameters) +{ + CK_RV rv = CKR_ARGUMENTS_BAD; + + if ((NULL != pSession) && (NULL != pBaseKey) && (NULL != pSecretKey) && (NULL != pEcdhParameters)) + { + pSecretKey->attributes = pkcs11_key_secret_attributes; + pSecretKey->count = pkcs11_key_secret_attributes_count; + pSecretKey->size = 32; + 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))) + { + pSecretKey->data = pkcs11_key_cache; + } +#else + pSecretKey->data = pkcs11_os_malloc(pSecretKey->size); +#endif + if (NULL == pSecretKey->data) + { + rv = CKR_HOST_MEMORY; + } + else + { + ATCA_STATUS status = ATCA_SUCCESS; + pkcs11_lib_ctx_ptr pLibCtx = pkcs11_get_context(); + if (atcab_is_ta_device(atcab_get_device_type_ext(pSession->slot->device_ctx))) { - #if ATCA_TA_SUPPORT - status = talib_ecdh_compat(pSession->slot->device_ctx, pBaseKey->slot, &pEcdhParameters->pPublicData[1], (uint8_t*)pSecretKey->data); - #endif + if (CKR_OK == (rv = pkcs11_lock_both(pLibCtx))) + { + status = talib_ecdh_compat(pSession->slot->device_ctx, pBaseKey->slot, &pEcdhParameters->pPublicData[1], (uint8_t*)pSecretKey->data); + (void)pkcs11_unlock_both(pLibCtx); + } } rv = pkcs11_util_convert_rv(status); } @@ -1894,6 +2381,7 @@ static CK_RV pkcs11_key_derive_ca(pkcs11_session_ctx_ptr pSession, pkcs11_object return rv; } +#endif CK_RV pkcs11_key_derive ( @@ -2019,7 +2507,15 @@ CK_RV pkcs11_key_derive { if (atcab_is_ca_device(atcab_get_device_type_ext(pSession->slot->device_ctx))) { +#if ATCA_CA_SUPPORT rv = pkcs11_key_derive_ca(pSession, pBaseKey, pSecretKey, pEcdhParameters); +#endif + } + else + { +#if ATCA_TA_SUPPORT + rv = pkcs11_key_derive_ta(pSession, pBaseKey, pSecretKey, pEcdhParameters); +#endif } } diff --git a/lib/pkcs11/pkcs11_key.h b/lib/pkcs11/pkcs11_key.h index 1c789fb92..7e0f1cb0f 100644 --- a/lib/pkcs11/pkcs11_key.h +++ b/lib/pkcs11/pkcs11_key.h @@ -51,21 +51,50 @@ typedef struct pkcs11_ecc_key_info_s CK_ULONG sig_sz; }pkcs11_ecc_key_info_t; +typedef struct pkcs11_rsa_key_info_s +{ +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + CK_BYTE rsa_key_type; + CK_BYTE rsa_encrypt_mode; + CK_BYTE rsa_decrypt_mode; + CK_BYTE rsa_asn1_header_size; + CK_BYTE rsa_pss_asn1_header_size; + CK_BYTE_PTR rsa_asn1_header; + CK_BYTE_PTR rsa_pss_asn1_header; + CK_BYTE_PTR rsa_public_exp_asn1_header; + CK_BYTE_PTR rsa_public_exp; + CK_ULONG rsa_modulus_bits; + CK_ULONG pubkey_sz; + CK_ULONG sig_min_msg_sz; + CK_ULONG sig_sz; +#endif +}pkcs11_rsa_key_info_t; + +typedef struct pkcs11_key_info_s +{ + const pkcs11_ecc_key_info_t* ecc_key_info; + const pkcs11_rsa_key_info_t* rsa_key_info; +}pkcs11_key_info_t; + #define PKCS11_X962_ASN1_HEADER_SZ 3u -//Maximum ASN1 Header size for the supported ECC curves (ECCP256/224/384/521) -//Set to ASN1 header size for ECCP256 which has the max size -#define PKCS11_MAX_ECC_ASN1_HDR_SIZE ATCA_ECCP256_ASN1_HDR_SIZE +//Maximum ASN1 Header size for the supported ECC and RSA curves (ECCP256/224/384/521, RSA1024/2048/3072/4096) +#define PKCS11_MAX_ECC_ASN1_HDR_SIZE ATCA_ECCP256_ASN1_HDR_SIZE +#define PKCS11_MAX_ECC_RSA_ASN1_HDR_SIZE ATCA_RSA4K_ASN1_HDR_SIZE +#define PKCS11_MAX_ECC_RSA_PB_KEY_SIZE ATCA_MAX_ECC_RSA_PB_KEY_SIZE #if ATCA_TA_SUPPORT -//Max public key size supported (ECCP521) in case of TA +//Max public key size supported (ECCP521 for ECC and RSA4096 for RSA) in case of TA #define PKCS11_MAX_ECC_PB_KEY_SIZE TA_ECC521_PUB_KEY_SIZE + #define PKCS11_MAX_RSA_PB_KEY_SIZE TA_KEY_TYPE_RSA4096_SIZE #else //Max public key size supported (ECCP256) in case of ECC device #define PKCS11_MAX_ECC_PB_KEY_SIZE ATCA_ECCP256_PUBKEY_SIZE #endif extern const pkcs11_ecc_key_info_t ec_key_data_table[4]; +extern const pkcs11_rsa_key_info_t rsa_key_data_table[4]; +extern const pkcs11_key_info_t key_data_table[]; extern const pkcs11_attrib_model pkcs11_key_public_attributes[]; extern const CK_ULONG pkcs11_key_public_attributes_count; @@ -80,6 +109,7 @@ extern CK_BYTE pkcs11_x962_asn1_hdr_ec256[]; extern CK_BYTE pkcs11_key_ec_params_p256[]; #if ATCA_TA_SUPPORT + extern CK_BYTE pkcs11_ec_pbkey_asn1_hdr_p224[]; extern CK_BYTE pkcs11_x962_asn1_hdr_ec224[]; extern CK_BYTE pkcs11_key_ec_params_p224[]; @@ -91,8 +121,23 @@ extern CK_BYTE pkcs11_key_ec_params_p384[]; extern CK_BYTE pkcs11_ec_pbkey_asn1_hdr_p521[]; extern CK_BYTE pkcs11_x962_asn1_hdr_ec521[]; extern CK_BYTE pkcs11_key_ec_params_p521[]; + +#if PKCS11_RSA_SUPPORT_ENABLE +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsa1024[]; +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss1024[]; +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsa2048[]; +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss2048[]; +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsa3072[]; +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss3072[]; +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsa4096[]; +extern CK_BYTE pkcs11_pbkey_asn1_hdr_rsapss4096[]; +extern CK_BYTE pkcs11_sha256_asn1_hdr[19]; + +extern CK_BYTE pkcs11_rsa_public_exp_asn1_hdr[]; +extern CK_BYTE pkcs11_rsa_public_exp[]; +#endif #endif -CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute, const pkcs11_ecc_key_info_t *ec_key_info); +CK_RV pkcs11_key_write(CK_VOID_PTR pSession, CK_VOID_PTR pObject, CK_ATTRIBUTE_PTR pAttribute); CK_RV pkcs11_key_generate(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey); CK_RV pkcs11_key_generate_pair(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, @@ -103,7 +148,7 @@ CK_RV pkcs11_key_derive(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism, CK_ATTRIBUTE_PTR pTemplate, CK_ULONG ulCount, CK_OBJECT_HANDLE_PTR phKey); CK_RV pkcs11_key_clear_session_cache(pkcs11_session_ctx_ptr session_ctx); CK_RV pkcs11_key_clear_object_cache(pkcs11_object_ptr pObject); -const pkcs11_ecc_key_info_t* pkcs11_get_object_key_type(ATCADevice device_ctx, pkcs11_object_ptr obj_ptr); +const pkcs11_key_info_t* pkcs11_get_object_key_type(ATCADevice device_ctx, pkcs11_object_ptr obj_ptr); #if ATCA_TA_SUPPORT CK_RV pkcs11_ta_get_pubkey(CK_VOID_PTR pObject, cal_buffer *key_buffer, pkcs11_session_ctx_ptr session_ctx); #endif diff --git a/lib/pkcs11/pkcs11_mech.c b/lib/pkcs11/pkcs11_mech.c index b56590eef..be967852f 100644 --- a/lib/pkcs11/pkcs11_mech.c +++ b/lib/pkcs11/pkcs11_mech.c @@ -311,6 +311,12 @@ static pcks11_mech_table_e pkcs11_mech_list_ta[] = { //CKM_AES_CFB1, //CKM_AES_KEY_WRAP, //CKM_AES_KEY_WRAP_PAD, +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + { CKM_RSA_PKCS_KEY_PAIR_GEN, { 1024, 4096, CKF_HW | CKF_GENERATE | CKF_GENERATE_KEY_PAIR } }, + { CKM_RSA_PKCS, { 1024, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_RSA_PKCS_PSS, { 1024, 4096, CKF_HW | CKF_SIGN | CKF_VERIFY } }, + { CKM_RSA_PKCS_OAEP, { 1024, 4096, CKF_HW | CKF_ENCRYPT | CKF_DECRYPT } }, +#endif }; #endif diff --git a/lib/pkcs11/pkcs11_object.c b/lib/pkcs11/pkcs11_object.c index 873c418f7..ab3ff3fd4 100644 --- a/lib/pkcs11/pkcs11_object.c +++ b/lib/pkcs11/pkcs11_object.c @@ -385,13 +385,13 @@ CK_RV pkcs11_object_get_size(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hObjec } rv = pkcs11_session_check(NULL, hSession); - if (CKR_OK == rv) + if (CKR_OK != rv) { return rv; } rv = pkcs11_object_check(&pObject, hObject); - if (CKR_OK == rv) + if (CKR_OK != rv) { return rv; } @@ -472,8 +472,10 @@ CK_RV pkcs11_object_create( CK_ULONG i; pkcs11_lib_ctx_ptr pLibCtx = NULL; pkcs11_session_ctx_ptr pSession = NULL; - CK_ULONG ecKeyTableIdx = 0; - CK_BBOOL OidMatched = false; +#if ATCA_TA_SUPPORT + CK_BBOOL matched = false; + CK_ULONG keyTableIdx = 0; +#endif rv = pkcs11_init_check(&pLibCtx, FALSE); if (CKR_OK != rv) @@ -503,6 +505,7 @@ CK_RV pkcs11_object_create( break; case CKA_VALUE: case CKA_EC_POINT: + case CKA_MODULUS: pData = &pTemplate[i]; break; case CKA_EC_PARAMS: @@ -513,7 +516,7 @@ CK_RV pkcs11_object_create( } } - //Data to be supplied by user for the certificate/ecc key object data to be written to device + //Data to be supplied by user for the certificate/ecc/rsa key object data to be written to device if (NULL == pData) { return CKR_TEMPLATE_INCOMPLETE; @@ -522,12 +525,17 @@ CK_RV pkcs11_object_create( if (CKO_PUBLIC_KEY == *pClass || CKO_PRIVATE_KEY == *pClass) { //Mandatory attributes for ECC KEY objects as per PKCS11 v2.40 standards - if (NULL == pKeyType || NULL == pEC_OID_Data) + if (NULL == pKeyType) { return CKR_TEMPLATE_INCOMPLETE; } - if (CKK_EC != *pKeyType) + if ((CKK_EC != *pKeyType) && (CKK_RSA != *pKeyType)) + { + return CKR_TEMPLATE_INCONSISTENT; + } + + if ((CKK_EC == *pKeyType) && (NULL == pEC_OID_Data)) { return CKR_TEMPLATE_INCONSISTENT; } @@ -557,24 +565,44 @@ CK_RV pkcs11_object_create( if (NULL != pObject) { - CK_ULONG ecKeyTableSz = 0u; - if (CKO_PUBLIC_KEY == *pClass || CKO_PRIVATE_KEY == *pClass) +#if ATCA_TA_SUPPORT + ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); + + if (atcab_is_ta_device(dev_type) && (CKO_PUBLIC_KEY == *pClass || CKO_PRIVATE_KEY == *pClass)) { - ecKeyTableSz = sizeof(ec_key_data_table) / sizeof(ec_key_data_table[0]); - for (i = 0; i < ecKeyTableSz; i++) + if (CKK_EC == *pKeyType) + { + CK_BYTE keyTableSz = (CK_BYTE)(sizeof(ec_key_data_table) / sizeof(ec_key_data_table[0])); + for (i = 0; i < keyTableSz; i++) + { + /* coverity[misra_c_2012_rule_21_16_violation:FALSE] CK_VOID_PTR is a pointer type */ + if ((0 == memcmp(pEC_OID_Data->pValue, ec_key_data_table[i].curve_oid, pEC_OID_Data->ulValueLen))) + { + //Key OID matched and we got the private key type + keyTableIdx = i; + matched = true; + break; + } + } + } +#if PKCS11_RSA_SUPPORT_ENABLE + else { - /* coverity[misra_c_2012_rule_21_16_violation:FALSE] CK_VOID_PTR is a pointer type */ - if ((0 == memcmp(pEC_OID_Data->pValue, ec_key_data_table[i].curve_oid, pEC_OID_Data->ulValueLen))) + CK_BYTE keyTableSz = (CK_BYTE)(sizeof(rsa_key_data_table) / sizeof(rsa_key_data_table[0])); + for (i = 0; i < keyTableSz; i++) { - //Key OID matched and we got the private key type - ecKeyTableIdx = i; - OidMatched = true; - break; + if (pData->ulValueLen == rsa_key_data_table[i].pubkey_sz) + { + //Modulus size matched and we got the private key type + keyTableIdx = i; + matched = true; + break; + } } } +#endif } - - ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); +#endif switch (*pClass) { @@ -590,64 +618,93 @@ CK_RV pkcs11_object_create( } break; case CKO_PUBLIC_KEY: - if (true == OidMatched) - { - pObject->class_id = CKO_PUBLIC_KEY; - - if(atcab_is_ta_device(dev_type)) - { + pObject->class_id = CKO_PUBLIC_KEY; + pObject->class_type = (CKK_EC == *pKeyType) ? (CKK_EC) : (CKK_RSA); #if ATCA_TA_SUPPORT - (void)talib_handle_init_public_key(&pObject->handle_info, ec_key_data_table[ecKeyTableIdx].ec_key_type, - TA_ALG_MODE_ECC_ECDSA, TA_PROP_NO_SIGN_GENERATION, - TA_PROP_NO_KEY_AGREEMENT); + if(atcab_is_ta_device(dev_type)) + { + if (false == matched) + { + return CKR_ARGUMENTS_BAD; + } + else + { + if (CKK_EC == *pKeyType) + { + (void)talib_handle_init_public_key(&pObject->handle_info, ec_key_data_table[keyTableIdx].ec_key_type, TA_ALG_MODE_ECC_ECDSA, TA_PROP_NO_SIGN_GENERATION, TA_PROP_NO_KEY_AGREEMENT); + } +#if PKCS11_RSA_SUPPORT_ENABLE + else if (CKK_RSA == *pKeyType) + { + (void)talib_handle_init_public_key(&pObject->handle_info, rsa_key_data_table[keyTableIdx].rsa_key_type, TA_ALG_MODE_RSA_SSA_1_5, TA_PROP_NO_SIGN_GENERATION, TA_PROP_NO_KEY_AGREEMENT); + } #endif + else + { + return CKR_KEY_TYPE_INCONSISTENT; + } } - if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + } +#endif + if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + { + if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) { - if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) + rv = pkcs11_key_write(pSession, pObject, pData); + if (CKR_OK != rv) { - rv = pkcs11_key_write(pSession, pObject, pData, &ec_key_data_table[ecKeyTableIdx]); - if (CKR_OK != rv) - { #if !PKCS11_USE_STATIC_CONFIG - (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); #endif - } } - (void)pkcs11_unlock_device(pLibCtx); } + (void)pkcs11_unlock_device(pLibCtx); } break; case CKO_PRIVATE_KEY: - if (true == OidMatched) + pObject->class_id = CKO_PRIVATE_KEY; + pObject->class_type = (CKK_EC == *pKeyType) ? (CKK_EC) : (CKK_RSA); +#if ATCA_TA_SUPPORT + if(atcab_is_ta_device(dev_type)) { - pObject->class_id = CKO_PRIVATE_KEY; - - if(atcab_is_ta_device(dev_type)) + if (false == matched) { - -#if ATCA_TA_SUPPORT - (void)talib_handle_init_private_key(&pObject->handle_info, ec_key_data_table[ecKeyTableIdx].ec_key_type, - TA_ALG_MODE_ECC_ECDSA, TA_PROP_SIGN_INT_EXT_DIGEST, - TA_PROP_NO_KEY_AGREEMENT); - /* coverity[cert_int31_c_violation] signed to unsigned casting */ - pObject->handle_info.property &= (uint16_t)(~TA_PROP_EXECUTE_ONLY_KEY_GEN_MASK); -#endif - if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + return CKR_ARGUMENTS_BAD; + } + else + { + if (CKK_EC == *pKeyType) + { + (void)talib_handle_init_private_key(&pObject->handle_info, ec_key_data_table[keyTableIdx].ec_key_type, TA_ALG_MODE_ECC_ECDSA, TA_PROP_SIGN_INT_EXT_DIGEST, TA_PROP_NO_KEY_AGREEMENT); + } +#if PKCS11_RSA_SUPPORT_ENABLE + else if (CKK_RSA == *pKeyType) + { + (void)talib_handle_init_private_key(&pObject->handle_info, rsa_key_data_table[keyTableIdx].rsa_key_type, TA_ALG_MODE_RSA_SSA_1_5, TA_PROP_SIGN_INT_EXT_DIGEST, TA_PROP_KEY_AGREEMENT_OUT_BUFF); + } +#endif + else + { + return CKR_KEY_TYPE_INCONSISTENT; + } + } + /* coverity[cert_int31_c_violation] signed to unsigned casting */ + pObject->handle_info.property &= (uint16_t)(~TA_PROP_EXECUTE_ONLY_KEY_GEN_MASK); + } +#endif + if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + { + if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) + { + rv = pkcs11_key_write(pSession, pObject, pData); + if (CKR_OK != rv) { - if (CKR_OK == (rv = pkcs11_config_key(pLibCtx, pSession->slot, pObject, pLabel))) - { - rv = pkcs11_key_write(pSession, pObject, pData, &ec_key_data_table[ecKeyTableIdx]); - if (CKR_OK != rv) - { #if !PKCS11_USE_STATIC_CONFIG - (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); + (void)pkcs11_config_remove_object(pLibCtx, pSession->slot, pObject); #endif - } - } - (void)pkcs11_unlock_device(pLibCtx); } } + (void)pkcs11_unlock_device(pLibCtx); } break; default: @@ -756,6 +813,11 @@ ATCA_STATUS pkcs11_object_load_handle_info(ATCADevice device, pkcs11_lib_ctx_ptr if (ATCA_SUCCESS == talib_info_get_handle_info(device, pObj->slot, &handle_info)) { (void)memcpy(&pObj->handle_info, &handle_info.attributes, sizeof(ta_element_attributes_t)); + + if (CKO_PRIVATE_KEY == pObj->class_id || CKO_PUBLIC_KEY == pObj->class_id) + { + (void)pkcs11_config_set_key_size(pObj); + } bHandleinfosuccess = true; } else @@ -805,7 +867,7 @@ CK_RV pkcs11_object_is_private(pkcs11_object_ptr pObject, CK_BBOOL *is_private, else if (atcab_is_ta_device(dev_type)) { #if ATCA_TA_SUPPORT - *is_private = (TA_CLASS_PRIVATE_KEY == (pObject->handle_info.element_CKA & 0xFu)); + *is_private = (TA_CLASS_PRIVATE_KEY == (pObject->handle_info.element_CKA & 0x7u)); rv = CKR_OK; #endif } diff --git a/lib/pkcs11/pkcs11_session.c b/lib/pkcs11/pkcs11_session.c index fa9cda08a..337d98b0a 100644 --- a/lib/pkcs11/pkcs11_session.c +++ b/lib/pkcs11/pkcs11_session.c @@ -551,7 +551,7 @@ CK_RV pkcs11_session_login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType, CK } } -#if ATCA_TA_SUPPORT && ATCA_HOSTLIB_EN +#if (ATCA_TA_SUPPORT && ATCA_HOSTLIB_EN && TALIB_AUTH_EN) ATCA_STATUS status; if (CKR_OK == rv && atcab_is_ta_device(atcab_get_device_type_ext(session_ctx->slot->device_ctx))) { @@ -625,7 +625,7 @@ CK_RV pkcs11_session_logout(CK_SESSION_HANDLE hSession) return CKR_SESSION_CLOSED; } -#if ATCA_TA_SUPPORT +#if (ATCA_TA_SUPPORT && TALIB_AUTH_EN) if (session_ctx->slot->logged_in && atcab_is_ta_device(atcab_get_device_type_ext(session_ctx->slot->device_ctx))) { if (CKR_OK == (rv = pkcs11_lock_both(lib_ctx))) diff --git a/lib/pkcs11/pkcs11_signature.c b/lib/pkcs11/pkcs11_signature.c index c64f5b27c..af28e0ce3 100644 --- a/lib/pkcs11/pkcs11_signature.c +++ b/lib/pkcs11/pkcs11_signature.c @@ -66,6 +66,9 @@ static CK_RV pkcs11_signature_check_key( rv = CKR_OK; } break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS: +#endif case CKM_ECDSA: if (CKO_PRIVATE_KEY == pKey->class_id) { @@ -80,6 +83,26 @@ static CK_RV pkcs11_signature_check_key( /* do nothing */ } break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS_PSS: + // pMechanism->pParameter should point to CK_RSA_PKCS_PSS_PARAMS + if ((NULL != pMechanism->pParameter) && (sizeof(CK_RSA_PKCS_PSS_PARAMS) == pMechanism->ulParameterLen)) + { + if (CKO_PRIVATE_KEY == pKey->class_id) + { + rv = CKR_OK; + } + else if (verify && (CKO_PUBLIC_KEY == pKey->class_id)) + { + rv = CKR_OK; + } + else + { + /* do nothing */ + } + } + break; +#endif default: rv = CKR_MECHANISM_INVALID; break; @@ -103,13 +126,24 @@ static CK_ULONG pkcs11_signature_get_len( { if (atcab_is_ca_device(dev_type)) { +#if ATCA_CA_SUPPORT ulSiglen = ATCA_ECCP256_SIG_SIZE; +#endif } else if (atcab_is_ta_device(dev_type)) { #if ATCA_TA_SUPPORT uint8_t key_type = ((pKey->handle_info.element_CKA & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT); - ulSiglen = (CK_ULONG)ec_key_data_table[key_type].sig_sz; + if (key_type < TA_KEY_TYPE_ECC_COUNT) + { + ulSiglen = key_data_table[key_type].ecc_key_info->sig_sz; + } +#if PKCS11_RSA_SUPPORT_ENABLE + else + { + ulSiglen = key_data_table[key_type].rsa_key_info->sig_sz; + } +#endif #endif } else @@ -269,7 +303,6 @@ CK_RV pkcs11_signature_sign( { if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) { - #if ATCA_CA_SUPPORT rv = pkcs11_util_convert_rv(atcab_sign_ext(pSession->slot->device_ctx, pKey->slot, pData, pSignature)); #endif @@ -285,11 +318,8 @@ CK_RV pkcs11_signature_sign( cal_buffer msg_buf = CAL_BUF_INIT(ulDataLen, pData); cal_buffer sign_buf = CAL_BUF_INIT(*pulSignatureLen, pSignature); //EC CURVE type depend on minium message size constraints for signing external messages in TA devices - if (ulDataLen >= ec_key_data_table[key_type].min_msg_sz) - { - rv = pkcs11_util_convert_rv(talib_sign_external(pSession->slot->device_ctx, key_type, pKey->slot, TA_HANDLE_INPUT_BUFFER, &msg_buf, - &sign_buf)); - } + rv = pkcs11_util_convert_rv(talib_sign_external(pSession->slot->device_ctx, key_type, pKey->slot, TA_HANDLE_INPUT_BUFFER, &msg_buf, + &sign_buf)); #endif (void)pkcs11_unlock_device(pLibCtx); } @@ -300,6 +330,41 @@ CK_RV pkcs11_signature_sign( } } break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS: + case CKM_RSA_PKCS_PSS: + if (CKR_OK == (rv = pkcs11_signature_check_params(pSignature, pulSignatureLen, pkcs11_signature_get_len(dev_type, pKey)))) + { + if (atcab_is_ta_device(dev_type)) + { + if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + { + uint8_t key_type = ((pKey->handle_info.element_CKA & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT); + uint8_t mode = (CKM_RSA_PKCS == pSession->active_mech) ? (key_type) : (uint8_t)(key_type | (uint8_t)(TA_ALG_MODE_RSA_SSA_PSS << TA_ALG_MODE_SHIFT)); + cal_buffer msg_buf = CAL_BUF_INIT(ulDataLen, pData); + cal_buffer sign_buf = CAL_BUF_INIT(*pulSignatureLen, pSignature); + + if (TA_KEY_TYPE_RSA1024 == key_type) + { + rv = CKR_DEVICE_ERROR; + } + else + { + // Data to be signed should not include encoded data(asn1 header) of SHA256 + if (0 == memcmp(pData, pkcs11_sha256_asn1_hdr, sizeof(pkcs11_sha256_asn1_hdr))) + { + (void)memmove(pData, &pData[sizeof(pkcs11_sha256_asn1_hdr)], TA_SHA256_DIGEST_SIZE); + msg_buf.len = TA_SHA256_DIGEST_SIZE; + } + rv = pkcs11_util_convert_rv(talib_sign_external(pSession->slot->device_ctx, mode, pKey->slot, TA_HANDLE_INPUT_BUFFER, &msg_buf, + &sign_buf)); + } + (void)pkcs11_unlock_device(pLibCtx); + } + } + } + break; +#endif default: /* An irrationality occured */ rv = CKR_GENERAL_ERROR; @@ -437,7 +502,7 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ return rv; } - const pkcs11_ecc_key_info_t *ec_key_data = pkcs11_get_object_key_type(pSession->slot->device_ctx, pKey); + const pkcs11_key_info_t* key_data = pkcs11_get_object_key_type(pSession->slot->device_ctx, pKey); if (CKR_OK != (rv = pkcs11_lock_context(pLibCtx))) { @@ -480,20 +545,20 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ } break; case CKM_ECDSA: - if (NULL == ec_key_data) + if (NULL == key_data || NULL == key_data->ecc_key_info) { return CKR_ARGUMENTS_BAD; } /* Checking data length */ - if (ulDataLen < ec_key_data->min_msg_sz) + if (ulDataLen < key_data->ecc_key_info->min_msg_sz) { (void)pkcs11_unlock_context(pLibCtx); return CKR_DATA_LEN_RANGE; } /* Checking Signature length */ - if (ulSignatureLen < ec_key_data->sig_sz) + if (ulSignatureLen < key_data->ecc_key_info->sig_sz) { (void)pkcs11_unlock_context(pLibCtx); return CKR_SIGNATURE_LEN_RANGE; @@ -503,7 +568,6 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ { if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) { - ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); /* Device can't verify against a private key so ask the device for @@ -520,17 +584,18 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ } #endif } - else if (atcab_is_ta_device(dev_type)) + else if ((atcab_is_ta_device(dev_type)) && (NULL != key_data->ecc_key_info)) { #if ATCA_TA_SUPPORT - cal_buffer ec_pubkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, pub_key); + cal_buffer ec_pubkey_buf = CAL_BUF_INIT(key_data->ecc_key_info->pubkey_sz, pub_key); if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pKey, &ec_pubkey_buf, pSession))) { +#if TALIB_VERIFY_EXTERN_EN uint8_t key_type = ((pKey->handle_info.element_CKA & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT); cal_buffer sign_buf = CAL_BUF_INIT(ulSignatureLen, pSignature); - cal_buffer pbkey_buf = CAL_BUF_INIT(ec_key_data->pubkey_sz, pub_key); + cal_buffer pbkey_buf = CAL_BUF_INIT(key_data->ecc_key_info->pubkey_sz, pub_key); cal_buffer msg_buf = CAL_BUF_INIT(ulDataLen, pData); -#if TALIB_VERIFY_EXTERN_EN + rv = pkcs11_util_convert_rv(talib_verify_extern(pSession->slot->device_ctx, key_type, TA_HANDLE_INPUT_BUFFER, &pbkey_buf, &sign_buf, &msg_buf, &verified)); #endif @@ -555,10 +620,11 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ else if (atcab_is_ta_device(dev_type)) { #if ATCA_TA_SUPPORT +#if TALIB_VERIFY_STORED_EN uint8_t key_type = ((pKey->handle_info.element_CKA & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT); cal_buffer sign_buf = CAL_BUF_INIT(ulSignatureLen, pSignature); cal_buffer msg_buf = CAL_BUF_INIT(ulDataLen, pData); -#if TALIB_VERIFY_STORED_EN + rv = pkcs11_util_convert_rv(talib_verify_stored(pSession->slot->device_ctx, key_type, TA_HANDLE_INPUT_BUFFER, pKey->slot, &sign_buf, &msg_buf, &verified)); #endif @@ -574,6 +640,77 @@ CK_RV pkcs11_signature_verify(CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData, CK_ } } break; +#if ATCA_TA_SUPPORT && PKCS11_RSA_SUPPORT_ENABLE + case CKM_RSA_PKCS: + case CKM_RSA_PKCS_PSS: + if (NULL == key_data || NULL == key_data->rsa_key_info) + { + return CKR_ARGUMENTS_BAD; + } + + /* Checking data length */ + if (ulDataLen < key_data->rsa_key_info->sig_min_msg_sz) + { + (void)pkcs11_unlock_context(pLibCtx); + return CKR_DATA_LEN_RANGE; + } + + /* Checking Signature length */ + if (ulSignatureLen < key_data->rsa_key_info->sig_sz) + { + (void)pkcs11_unlock_context(pLibCtx); + return CKR_SIGNATURE_LEN_RANGE; + } + + if (CKR_OK == (rv = pkcs11_object_is_private(pKey, &is_private, pSession))) + { + if (CKR_OK == (rv = pkcs11_lock_device(pLibCtx))) + { + ATCADeviceType dev_type = atcab_get_device_type_ext(pSession->slot->device_ctx); + + if (atcab_is_ta_device(dev_type)) + { + uint8_t key_type = ((pKey->handle_info.element_CKA & TA_HANDLE_INFO_KEY_TYPE_MASK) >> TA_HANDLE_INFO_KEY_TYPE_SHIFT); + uint8_t mode = (CKM_RSA_PKCS == pSession->active_mech) ? (key_type) : (uint8_t)(key_type | (uint8_t)(TA_ALG_MODE_RSA_SSA_PSS << TA_ALG_MODE_SHIFT)); + cal_buffer sign_buf = CAL_BUF_INIT(ulSignatureLen, pSignature); + cal_buffer msg_buf = CAL_BUF_INIT(ulDataLen, pData); + + // Data to be verified should not include encoded data(asn1 header) of SHA256 + if (0 == memcmp(pData, pkcs11_sha256_asn1_hdr, sizeof(pkcs11_sha256_asn1_hdr))) + { + (void)memmove(pData, &pData[sizeof(pkcs11_sha256_asn1_hdr)], TA_SHA256_DIGEST_SIZE); + msg_buf.len = TA_SHA256_DIGEST_SIZE; + } + + if (true == is_private) + { + /* Device can't verify against a private key so ask the device for the public key + first then perform an external verify */ + uint8_t pub_key[PKCS11_MAX_RSA_PB_KEY_SIZE]; + cal_buffer rsa_pubkey_buf = CAL_BUF_INIT(key_data->rsa_key_info->pubkey_sz, pub_key); + + if (CKR_OK == (rv = pkcs11_ta_get_pubkey(pKey, &rsa_pubkey_buf, pSession))) + { +#if TALIB_VERIFY_EXTERN_EN + rv = pkcs11_util_convert_rv(talib_verify_extern(pSession->slot->device_ctx, mode, TA_HANDLE_INPUT_BUFFER, &rsa_pubkey_buf, &sign_buf, + &msg_buf, &verified)); +#endif + } + } + else + { + /* Assume Public Key has been stored properly and verify against whatever is stored */ +#if TALIB_VERIFY_STORED_EN + rv = pkcs11_util_convert_rv(talib_verify_stored(pSession->slot->device_ctx, mode, TA_HANDLE_INPUT_BUFFER, pKey->slot, &sign_buf, + &msg_buf, &verified)); +#endif + } + } + (void)pkcs11_unlock_device(pLibCtx); + } + } + break; +#endif default: break; } diff --git a/lib/pkcs11/pkcs11_token.c b/lib/pkcs11/pkcs11_token.c index 0206589f8..cfb2d5f92 100644 --- a/lib/pkcs11/pkcs11_token.c +++ b/lib/pkcs11/pkcs11_token.c @@ -86,6 +86,7 @@ static const char * pkcs11_token_device(ATCADeviceType dev_type, uint8_t info[4] if (atcab_is_ca_device(dev_type)) { +#if ATCA_CA_SUPPORT switch (info[DEVICE_PART_LOCATION]) { case 0x00: @@ -111,10 +112,12 @@ static const char * pkcs11_token_device(ATCADeviceType dev_type, uint8_t info[4] rv = "unknown"; break; } +#endif } if (atcab_is_ta_device(dev_type)) { +#if ATCA_TA_SUPPORT if(0x01u == info[DEVICE_PRODUCT_ID_LOCATION]) { rv = "TA101"; @@ -123,6 +126,7 @@ static const char * pkcs11_token_device(ATCADeviceType dev_type, uint8_t info[4] { rv = "TA100"; } +#endif } return rv; @@ -166,6 +170,7 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL if (atcab_is_ca_device(pSlotCtx->interface_config.devtype)) { +#if ATCA_CA_SUPPORT if (ATCA_SUCCESS == rv) { /* Get the device type */ @@ -188,6 +193,7 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL rv = CKR_TOKEN_NOT_RECOGNIZED; break; } +#endif } /* Program the configuration zone */ @@ -227,6 +233,7 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL if (atcab_is_ca_device(pSlotCtx->interface_config.devtype)) { +#if ATCA_CA_SUPPORT /* Generate New Keys */ for (int i = 0; (i < 16) && (ATCA_SUCCESS == rv); i++) { @@ -235,6 +242,7 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL rv = atcab_genkey_ext(pSlotCtx->device_ctx, i, NULL); } } +#endif } else { @@ -272,11 +280,13 @@ CK_RV pkcs11_token_init(CK_SLOT_ID slotID, CK_UTF8CHAR_PTR pPin, CK_ULONG ulPinL { if (atcab_is_ca_device(pSlotCtx->interface_config.devtype)) { +#if ATCA_CA_SUPPORT /* Write the default pin */ if (CKR_OK == rv) { rv = atcab_write_zone_ext(pSlotCtx->device_ctx, ATCA_ZONE_DATA, pSlotCtx->so_pin_handle, 0, 0, buf, buflen); } +#endif } } } diff --git a/lib/wolfssl/atca_wolfssl_interface.c b/lib/wolfssl/atca_wolfssl_interface.c index 5150359ba..215da3cae 100644 --- a/lib/wolfssl/atca_wolfssl_interface.c +++ b/lib/wolfssl/atca_wolfssl_interface.c @@ -343,6 +343,7 @@ ATCA_STATUS atcac_sw_sha1_finish( return status; } +#if ATCAC_SHA256_EN /** \brief Initialize context for performing SHA256 hash in software. * * \return ATCA_SUCCESS on success, otherwise an error code. @@ -391,6 +392,109 @@ ATCA_STATUS atcac_sw_sha2_256_finish( return status; } +#endif /* ATCAC_SHA256_EN */ + +#if ATCAC_SHA384_EN +/** \brief Initialize context for performing SHA384 hash in software. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_init( + struct atcac_sha2_384_ctx* ctx /**< [in] pointer to a hash context */ +) +{ + wc_Sha384* temp_ptr = &ctx->sha; + ATCA_STATUS status = (0 == wc_InitSha384(temp_ptr)) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + + return status; +} + +/** \brief Add data to a SHA384 hash. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_update( + struct atcac_sha2_384_ctx* ctx, /**< [in] pointer to a hash context */ + const uint8_t* data, /**< [in] input data buffer */ + size_t data_size /**< [in] input data length */ +) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (data_size <= UINT32_MAX) + { + wc_Sha384* temp_ptr = &ctx->sha; + status = (0 == wc_Sha384Update(temp_ptr, data, (word32)data_size)) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + return status; +} + +/** \brief Complete the SHA384 hash in software and return the digest. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_384_finish( + struct atcac_sha2_384_ctx* ctx, /**< [in] pointer to a hash context */ + uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE] /**< [out] output buffer (48 bytes) */ +) +{ + wc_Sha384* temp_ptr = &ctx->sha; + ATCA_STATUS status = (0 == wc_Sha384Final(temp_ptr, digest)) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + + return status; +} +#endif /* ATCAC_SHA384_EN */ + +#if ATCAC_SHA512_EN +/** \brief Initialize context for performing SHA512 hash in software. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_init( + struct atcac_sha2_512_ctx* ctx /**< [in] pointer to a hash context */ +) +{ + wc_Sha512* temp_ptr = &ctx->sha; + ATCA_STATUS status = (0 == wc_InitSha512(temp_ptr)) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + + return status; +} + +/** \brief Add data to a SHA512 hash. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_update( + struct atcac_sha2_512_ctx* ctx, /**< [in] pointer to a hash context */ + const uint8_t* data, /**< [in] input data buffer */ + size_t data_size /**< [in] input data length */ +) +{ + ATCA_STATUS status = ATCA_BAD_PARAM; + + if (data_size <= UINT32_MAX) + { + wc_Sha512* temp_ptr = &ctx->sha; + status = (0 == wc_Sha512Update(temp_ptr, data, (word32)data_size)) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + } + return status; +} + +/** \brief Complete the SHA512 hash in software and return the digest. + * + * \return ATCA_SUCCESS on success, otherwise an error code. + */ +ATCA_STATUS atcac_sw_sha2_512_finish( + struct atcac_sha2_512_ctx* ctx, /**< [in] pointer to a hash context */ + uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE] /**< [out] output buffer (64 bytes) */ +) +{ + wc_Sha512* temp_ptr = &ctx->sha; + ATCA_STATUS status = (0 == wc_Sha512Final(temp_ptr, digest)) ? ATCA_SUCCESS : ATCA_FUNC_FAIL; + + return status; +} +#endif /* ATCAC_SHA512_EN */ /** \brief Initialize context for performing CMAC in software. * @@ -947,35 +1051,72 @@ ATCA_STATUS atcac_get_subj_public_key(const struct atcac_x509_ctx* cert, cal_buf if (NULL != (key = wolfSSL_X509_get_pubkey(get_wssl_cert_from_atcac_ctx(cert)))) { - ecc_key pubKeyEcc; - (void)memset(&pubKeyEcc, 0, sizeof(ecc_key)); - word32 idx = 0; - if (0 == wc_ecc_init(&pubKeyEcc)) + if (EVP_PKEY_EC == key->type) { - int pkey_sz = key->pkey_sz; // Cast to signed int - - if (pkey_sz >= 0) + ecc_key pubKeyEcc; + (void)memset(&pubKeyEcc, 0, sizeof(ecc_key)); + word32 idx = 0; + if (0 == wc_ecc_init(&pubKeyEcc)) { - if (0 == wc_EccPublicKeyDecode((byte*)key->pkey.ptr, &idx, &pubKeyEcc, (word32)key->pkey_sz)) + int pkey_sz = key->pkey_sz; // Cast to signed int + + if (pkey_sz >= 0) { - /* coverity[misra_c_2012_rule_9_1_violation:SUPPRESS] wc_ecc_init is called to initialize pubKeyEcc */ - if (NULL != pubKeyEcc.dp) + if (0 == wc_EccPublicKeyDecode((byte*)key->pkey.ptr, &idx, &pubKeyEcc, (word32)key->pkey_sz)) { - word32 xlen = (word32)pubKeyEcc.dp->size; - word32 ylen = (word32)pubKeyEcc.dp->size; - if (0 == wc_ecc_export_public_raw(&pubKeyEcc, (byte*)subj_public_key->buf, &xlen, - (byte*)&subj_public_key->buf[pubKeyEcc.dp->size], &ylen)) + /* coverity[misra_c_2012_rule_9_1_violation:SUPPRESS] wc_ecc_init is called to initialize pubKeyEcc */ + if (NULL != pubKeyEcc.dp) { - status = ATCA_SUCCESS; + word32 xlen = (word32)pubKeyEcc.dp->size; + word32 ylen = (word32)pubKeyEcc.dp->size; + if (0 == wc_ecc_export_public_raw(&pubKeyEcc, (byte*)subj_public_key->buf, &xlen, + (byte*)&subj_public_key->buf[pubKeyEcc.dp->size], &ylen)) + { + subj_public_key->len = (word64)(xlen) + (word64)(ylen); + status = ATCA_SUCCESS; + } } } } } + wolfSSL_EVP_PKEY_free(key); + if (0 != wc_ecc_free(&pubKeyEcc)) + { + status = ATCA_BAD_PARAM; + } } - wolfSSL_EVP_PKEY_free(key); - if (0 != wc_ecc_free(&pubKeyEcc)) + else { - status = ATCA_BAD_PARAM; + RsaKey rsaKey; + (void)memset(&rsaKey, 0, sizeof(RsaKey)); + word32 idx = 0; + + if (0 == wc_InitRsaKey(&rsaKey, NULL)) + { + int pkey_sz = key->pkey_sz; // Cast to signed int + + if (pkey_sz >= 0) + { + if (0 == wc_RsaPublicKeyDecode((byte*)key->pkey.ptr, &idx, &rsaKey, (word32)key->pkey_sz)) + { + int nlen = mp_unsigned_bin_size(&rsaKey.n); + // Check buffer size before storing public key + if ((nlen > 0) && ((unsigned long)nlen <= subj_public_key->len)) + { + if (0 == mp_to_unsigned_bin(&rsaKey.n, (byte*)subj_public_key->buf)) + { + subj_public_key->len = (word64)nlen; + status = ATCA_SUCCESS; + } + } + } + } + wolfSSL_EVP_PKEY_free(key); + if (0 != wc_FreeRsaKey(&rsaKey)) + { + status = ATCA_BAD_PARAM; + } + } } } } @@ -1091,6 +1232,11 @@ ATCA_STATUS atcac_get_auth_key_id(const struct atcac_x509_ctx* cert, cal_buffer* { status = ATCA_SUCCESS; } + else + { + /* No data is available */ + status = cal_buf_set_used(auth_key_id, 0U); + } } } return status; @@ -1110,10 +1256,26 @@ struct atcac_sha1_ctx * atcac_sha1_ctx_new(void) return (struct atcac_sha1_ctx*)hal_malloc(sizeof(atcac_sha1_ctx_t)); } +#if ATCAC_SHA256_EN struct atcac_sha2_256_ctx * atcac_sha256_ctx_new(void) { return (struct atcac_sha2_256_ctx*)hal_malloc(sizeof(atcac_sha2_256_ctx_t)); } +#endif + +#if ATCAC_SHA384_EN +struct atcac_sha2_384_ctx * atcac_sha384_ctx_new(void) +{ + return (struct atcac_sha2_384_ctx*)hal_malloc(sizeof(atcac_sha2_384_ctx_t)); +} +#endif + +#if ATCAC_SHA512_EN +struct atcac_sha2_512_ctx * atcac_sha512_ctx_new(void) +{ + return (struct atcac_sha2_512_ctx*)hal_malloc(sizeof(atcac_sha2_512_ctx_t)); +} +#endif struct atcac_hmac_ctx * atcac_hmac_ctx_new(void) { @@ -1140,10 +1302,26 @@ void atcac_sha1_ctx_free(struct atcac_sha1_ctx * ctx) hal_free(ctx); } +#if ATCAC_SHA256_EN void atcac_sha256_ctx_free(struct atcac_sha2_256_ctx * ctx) { hal_free(ctx); } +#endif + +#if ATCAC_SHA384_EN +void atcac_sha384_ctx_free(struct atcac_sha2_384_ctx * ctx) +{ + hal_free(ctx); +} +#endif + +#if ATCAC_SHA512_EN +void atcac_sha512_ctx_free(struct atcac_sha2_512_ctx * ctx) +{ + hal_free(ctx); +} +#endif void atcac_hmac_ctx_free(struct atcac_hmac_ctx * ctx) { diff --git a/lib/wolfssl/atca_wolfssl_interface.h b/lib/wolfssl/atca_wolfssl_interface.h index ce520abf0..8476aea02 100644 --- a/lib/wolfssl/atca_wolfssl_interface.h +++ b/lib/wolfssl/atca_wolfssl_interface.h @@ -54,10 +54,36 @@ #if defined(WOLF_CRYPT_SETTINGS_H) && defined(NO_SHA256) #define ATCAC_SHA256_EN (DEFAULT_DISABLED) #else -#define ATCAC_SHA256_EN (DEFAULT_ENABLED) +#define ATCAC_SHA256_EN (FEATURE_ENABLED) #endif #endif /* ATCAC_SHA256_EN */ +/** \def ATCAC_SHA384_EN + * Indicates if this module is a provider of a SHA384 implementation + * + * Disabled by default. Use FEATURE_ENABLED to use SHA384 + */ +#ifndef ATCAC_SHA384_EN +#if defined(WOLF_CRYPT_SETTINGS_H) && defined(NO_SHA512) +#define ATCAC_SHA384_EN (DEFAULT_DISABLED) +#else +#define ATCAC_SHA384_EN (FEATURE_DISABLED) +#endif +#endif /* ATCAC_SHA384_EN */ + +/** \def ATCAC_SHA512_EN + * Indicates if this module is a provider of a SHA512 implementation + * + * Disabled by default. Use FEATURE_ENABLED to use SHA512 + */ +#ifndef ATCAC_SHA512_EN +#if defined(WOLF_CRYPT_SETTINGS_H) && defined(NO_SHA512) +#define ATCAC_SHA512_EN (DEFAULT_DISABLED) +#else +#define ATCAC_SHA512_EN (FEATURE_DISABLED) +#endif +#endif /* ATCAC_SHA512_EN */ + /** \def ATCAC_AES_CMAC_EN * Indicates if this module is a provider of an AES-CMAC implementation */ diff --git a/lib/wolfssl/atca_wolfssl_internal.h b/lib/wolfssl/atca_wolfssl_internal.h index cc3f35e73..4929e2dfb 100644 --- a/lib/wolfssl/atca_wolfssl_internal.h +++ b/lib/wolfssl/atca_wolfssl_internal.h @@ -80,6 +80,16 @@ typedef struct atcac_sha2_256_ctx wc_Sha256 sha; } atcac_sha2_256_ctx_t; +typedef struct atcac_sha2_384_ctx +{ + wc_Sha384 sha; +} atcac_sha2_384_ctx_t; + +typedef struct atcac_sha2_512_ctx +{ + wc_Sha512 sha; +} atcac_sha2_512_ctx_t; + typedef struct atcac_aes_cmac_ctx { Cmac cmac; diff --git a/package.yml b/package.yml index 830ac3290..82c697dec 100644 --- a/package.yml +++ b/package.yml @@ -4,7 +4,7 @@ package: type: "application" status: "production" required: true - version: "v3.7.5" + version: "v3.7.6" dependencies: - name: "csp" diff --git a/release_notes.md b/release_notes.md index b9bbafd06..3025324a4 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,6 +1,23 @@ # Microchip Cryptoauthlib Release Notes +## Release v3.7.6 (09/26/2026) + +### New Features + - In PKCS11 module, added support for RSA key types, certificates and algorithms + - Added SHA384 and SHA512 support for host side software crypto (lib/crypto/) operations + - Modified WPC application to support ECC204 and TA010 devices + - See [talib/CHANGES.md] for details on talib module changes + +### Fixes + - Shared library build (libcryptoauth.so) sets ABI version number (libcryptoauth.so.x) + - Fixed atcacert_read_cert() API failure when certificate elements read from config zone + for ECC204 and TA010 devices + - Resolved kit protocol compilation failure for PIC18 device (XC8) builds + - PKCS11 layer fixes/updates + - Fixed C_DestroyObject failure when deleting a key pair + - Fixed C_DeriveKey API usage sequence + ## Release v3.7.5 (06/26/2024) ### New Features diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 7fc75d495..93837191f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -124,4 +124,4 @@ add_custom_command(TARGET cryptoauth_test POST_BUILD add_custom_command(TARGET cryptoauth_test POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/vectors/aesmmt_cbc_cavp_vectors - $/aesmmt_cbc_cavp_vectors ) \ No newline at end of file + $/aesmmt_cbc_cavp_vectors ) diff --git a/test/api_atcab/atca_tests_startup.c b/test/api_atcab/atca_tests_startup.c index 40f9785a8..341f99f1f 100644 --- a/test/api_atcab/atca_tests_startup.c +++ b/test/api_atcab/atca_tests_startup.c @@ -66,14 +66,12 @@ TEST(atca_cmd_basic_test, doubleinit) status = atcab_info(rev); TEST_ASSERT_SUCCESS(status); } - // *INDENT-OFF* - Preserve formatting t_test_case_info startup_basic_test_info[] = { { REGISTER_TEST_CASE(atca_cmd_basic_test, version), NULL }, { REGISTER_TEST_CASE(atca_cmd_basic_test, init), NULL }, { REGISTER_TEST_CASE(atca_cmd_basic_test, doubleinit), NULL }, - /* Array Termination element*/ { (fp_test_case)NULL, NULL }, }; diff --git a/test/api_atcab/atca_tests_write.c b/test/api_atcab/atca_tests_write.c index 07c16d403..86685b9be 100644 --- a/test/api_atcab/atca_tests_write.c +++ b/test/api_atcab/atca_tests_write.c @@ -95,7 +95,7 @@ TEST(atca_cmd_basic_test, write_upper_slots) uint8_t read_data[32]; uint8_t config88[4]; uint16_t slot_locked; - char msg[8]; + char msg[16]= {0}; bool is_data_locked = false; ATCA_STATUS status = ATCA_SUCCESS; @@ -771,6 +771,43 @@ TEST(atca_cmd_basic_test, write_pubkey) } #endif +TEST(atca_cmd_basic_test, write_full_cert_608_slot8) +{ + ATCA_STATUS status = ATCA_SUCCESS; + + TEST_ASSERT_NOT_EQUAL(NULL, g_atcab_device_ptr); + + test_assert_config_is_locked(); + test_assert_data_is_unlocked(); + + if(true == atca_test_cond_ecc608()) + { + //x.509 certificate for ecc608 + const uint8_t ecc256_ca_cert_ecc608[408] = { + 0x30, 0x82, 0x01, 0x91, 0x30, 0x82, 0x01, 0x38, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x51, 0xd7, 0x42, 0x1c, 0xdd, 0xd2, 0xed, 0xed, 0xd0, 0x3d, 0x59, + 0xa4, 0x15, 0xec, 0xf0, 0xd1, 0xcc, 0xaa, 0xce, 0xcb, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x1e, 0x31, 0x1c, 0x30, + 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x44, 0x65, 0x6d, 0x6f, 0x20, 0x45, 0x63, 0x6f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x52, 0x6f, 0x6f, + 0x74, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x31, 0x32, 0x33, 0x30, 0x31, 0x35, 0x33, 0x33, 0x33, 0x32, 0x5a, 0x17, 0x0d, 0x33, 0x31, 0x31, 0x32, 0x32, 0x38, + 0x31, 0x35, 0x33, 0x33, 0x33, 0x32, 0x5a, 0x30, 0x20, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x63, + 0x68, 0x69, 0x70, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x63, 0x65, 0x72, 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, 0x6b, 0xd8, 0xec, 0x15, 0x0f, 0xd5, 0xb6, 0x44, 0xe4, 0xc1, + 0xb4, 0x41, 0x23, 0xa0, 0xe3, 0x9e, 0x6e, 0xfd, 0x88, 0x83, 0x07, 0xae, 0xcc, 0x0b, 0x81, 0x54, 0x51, 0x2c, 0x5e, 0x7f, 0x71, 0xfb, 0x8e, 0xe5, 0x7b, 0x15, + 0x61, 0xb1, 0xb5, 0x8e, 0x93, 0x65, 0x7a, 0x02, 0x68, 0xa4, 0x1f, 0x00, 0xe5, 0x0b, 0x02, 0x5d, 0x12, 0xd1, 0x39, 0x4c, 0x84, 0xac, 0x94, 0xc7, 0x51, 0x51, + 0xd3, 0x1f, 0xa3, 0x52, 0x30, 0x50, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x1d, 0x06, 0x03, + 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x52, 0xcb, 0xbf, 0x0d, 0xa6, 0xa5, 0xe2, 0x72, 0x67, 0x61, 0x39, 0x87, 0xe5, 0x24, 0xae, 0xc3, 0x7d, 0x74, 0xe2, + 0x3f, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x99, 0x9c, 0xa4, 0x4c, 0xc7, 0x23, 0x40, 0xd9, 0xa9, 0xc6, 0x85, 0xaf, + 0x76, 0x76, 0x04, 0x34, 0x13, 0x81, 0x72, 0xb8, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, + 0x20, 0x28, 0x62, 0x0a, 0xb2, 0x4d, 0x1a, 0x60, 0xe1, 0x89, 0xd1, 0x9b, 0xba, 0x8a, 0x46, 0x7f, 0x9d, 0x34, 0x90, 0xda, 0x74, 0x0a, 0x3a, 0xc6, 0x1f, 0x7d, + 0x03, 0xbd, 0xa7, 0x56, 0xe0, 0xe8, 0x4f, 0x02, 0x20, 0x13, 0x62, 0xe2, 0x60, 0x77, 0x94, 0x73, 0xb3, 0xff, 0xa1, 0x82, 0x07, 0x6a, 0x72, 0xf7, 0xeb, 0xe2, + 0x98, 0xd5, 0xf1, 0x1f, 0x47, 0xd1, 0x8b, 0x59, 0x21, 0x8f, 0x2e, 0x97, 0x58, 0x74, 0x09, 0x00, 0x00, 0x00 //Padded 3 bytes as zero for ecc device for len = 4 byte multiple + }; + + status = atcab_write_bytes_zone(ATCA_ZONE_DATA, 8, 0, ecc256_ca_cert_ecc608, sizeof(ecc256_ca_cert_ecc608)); + } + + TEST_ASSERT_SUCCESS(status); +} + #endif /* TEST_ATCAB_WRITE_EN */ // *INDENT-OFF* - Preserve formatting @@ -802,6 +839,7 @@ t_test_case_info write_basic_test_info[] = { REGISTER_TEST_CASE(atca_cmd_basic_test, write_config_zone), REGISTER_TEST_CONDITION(atca_cmd_basic_test, write_config_zone) }, #if CALIB_WRITE_EN { REGISTER_TEST_CASE(atca_cmd_basic_test, write_pubkey), REGISTER_TEST_CONDITION(atca_cmd_basic_test, write_pubkey) }, + //{ REGISTER_TEST_CASE(atca_cmd_basic_test, write_full_cert_608_slot8), NULL }, #endif #endif diff --git a/test/api_crypto/test_crypto_sha.c b/test/api_crypto/test_crypto_sha.c index cb72b9d18..43cd520ea 100644 --- a/test/api_crypto/test_crypto_sha.c +++ b/test/api_crypto/test_crypto_sha.c @@ -37,6 +37,14 @@ #define TEST_ATCAC_SHA256_EN ATCAC_SHA256_EN #endif +#ifndef TEST_ATCAC_SHA384_EN +#define TEST_ATCAC_SHA384_EN ATCAC_SHA384_EN +#endif + +#ifndef TEST_ATCAC_SHA512_EN +#define TEST_ATCAC_SHA512_EN ATCAC_SHA512_EN +#endif + #include "crypto/atca_crypto_sw_sha1.h" #include "crypto/atca_crypto_sw_sha2.h" @@ -538,6 +546,345 @@ TEST(atcac_sha, sha256_hmac_nist) } #endif /* TEST_ATCAC_SHA256_EN */ +#if TEST_ATCAC_SHA384_EN +TEST(atcac_sha, sha384_nist1) +{ + const uint8_t digest_ref[] = { + 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 + }; + uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE]; + int ret; + + TEST_ASSERT_EQUAL(ATCA_SHA2_384_DIGEST_SIZE, sizeof(digest_ref)); + + ret = atcac_sw_sha2_384(nist_hash_msg1, sizeof(nist_hash_msg1) - 1, digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); +} + +TEST(atcac_sha, sha384_nist2) +{ + const uint8_t digest_ref[] = { + 0x33, 0x91, 0xfd, 0xdd, 0xfc, 0x8d, 0xc7, 0x39, 0x37, 0x07, 0xa6, 0x5b, 0x1b, 0x47, 0x09, 0x39, + 0x7c, 0xf8, 0xb1, 0xd1, 0x62, 0xaf, 0x05, 0xab, 0xfe, 0x8f, 0x45, 0x0d, 0xe5, 0xf3, 0x6b, 0xc6, + 0xb0, 0x45, 0x5a, 0x85, 0x20, 0xbc, 0x4e, 0x6f, 0x5f, 0xe9, 0x5b, 0x1f, 0xe3, 0xc8, 0x45, 0x2b + }; + uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE]; + int ret; + + TEST_ASSERT_EQUAL(ATCA_SHA2_384_DIGEST_SIZE, sizeof(digest_ref)); + + ret = atcac_sw_sha2_384(nist_hash_msg2, sizeof(nist_hash_msg2) - 1, digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); +} + +TEST(atcac_sha, sha384_nist3) +{ + const uint8_t digest_ref[] = { + 0x54, 0xa5, 0x9b, 0x9f, 0x22, 0xb0, 0xb8, 0x08, 0x80, 0xd8, 0x42, 0x7e, 0x54, 0x8b, 0x7c, 0x23, + 0xab, 0xd8, 0x73, 0x48, 0x6e, 0x1f, 0x03, 0x5d, 0xce, 0x9c, 0xd6, 0x97, 0xe8, 0x51, 0x75, 0x03, + 0x3c, 0xaa, 0x88, 0xe6, 0xd5, 0x7b, 0xc3, 0x5e, 0xfa, 0xe0, 0xb5, 0xaf, 0xd3, 0x14, 0x5f, 0x31 + }; + uint8_t digest[ATCA_SHA2_384_DIGEST_SIZE]; + int ret; + struct atcac_sha2_384_ctx* ctx; + +#if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) + ctx = atcac_sha384_ctx_new(); + TEST_ASSERT_NOT_NULL(ctx); +#else + atcac_sha2_384_ctx_t sha384_ctx; + ctx = &sha384_ctx; +#endif + + TEST_ASSERT_EQUAL(ATCA_SHA2_384_DIGEST_SIZE, sizeof(digest_ref)); + + ret = atcac_sw_sha2_384_init(ctx); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + ret = atcac_sw_sha2_384_update(ctx, nist_hash_msg3, 1); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + ret = atcac_sw_sha2_384_finish(ctx, digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); + +#if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) + atcac_sha384_ctx_free(ctx); +#endif +} + +static void test_atcac_sw_sha2_384_nist_simple(const char* filename) +{ +#if !defined(_WIN32) && !defined(__linux__) + ((void)filename); + TEST_IGNORE_MESSAGE("Test is not available for this platform."); +#else + FILE* rsp_file = NULL; + int ret = ATCA_SUCCESS; + uint8_t md_ref[ATCA_SHA2_384_DIGEST_SIZE]; + uint8_t md[sizeof(md_ref)]; + int len_bits = 0; + uint8_t* msg = NULL; + size_t count = 0; + + rsp_file = fopen(filename, "r"); + TEST_ASSERT_NOT_NULL_MESSAGE(rsp_file, "Failed to open file"); + + do + { + ret = read_rsp_int_value(rsp_file, "Len = ", NULL, &len_bits); + if (ret != ATCA_SUCCESS) + { + continue; + } + + msg = hal_malloc(len_bits == 0 ? 1 : len_bits / 8); + TEST_ASSERT_NOT_NULL_MESSAGE(msg, "malloc failed"); + + ret = read_rsp_hex_value(rsp_file, "Msg = ", msg, len_bits == 0 ? 1 : len_bits / 8); + TEST_ASSERT_EQUAL(ret, ATCA_SUCCESS); + + ret = read_rsp_hex_value(rsp_file, "MD = ", md_ref, sizeof(md_ref)); + TEST_ASSERT_EQUAL(ret, ATCA_SUCCESS); + + ret = atcac_sw_sha2_384(msg, len_bits / 8, md); + TEST_ASSERT_EQUAL(ret, ATCA_SUCCESS); + TEST_ASSERT_EQUAL_MEMORY(md_ref, md, sizeof(md_ref)); + + hal_free(msg); + msg = NULL; + count++; + } while (ret == ATCA_SUCCESS); + TEST_ASSERT_MESSAGE(count > 0, "No long tests found in file."); +#endif +} + +TEST(atcac_sha, sha384_nist_short) +{ + test_atcac_sw_sha2_384_nist_simple("sha-byte-test-vectors/SHA384ShortMsg.rsp"); +} + +TEST(atcac_sha, sha384_nist_long) +{ + test_atcac_sw_sha2_384_nist_simple("sha-byte-test-vectors/SHA384LongMsg.rsp"); +} + +TEST(atcac_sha, sha384_nist_monte) +{ +#if !defined(_WIN32) && !defined(__linux__) + TEST_IGNORE_MESSAGE("Test is not available for this platform."); +#else + FILE* rsp_file = NULL; + int ret = ATCA_SUCCESS; + uint8_t seed[ATCA_SHA2_384_DIGEST_SIZE]; + uint8_t md[4][sizeof(seed)]; + int i, j; + uint8_t m[sizeof(seed) * 3]; + uint8_t md_ref[sizeof(seed)]; + + rsp_file = fopen("sha-byte-test-vectors/SHA384Monte.rsp", "r"); + TEST_ASSERT_NOT_EQUAL_MESSAGE(NULL, rsp_file, "Failed to open sha-byte-test-vectors/SHA384Monte.rsp"); + + // Find the seed value + ret = read_rsp_hex_value(rsp_file, "Seed = ", seed, sizeof(seed)); + TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, ret, "Failed to find Seed value in file."); + + for (j = 0; j < 100; j++) + { + memcpy(&md[0], seed, sizeof(seed)); + memcpy(&md[1], seed, sizeof(seed)); + memcpy(&md[2], seed, sizeof(seed)); + for (i = 0; i < 1000; i++) + { + memcpy(m, md, sizeof(m)); + ret = atcac_sw_sha2_384(m, sizeof(m), &md[3][0]); + TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, ret, "atcac_sw_sha2_384 failed"); + memmove(&md[0], &md[1], sizeof(seed) * 3); + } + ret = read_rsp_hex_value(rsp_file, "MD = ", md_ref, sizeof(md_ref)); + TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, ret, "Failed to find MD value in file."); + TEST_ASSERT_EQUAL_MEMORY(md_ref, &md[2], sizeof(md_ref)); + memcpy(seed, &md[2], sizeof(seed)); + } +#endif +} +#endif /* TEST_ATCAC_SHA384_EN */ + +#if TEST_ATCAC_SHA512_EN +TEST(atcac_sha, sha512_nist1) +{ + const uint8_t digest_ref[] = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f + }; + uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE]; + int ret; + + TEST_ASSERT_EQUAL(ATCA_SHA2_512_DIGEST_SIZE, sizeof(digest_ref)); + + ret = atcac_sw_sha2_512(nist_hash_msg1, sizeof(nist_hash_msg1) - 1, digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); +} + +TEST(atcac_sha, sha512_nist2) +{ + const uint8_t digest_ref[] = { + 0x20, 0x4a, 0x8f, 0xc6, 0xdd, 0xa8, 0x2f, 0x0a, 0x0c, 0xed, 0x7b, 0xeb, 0x8e, 0x08, 0xa4, 0x16, + 0x57, 0xc1, 0x6e, 0xf4, 0x68, 0xb2, 0x28, 0xa8, 0x27, 0x9b, 0xe3, 0x31, 0xa7, 0x03, 0xc3, 0x35, + 0x96, 0xfd, 0x15, 0xc1, 0x3b, 0x1b, 0x07, 0xf9, 0xaa, 0x1d, 0x3b, 0xea, 0x57, 0x78, 0x9c, 0xa0, + 0x31, 0xad, 0x85, 0xc7, 0xa7, 0x1d, 0xd7, 0x03, 0x54, 0xec, 0x63, 0x12, 0x38, 0xca, 0x34, 0x45 + }; + uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE]; + int ret; + + TEST_ASSERT_EQUAL(ATCA_SHA2_512_DIGEST_SIZE, sizeof(digest_ref)); + + ret = atcac_sw_sha2_512(nist_hash_msg2, sizeof(nist_hash_msg2) - 1, digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); +} + +TEST(atcac_sha, sha512_nist3) +{ + const uint8_t digest_ref[] = { + 0x1f, 0x40, 0xfc, 0x92, 0xda, 0x24, 0x16, 0x94, 0x75, 0x09, 0x79, 0xee, 0x6c, 0xf5, 0x82, 0xf2, + 0xd5, 0xd7, 0xd2, 0x8e, 0x18, 0x33, 0x5d, 0xe0, 0x5a, 0xbc, 0x54, 0xd0, 0x56, 0x0e, 0x0f, 0x53, + 0x02, 0x86, 0x0c, 0x65, 0x2b, 0xf0, 0x8d, 0x56, 0x02, 0x52, 0xaa, 0x5e, 0x74, 0x21, 0x05, 0x46, + 0xf3, 0x69, 0xfb, 0xbb, 0xce, 0x8c, 0x12, 0xcf, 0xc7, 0x95, 0x7b, 0x26, 0x52, 0xfe, 0x9a, 0x75 + }; + uint8_t digest[ATCA_SHA2_512_DIGEST_SIZE]; + int ret; + struct atcac_sha2_512_ctx* ctx; + +#if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) + ctx = atcac_sha512_ctx_new(); + TEST_ASSERT_NOT_NULL(ctx); +#else + atcac_sha2_512_ctx_t sha512_ctx; + ctx = &sha512_ctx; +#endif + + TEST_ASSERT_EQUAL(ATCA_SHA2_512_DIGEST_SIZE, sizeof(digest_ref)); + + ret = atcac_sw_sha2_512_init(ctx); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + ret = atcac_sw_sha2_512_update(ctx, nist_hash_msg3, 1); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + ret = atcac_sw_sha2_512_finish(ctx, digest); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + TEST_ASSERT_EQUAL_MEMORY(digest_ref, digest, sizeof(digest_ref)); + +#if defined(ATCA_BUILD_SHARED_LIBS) || defined(ATCA_HEAP) + atcac_sha512_ctx_free(ctx); +#endif +} + +static void test_atcac_sw_sha2_512_nist_simple(const char* filename) +{ +#if !defined(_WIN32) && !defined(__linux__) + ((void)filename); + TEST_IGNORE_MESSAGE("Test is not available for this platform."); +#else + FILE* rsp_file = NULL; + int ret = ATCA_SUCCESS; + uint8_t md_ref[ATCA_SHA2_512_DIGEST_SIZE]; + uint8_t md[sizeof(md_ref)]; + int len_bits = 0; + uint8_t* msg = NULL; + size_t count = 0; + + rsp_file = fopen(filename, "r"); + TEST_ASSERT_NOT_NULL_MESSAGE(rsp_file, "Failed to open file"); + + do + { + ret = read_rsp_int_value(rsp_file, "Len = ", NULL, &len_bits); + if (ret != ATCA_SUCCESS) + { + continue; + } + + msg = hal_malloc(len_bits == 0 ? 1 : len_bits / 8); + TEST_ASSERT_NOT_NULL_MESSAGE(msg, "malloc failed"); + + ret = read_rsp_hex_value(rsp_file, "Msg = ", msg, len_bits == 0 ? 1 : len_bits / 8); + TEST_ASSERT_EQUAL(ret, ATCA_SUCCESS); + + ret = read_rsp_hex_value(rsp_file, "MD = ", md_ref, sizeof(md_ref)); + TEST_ASSERT_EQUAL(ret, ATCA_SUCCESS); + + ret = atcac_sw_sha2_512(msg, len_bits / 8, md); + TEST_ASSERT_EQUAL(ret, ATCA_SUCCESS); + TEST_ASSERT_EQUAL_MEMORY(md_ref, md, sizeof(md_ref)); + + hal_free(msg); + msg = NULL; + count++; + } while (ret == ATCA_SUCCESS); + TEST_ASSERT_MESSAGE(count > 0, "No long tests found in file."); +#endif +} + +TEST(atcac_sha, sha512_nist_short) +{ + test_atcac_sw_sha2_512_nist_simple("sha-byte-test-vectors/SHA512ShortMsg.rsp"); +} + +TEST(atcac_sha, sha512_nist_long) +{ + test_atcac_sw_sha2_512_nist_simple("sha-byte-test-vectors/SHA512LongMsg.rsp"); +} + +TEST(atcac_sha, sha512_nist_monte) +{ +#if !defined(_WIN32) && !defined(__linux__) + TEST_IGNORE_MESSAGE("Test is not available for this platform."); +#else + FILE* rsp_file = NULL; + int ret = ATCA_SUCCESS; + uint8_t seed[ATCA_SHA2_512_DIGEST_SIZE]; + uint8_t md[4][sizeof(seed)]; + int i, j; + uint8_t m[sizeof(seed) * 3]; + uint8_t md_ref[sizeof(seed)]; + + rsp_file = fopen("sha-byte-test-vectors/SHA512Monte.rsp", "r"); + TEST_ASSERT_NOT_EQUAL_MESSAGE(NULL, rsp_file, "Failed to open sha-byte-test-vectors/SHA512Monte.rsp"); + + // Find the seed value + ret = read_rsp_hex_value(rsp_file, "Seed = ", seed, sizeof(seed)); + TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, ret, "Failed to find Seed value in file."); + + for (j = 0; j < 100; j++) + { + memcpy(&md[0], seed, sizeof(seed)); + memcpy(&md[1], seed, sizeof(seed)); + memcpy(&md[2], seed, sizeof(seed)); + for (i = 0; i < 1000; i++) + { + memcpy(m, md, sizeof(m)); + ret = atcac_sw_sha2_512(m, sizeof(m), &md[3][0]); + TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, ret, "atcac_sw_sha2_512 failed"); + memmove(&md[0], &md[1], sizeof(seed) * 3); + } + ret = read_rsp_hex_value(rsp_file, "MD = ", md_ref, sizeof(md_ref)); + TEST_ASSERT_EQUAL_MESSAGE(ATCA_SUCCESS, ret, "Failed to find MD value in file."); + TEST_ASSERT_EQUAL_MEMORY(md_ref, &md[2], sizeof(md_ref)); + memcpy(seed, &md[2], sizeof(seed)); + } +#endif +} +#endif /* TEST_ATCAC_SHA512_EN*/ + // *INDENT-OFF* - Preserve formatting t_test_case_info atcac_sha_test_info[] = { @@ -558,6 +905,22 @@ t_test_case_info atcac_sha_test_info[] = { REGISTER_TEST_CASE(atcac_sha, sha256_nist_monte), NULL }, { REGISTER_TEST_CASE(atcac_sha, sha256_hmac), NULL }, { REGISTER_TEST_CASE(atcac_sha, sha256_hmac_nist), NULL }, +#endif +#if TEST_ATCAC_SHA384_EN + { REGISTER_TEST_CASE(atcac_sha, sha384_nist1), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha384_nist2), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha384_nist3), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha384_nist_short), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha384_nist_long), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha384_nist_monte), NULL }, +#endif +#if TEST_ATCAC_SHA512_EN + { REGISTER_TEST_CASE(atcac_sha, sha512_nist1), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha512_nist2), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha512_nist3), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha512_nist_short), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha512_nist_long), NULL }, + { REGISTER_TEST_CASE(atcac_sha, sha512_nist_monte), NULL }, #endif { NULL, NULL }, /* Array Termination element*/ }; diff --git a/test/atca_test.c b/test/atca_test.c index b257138b9..ae1069a59 100644 --- a/test/atca_test.c +++ b/test/atca_test.c @@ -37,7 +37,7 @@ #if ATCA_CA_SUPPORT #include "api_calib/test_calib.h" #endif -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) #include "api_talib/test_talib.h" #endif @@ -121,8 +121,10 @@ t_test_case_info* otpzero_tests[] = t_test_case_info* helper_tests[] = { +#ifndef LIBRARY_USAGE_EN helper_basic_test_info, buffer_test_info, +#endif (t_test_case_info*)NULL, /* Array Termination element*/ }; @@ -367,7 +369,7 @@ void atca_test_assert_aes_enabled(UNITY_LINE_TYPE from_line) } } -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) //The Function checks the Secureboot mode byte in configuration zone , if it is not set, it skips the test void atca_test_assert_ta_sboot_enabled(UNITY_LINE_TYPE from_line, uint8_t mode) { @@ -454,6 +456,23 @@ void atca_test_assert_ta_sboot_digest_type_enabled(UNITY_LINE_TYPE from_line, ui } #endif +#if ATCA_TA_SUPPORT +//The Function checks whether the provided handle is created, if not skip the test +void atca_test_assert_ta_check_handle_validity(UNITY_LINE_TYPE from_line, uint16_t handle) +{ + ATCA_STATUS status; + uint8_t is_valid; + + status = talib_is_handle_valid(atcab_get_device(), handle, &is_valid); + UNITY_TEST_ASSERT_EQUAL_INT(ATCA_SUCCESS, status, from_line, NULL); + + if (!is_valid) + { + TEST_IGNORE_MESSAGE("Ignoring the test, Handle is not created"); + } +} +#endif + ATCA_STATUS atca_test_config_get_id(uint8_t test_type, uint16_t* handle) { ATCA_STATUS status = ATCA_BAD_PARAM; @@ -504,7 +523,7 @@ ATCA_STATUS atca_test_config_get_id(uint8_t test_type, uint16_t* handle) /* 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 */ -#if defined(ATCA_ECC_SUPPORT) || defined(ATCA_ECC204_SUPPORT) || defined(ATCA_TA010_SUPPORT) || ATCA_TA_SUPPORT +#if (defined(ATCA_ECC_SUPPORT) || defined(ATCA_ECC204_SUPPORT) || defined(ATCA_TA010_SUPPORT) || ATCA_TA_SUPPORT) && !defined(LIBRARY_USAGE_EN) ATCA_STATUS atca_test_genkey(uint16_t key_id, uint8_t *public_key) { int attempts = 2; diff --git a/test/atca_test.h b/test/atca_test.h index 259c93200..a510dbd45 100644 --- a/test/atca_test.h +++ b/test/atca_test.h @@ -92,7 +92,7 @@ typedef struct #include "host/atca_host.h" #endif -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) #include "api_talib/test_talib.h" #endif @@ -153,12 +153,15 @@ void atca_test_assert_data_is_unlocked(UNITY_LINE_TYPE from_line); void atca_test_assert_data_is_locked(UNITY_LINE_TYPE from_line); void atca_test_assert_random_buffer(UNITY_LINE_TYPE from_line, uint8_t * buf, size_t buflen); void atca_test_assert_aes_enabled(UNITY_LINE_TYPE from_line); -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) void atca_test_assert_ta_sboot_enabled(UNITY_LINE_TYPE from_line, uint8_t mode); void atca_test_assert_ta_sboot_preboot_enabled(UNITY_LINE_TYPE from_line); void atca_test_assert_ta_sboot_preboot_digest_type_enabled(UNITY_LINE_TYPE from_line, uint8_t mode); void atca_test_assert_ta_sboot_digest_type_enabled(UNITY_LINE_TYPE from_line, uint8_t mode); #endif +#if ATCA_TA_SUPPORT +void atca_test_assert_ta_check_handle_validity(UNITY_LINE_TYPE from_line, uint16_t handle); +#endif #define unit_test_assert_config_is_locked() atca_test_assert_config_is_locked(__LINE__) #define unit_test_assert_config_is_unlocked() atca_test_assert_config_is_unlocked(__LINE__) @@ -176,7 +179,7 @@ void atca_test_assert_ta_sboot_digest_type_enabled(UNITY_LINE_TYPE from_line, ui #define check_config_ta_sboot_preboot_enable() atca_test_assert_ta_sboot_preboot_enabled(__LINE__) #define check_config_ta_sboot_preboot_digest_type_enable(mode) atca_test_assert_ta_sboot_preboot_digest_type_enabled(__LINE__, mode) #define check_config_ta_sboot_digest_type_enable(mode) atca_test_assert_ta_sboot_digest_type_enabled(__LINE__, mode) - +#define check_tatflex_handle_validity(handle) atca_test_assert_ta_check_handle_validity(__LINE__, handle) #define TEST_TYPE_ECC_SIGN (1) #define TEST_TYPE_ECC_VERIFY (2) @@ -197,6 +200,11 @@ void atca_test_assert_ta_sboot_digest_type_enabled(UNITY_LINE_TYPE from_line, ui #define TEST_TYPE_ECC_ROOT_KEY_P521 (17) #define TEST_TYPE_ECC_ROOT_KEY_ED25519 (18) #define TEST_TYPE_RSA3072_CERT (19) +#define TEST_TYPE_RSA2048_SIGN (20) +#define TEST_TYPE_AUTH_HANDLE (21) +#define TEST_TYPE_CERT_DATA (22) +#define TEST_TYPE_SUBJKEY_HANDLE (23) +#define TEST_TYPE_PVT_KEY_HANDLE (24) typedef struct { diff --git a/test/atca_test_console.c b/test/atca_test_console.c index d9a1a17ca..83adca3a1 100644 --- a/test/atca_test_console.c +++ b/test/atca_test_console.c @@ -27,9 +27,12 @@ #include "cryptoauthlib.h" #include "atca_test.h" -#include "api_atcab/test_atcab.h" #include "api_crypto/test_crypto.h" +#ifndef LIBRARY_USAGE_EN +#include "api_atcab/test_atcab.h" +#endif + #ifndef ATCA_SERIAL_NUM_SIZE #define ATCA_SERIAL_NUM_SIZE (9) #endif @@ -48,6 +51,7 @@ int run_helper_tests(int argc, char* argv[]) return run_test(argc, argv, RunAllHelperTests); } +#ifndef LIBRARY_USAGE_EN int read_config(int argc, char* argv[]) { ATCA_STATUS status; @@ -106,6 +110,7 @@ int read_config(int argc, char* argv[]) return 0; } +#endif int lock_status(int argc, char* argv[]) { @@ -132,6 +137,7 @@ int lock_status(int argc, char* argv[]) return (int)status; } +#ifndef LIBRARY_USAGE_EN int lock_config(int argc, char* argv[]) { int ret = lock_config_zone(argc, argv); @@ -153,6 +159,7 @@ int lock_data(int argc, char* argv[]) } return ret; } +#endif int do_randoms(int argc, char* argv[]) { @@ -291,6 +298,7 @@ ATCA_STATUS is_data_locked(bool* isLocked) return status; } +#ifndef LIBRARY_USAGE_EN int lock_config_zone(int argc, char* argv[]) { ATCA_STATUS status; @@ -428,6 +436,7 @@ ATCA_STATUS get_serial_no(uint8_t* sernum) return status; } +#endif int run_all_tests(int argc, char* argv[]) { @@ -577,8 +586,12 @@ int run_tng_tests(int argc, char* argv[]) ATCA_STATUS status; ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_interface) = ATCA_KIT_I2C_IFACE; - ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_identity) = 0x6C; - + // Set default address if dev_identity is not set + if (0 == ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_identity)) + { + ATCA_IFACECFG_VALUE(gCfg, atcahid.dev_identity) = 0x6C; + } + status = atcab_init(gCfg); if (status != ATCA_SUCCESS) { diff --git a/test/atcacert/test_atcacert_client.c b/test/atcacert/test_atcacert_client.c index d30e14ffe..bff2f2852 100644 --- a/test/atcacert/test_atcacert_client.c +++ b/test/atcacert/test_atcacert_client.c @@ -42,6 +42,8 @@ #include "test_cert_def_8_signer.h" #include "test_cert_def_9_device.h" #include "test_cert_def_10_device.h" +#include "test_cert_def_11_signer.h" +#include "test_cert_def_12_device.h" #ifdef ATCA_MBEDTLS #include "mbedtls/certs.h" @@ -710,8 +712,10 @@ TEST(atcacert_client, atcacert_get_subj) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); status = atcacert_get_subject(&g_test_cert_def_4_device, cert_buffer, cert_sz, &subject_data_buf); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } @@ -722,6 +726,7 @@ TEST(atcacert_client, atcacert_get_subj_pbkey) ATCA_STATUS status; uint8_t cert_buffer[800] = { 0x00 }; uint8_t public_key[64] = { 0x00 }; + cal_buffer pubkey = CAL_BUF_INIT(sizeof(public_key), public_key); // Skip test if data zone isn't locked test_assert_data_is_locked(); @@ -756,7 +761,7 @@ TEST(atcacert_client, atcacert_get_subj_pbkey) //Read cert to check the asn1 parse der api works fine status = atcacert_read_cert(&g_test_cert_def_5_device, public_key, cert_buffer, &cert_sz); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atcacert_get_subj_public_key(&g_test_cert_def_5_device, cert_buffer, cert_sz, public_key); + status = atcacert_get_subj_public_key(&g_test_cert_def_5_device, cert_buffer, cert_sz, &pubkey); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); #else status = ATCA_NO_DEVICES; @@ -783,10 +788,12 @@ TEST(atcacert_client, atcacert_get_subj_pbkey) //Read cert to check the asn1 parse der api works fine status = atcacert_read_cert(&g_test_cert_def_4_device, public_key, cert_buffer, &cert_sz); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - status = atcacert_get_subj_public_key(&g_test_cert_def_4_device, cert_buffer, cert_sz, public_key); + status = atcacert_get_subj_public_key(&g_test_cert_def_4_device, cert_buffer, cert_sz, &pubkey); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } TEST_ASSERT_EQUAL(0, memcmp(ref_pubkey, public_key, sizeof(ref_pubkey))); @@ -861,8 +868,10 @@ TEST(atcacert_client, atcacert_get_subj_pbkey_id) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); status = atcacert_get_subj_key_id(&g_test_cert_def_4_device, cert_buffer, cert_sz, key_id); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } TEST_ASSERT_EQUAL(0, memcmp(ref_key_id, key_id, key_id_sz)); @@ -970,8 +979,10 @@ TEST(atcacert_client, atcacert_get_issue_date_test) //221224182604Z (from asn1 editor) status = atcacert_get_issue_date(&g_test_cert_def_4_device, cert_buffer, cert_sz, &issue_date); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } TEST_ASSERT_EQUAL(0, memcmp(&issue_date_ref, &issue_date, sizeof(atcacert_tm_utc_t))); @@ -1074,8 +1085,10 @@ TEST(atcacert_client, atcacert_get_expiry_date) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); status = atcacert_get_expire_date(&g_test_cert_def_4_device, cert_buffer, cert_sz, &expiry_date); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } @@ -1154,8 +1167,10 @@ TEST(atcacert_client, atcacert_get_serial_num) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); status = atcacert_get_cert_sn(&g_test_cert_def_4_device, cert_buffer, cert_sz, cert_sn, &cert_sn_size); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } TEST_ASSERT_EQUAL(0, memcmp(ref_cert_sn, cert_sn, cert_sn_size)); @@ -1232,8 +1247,10 @@ TEST(atcacert_client, atcacert_get_auth_key_id_test) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); status = atcacert_get_auth_key_id(&g_test_cert_def_4_device, cert_buffer, cert_sz, auth_key_id); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } TEST_ASSERT_EQUAL(0, memcmp(ref_auth_key_id, auth_key_id, sizeof(ref_auth_key_id))); @@ -1305,8 +1322,10 @@ TEST(atcacert_client, atcacert_get_issuer_test) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); status = atcacert_get_issuer(&g_test_cert_def_4_device, cert_buffer, cert_sz, issuer_data); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)signer_cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif #endif } } @@ -1318,7 +1337,6 @@ TEST(atcacert_client, atcacert_get_issuer_test) TEST(atcacert_client, atcacert_write_rsa_signed_cert) { ATCA_STATUS status; - ta_element_attributes_t attr_crt_handle_attr; // Skip test if data zone isn't locked test_assert_data_is_locked(); @@ -1344,28 +1362,30 @@ TEST(atcacert_client, atcacert_write_rsa_signed_cert) cal_buffer cert_rddata_buf = CAL_BUF_INIT(cert_rd_sz, NULL); //Read cert get the length of the certificate stored; pass null output buffer status = talib_read_X509_cert(atcab_get_device(), cert_handle, &cert_rddata_buf); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL(cert_rddata_buf.len, g_test_cert_def_10_device.cert_template_size); //Read full certificate stored cert_rddata_buf.buf = cert_rd; status = talib_read_X509_cert(atcab_get_device(), cert_handle, &cert_rddata_buf); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); #else status = atcacert_write_cert(&g_test_cert_def_10_device, g_test_cert_rsa3072, g_test_cert_def_10_device.cert_template_size); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); //Read cert get the length of the certificate stored; pass null output buffer status = atcacert_read_cert(&g_test_cert_def_10_device, NULL, NULL, &cert_rd_sz); - TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL(cert_rd_sz, g_test_cert_def_10_device.cert_template_size); //Read cert to check the asn1 parse der api works fine status = atcacert_read_cert(&g_test_cert_def_10_device, NULL, cert_rd, &cert_rd_sz); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); - TEST_ASSERT_EQUAL(cert_rd_sz, g_test_cert_def_10_device.cert_template_size); + TEST_ASSERT_EQUAL(cert_rd_sz, g_test_cert_def_10_device.cert_template_size); #endif TEST_ASSERT_EQUAL_MEMORY(&g_test_cert_rsa3072, cert_rd, g_test_cert_def_10_device.cert_template_size); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)cert_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif } #endif @@ -1683,5 +1703,127 @@ TEST(atcacert_client_ca2, atcacert_get_response_bad_params) ret = atcacert_get_response(16, NULL, NULL); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); } + +//! #warning "For demonstration purposes, we're storing the Root private key and Signer private key inside a protected part of the device. +//! However, for production setup, these secure keys should not be kept in the device, +//! and the process to create a verification certificate should be performed off-chip." +TEST(atcacert_client_ca2, cert_element_init) +{ + int ret = 0; + static const uint8_t signer_ca_private_key_slot = 0; + static const uint8_t signer_private_key_slot = 0; + uint8_t signer_id[2] = { 0xC4, 0x8B }; + const atcacert_tm_utc_t signer_issue_date = { + .tm_year = 2014 - 1900, + .tm_mon = 8 - 1, + .tm_mday = 2, + .tm_hour = 20, + .tm_min = 0, + .tm_sec = 0 + }; + static const uint8_t device_private_key_slot = 0; + const atcacert_tm_utc_t device_issue_date = { + .tm_year = 2015 - 1900, + .tm_mon = 9 - 1, + .tm_mday = 3, + .tm_hour = 21, + .tm_min = 0, + .tm_sec = 0 + }; + uint8_t config[16]; + char disp_str[1500]; + size_t disp_size = sizeof(disp_str); + + ret = atcab_read_zone(ATCA_ZONE_CONFIG, 0, 0, 0, config, 16); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + //! Generate Device private key and 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); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + printf("Device Public Key:\r\n%s\r\n", disp_str); + + ret = atcab_write_bytes_zone(ATCA_ZONE_DATA, 1, 8, g_device_public_key, ATCA_ECCP256_PUBKEY_SIZE); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + //! Generate Signer private key and 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_write_bytes_zone(ATCA_ZONE_DATA, 1, 6, g_signer_public_key, ATCA_ECCP256_PUBKEY_SIZE); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + + g_device_cert_ref_size = sizeof(g_device_cert_ref); + build_and_save_cert( + &g_test_cert_def_12_device, + g_device_cert_ref, + &g_device_cert_ref_size, + g_signer_public_key, + g_device_public_key, + signer_id, + &device_issue_date, + config, + signer_private_key_slot); + disp_size = sizeof(disp_str); + ret = atcab_bin2hex(g_device_cert_ref, g_device_cert_ref_size, disp_str, &disp_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + printf("Device Certificate:\r\n%s\r\n", disp_str); + + //! Generate Signer CA Private key and 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); + + // Build signer cert + g_signer_cert_ref_size = sizeof(g_signer_cert_ref); + build_and_save_cert( + &g_test_cert_def_11_signer, + g_signer_cert_ref, + &g_signer_cert_ref_size, + g_signer_ca_public_key, + g_signer_public_key, + signer_id, + &signer_issue_date, + config, + signer_ca_private_key_slot); + disp_size = sizeof(disp_str); + ret = atcab_bin2hex(g_signer_cert_ref, g_signer_cert_ref_size, disp_str, &disp_size); + TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); + printf("Signer Certificate:\r\n%s\r\n", disp_str); + printf("\n"); +} + +TEST(atcacert_client_ca2, cert_element_atcacert_read_cert_signer) +{ + int ret = 0; + uint8_t cert[512]; + size_t cert_size = sizeof(cert); + + ret = atcacert_read_cert(&g_test_cert_def_11_signer, g_signer_ca_public_key, cert, &cert_size); + TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); + TEST_ASSERT_EQUAL(g_signer_cert_ref_size, cert_size); + TEST_ASSERT_EQUAL_MEMORY(g_signer_cert_ref, cert, cert_size); +} + +TEST(atcacert_client_ca2, cert_element_atcacert_read_cert_device) +{ + int ret = 0; + uint8_t cert[512]; + size_t cert_size = sizeof(cert); + + ret = atcacert_read_cert(&g_test_cert_def_12_device, g_signer_public_key, cert, &cert_size); + TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); + TEST_ASSERT_EQUAL(g_device_cert_ref_size, cert_size); + TEST_ASSERT_EQUAL_MEMORY(g_device_cert_ref, cert, cert_size); +} #endif #endif diff --git a/test/atcacert/test_atcacert_client_runner.c b/test/atcacert/test_atcacert_client_runner.c index 01b65c1d9..0c83f4b9e 100644 --- a/test/atcacert/test_atcacert_client_runner.c +++ b/test/atcacert/test_atcacert_client_runner.c @@ -84,6 +84,9 @@ TEST_GROUP_RUNNER(atcacert_client_ca2) RUN_TEST_CASE(atcacert_client_ca2, atcacert_read_cert_small_buf); RUN_TEST_CASE(atcacert_client_ca2, atcacert_read_cert_bad_params); RUN_TEST_CASE(atcacert_client_ca2, atcacert_get_response_bad_params); + RUN_TEST_CASE(atcacert_client_ca2, cert_element_init); + RUN_TEST_CASE(atcacert_client_ca2, cert_element_atcacert_read_cert_signer); + RUN_TEST_CASE(atcacert_client_ca2, cert_element_atcacert_read_cert_device); } #endif #endif diff --git a/test/atcacert/test_atcacert_def.c b/test/atcacert/test_atcacert_def.c index 8bfe647ad..60da19a35 100644 --- a/test/atcacert/test_atcacert_def.c +++ b/test/atcacert/test_atcacert_def.c @@ -466,8 +466,9 @@ TEST(atcacert_get_subj_public_key, good) 0x01, 0x51, 0xD1, 0x3A, 0x6F, 0x01, 0x23, 0xD6, 0x70, 0xB5, 0xE5, 0x0C, 0xE0, 0xFF, 0x49, 0x31 }; uint8_t public_key[64]; + cal_buffer pubkey = CAL_BUF_INIT(sizeof(public_key), public_key); - ret = atcacert_get_subj_public_key(&g_cert_def, g_cert_def_cert_template, g_cert_def.cert_template_size, public_key); + ret = atcacert_get_subj_public_key(&g_cert_def, g_cert_def_cert_template, g_cert_def.cert_template_size, &pubkey); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); TEST_ASSERT_EQUAL_MEMORY(public_key_ref, public_key, sizeof(public_key)); } @@ -476,14 +477,15 @@ TEST(atcacert_get_subj_public_key, bad_params) { int ret = 0; uint8_t public_key[64]; + cal_buffer pubkey = CAL_BUF_INIT(sizeof(public_key), public_key); - ret = atcacert_get_subj_public_key(NULL, g_cert_def_cert_template, g_cert_def.cert_template_size, public_key); + ret = atcacert_get_subj_public_key(NULL, g_cert_def_cert_template, g_cert_def.cert_template_size, &pubkey); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_get_subj_public_key(&g_cert_def, NULL, g_cert_def.cert_template_size, public_key); + ret = atcacert_get_subj_public_key(&g_cert_def, NULL, g_cert_def.cert_template_size, &pubkey); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); - ret = atcacert_get_subj_public_key(NULL, NULL, g_cert_def.cert_template_size, public_key); + ret = atcacert_get_subj_public_key(NULL, NULL, g_cert_def.cert_template_size, &pubkey); TEST_ASSERT_EQUAL(ATCACERT_E_BAD_PARAMS, ret); ret = atcacert_get_subj_public_key(&g_cert_def, g_cert_def_cert_template, g_cert_def.cert_template_size, NULL); diff --git a/test/atcacert/test_atcacert_host_hw.c b/test/atcacert/test_atcacert_host_hw.c index b47158d02..ea5fb079f 100644 --- a/test/atcacert/test_atcacert_host_hw.c +++ b/test/atcacert/test_atcacert_host_hw.c @@ -144,13 +144,14 @@ TEST(atcacert_host_hw, atcacert_verify_cert_hw) { int ret = 0; uint8_t signer_public_key[64]; + cal_buffer signer_pubkey = CAL_BUF_INIT(sizeof(signer_public_key), signer_public_key); // Validate signer cert against its certificate authority (CA) public key ret = atcacert_verify_cert_hw(&g_test_cert_def_1_signer, g_signer_cert, sizeof(g_signer_cert), g_test_signer_1_ca_public_key); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); // Get the signer's public key from its certificate - ret = atcacert_get_subj_public_key(&g_test_cert_def_1_signer, g_signer_cert, sizeof(g_signer_cert), signer_public_key); + ret = atcacert_get_subj_public_key(&g_test_cert_def_1_signer, g_signer_cert, sizeof(g_signer_cert), &signer_pubkey); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); // Validate the device cert against its certificate authority (CA) which is the signer diff --git a/test/atcacert/test_cert_def_11_signer.c b/test/atcacert/test_cert_def_11_signer.c new file mode 100644 index 000000000..94b317b61 --- /dev/null +++ b/test/atcacert/test_cert_def_11_signer.c @@ -0,0 +1,117 @@ +#include "atca_test.h" +#ifndef DO_NOT_TEST_CERT +#include "atcacert/atcacert_def.h" + +const uint8_t g_test_signer_11_ca_public_key[64] = { + 0x82, 0xf4, 0xd9, 0x0d, 0xc3, 0x93, 0x62, 0xf6, 0xaf, 0x82, 0x9e, 0x48, 0xc5, 0xf9, 0x23, 0x86, + 0xdd, 0xfc, 0x7b, 0xe5, 0xc3, 0x60, 0xd4, 0xe2, 0x55, 0x9a, 0xac, 0x7d, 0x92, 0xbe, 0xb3, 0x34, + 0x92, 0x50, 0x59, 0x9a, 0x4d, 0x84, 0xb1, 0xfc, 0x9c, 0xff, 0x90, 0x12, 0xc2, 0x3a, 0xf9, 0xa9, + 0xd6, 0xde, 0xb5, 0x41, 0xf6, 0x13, 0xe0, 0xab, 0x35, 0xe9, 0x31, 0xd6, 0x35, 0x3c, 0x9e, 0x6c, +}; + +const uint8_t g_test_cert_template_11_signer[439] = { + 0x30, 0x82, 0x01, 0xb3, 0x30, 0x82, 0x01, 0x59, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x5b, + 0xc6, 0x77, 0xc0, 0x42, 0xdf, 0x5f, 0x82, 0x30, 0x58, 0x27, 0x55, 0x7c, 0x7c, 0x84, 0x32, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x25, 0x31, 0x0f, 0x30, + 0x0d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x06, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x74, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6b, + 0x75, 0x6e, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x37, 0x30, 0x38, 0x30, 0x34, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x33, 0x39, 0x30, 0x37, 0x30, 0x38, 0x30, 0x34, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x30, 0x28, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, + 0x04, 0x74, 0x65, 0x73, 0x74, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, + 0x74, 0x65, 0x73, 0x74, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x46, 0x46, 0x46, 0x46, 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, 0x3e, 0x3d, 0xc0, 0xf6, 0xab, 0x8c, 0x0f, + 0xaa, 0xd8, 0x97, 0x79, 0x61, 0x52, 0xd6, 0x68, 0xfe, 0x30, 0x72, 0x0e, 0xf6, 0x65, 0x0f, 0x16, + 0xd6, 0x25, 0xa7, 0x93, 0x1a, 0x51, 0x4a, 0xa5, 0x42, 0x64, 0x13, 0x5c, 0x10, 0xe0, 0xf4, 0x3f, + 0xb5, 0x14, 0x01, 0xa0, 0xdf, 0x24, 0x72, 0xac, 0xe0, 0x02, 0xb0, 0x5b, 0x5a, 0xaa, 0x0a, 0x6b, + 0xf8, 0x2d, 0x0b, 0xca, 0x59, 0x30, 0xb2, 0xd7, 0x28, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x01, 0x86, 0x30, 0x12, 0x06, + 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x08, 0x30, 0x06, 0x01, 0x01, 0xff, 0x02, 0x01, + 0x00, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x5d, 0x9b, 0x2f, 0xc6, + 0xdd, 0xf1, 0x3f, 0x88, 0x4c, 0xd2, 0x7f, 0xea, 0x43, 0xc6, 0x0a, 0xed, 0xc6, 0x23, 0x07, 0x8b, + 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xf2, 0x35, 0x0f, + 0x0b, 0x5c, 0x6d, 0xbb, 0x55, 0xa9, 0x86, 0x6f, 0xdc, 0x8d, 0xf1, 0x8b, 0x9b, 0x82, 0xb9, 0x06, + 0x6e, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, + 0x30, 0x45, 0x02, 0x21, 0x00, 0xc2, 0x14, 0x73, 0x8e, 0xb8, 0x53, 0x32, 0x0f, 0x07, 0xd0, 0x58, + 0x8d, 0x18, 0x78, 0xea, 0x93, 0x07, 0x67, 0xd8, 0x1f, 0x5b, 0xe3, 0xd6, 0x4f, 0x08, 0xd4, 0x9d, + 0x5f, 0x74, 0x60, 0x52, 0x35, 0x02, 0x20, 0x3b, 0xd1, 0x76, 0x7d, 0xac, 0xb2, 0x47, 0x32, 0xa9, + 0x22, 0xd9, 0x33, 0x20, 0x29, 0xc0, 0x5f, 0xe4, 0xc7, 0xf9, 0x41, 0xb0, 0xe3, 0x77, 0xc1, 0x04, + 0xd1, 0xe6, 0x61, 0xbc, 0x52, 0x67, 0xc3, +}; + +const atcacert_def_t g_test_cert_def_11_signer = { + .type = CERTTYPE_X509, + .template_id = 1, + .chain_id = 0, + .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_UTC, + .expire_date_format = DATEFMT_RFC5280_GEN, + .tbs_cert_loc = { + .offset = 4, + .count = 349 + }, + .expire_years = 15, + .public_key_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 1, + .is_genkey = 0, + .offset = 192, + .count = 64 + }, + .comp_cert_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 1, + .is_genkey = 0, + .offset = 0, + .count = 72 + }, + .std_cert_elements = { + { // STDCERT_PUBLIC_KEY + .offset = 185, + .count = 64 + }, + { // STDCERT_SIGNATURE + .offset = 365, + .count = 74 + }, + { // STDCERT_ISSUE_DATE + .offset = 86, + .count = 13 + }, + { // STDCERT_EXPIRE_DATE + .offset = 101, + .count = 15 + }, + { // STDCERT_SIGNER_ID + .offset = 154, + .count = 4 + }, + { // STDCERT_CERT_SN + .offset = 15, + .count = 16 + }, + { // STDCERT_AUTH_KEY_ID + .offset = 333, + .count = 20 + }, + { // STDCERT_SUBJ_KEY_ID + .offset = 300, + .count = 20 + }, + }, + .cert_elements = NULL, + .cert_elements_count = 0, + .cert_template = g_test_cert_template_11_signer, + .cert_template_size = sizeof(g_test_cert_template_11_signer), + .ca_cert_def = NULL +}; +#endif \ No newline at end of file diff --git a/test/atcacert/test_cert_def_11_signer.h b/test/atcacert/test_cert_def_11_signer.h new file mode 100644 index 000000000..9933dd4be --- /dev/null +++ b/test/atcacert/test_cert_def_11_signer.h @@ -0,0 +1,9 @@ +#ifndef TEST_CERT_DEF_11_SIGNER_H +#define TEST_CERT_DEF_11_SIGNER_H + +#include "atcacert/atcacert_def.h" + +extern const uint8_t g_test_signer_11_ca_public_key[]; +extern const atcacert_def_t g_test_cert_def_11_signer; + +#endif diff --git a/test/atcacert/test_cert_def_12_device.c b/test/atcacert/test_cert_def_12_device.c new file mode 100644 index 000000000..1e6102ada --- /dev/null +++ b/test/atcacert/test_cert_def_12_device.c @@ -0,0 +1,132 @@ +#include "atca_test.h" +#ifndef DO_NOT_TEST_CERT +#include "atcacert/atcacert_def.h" +#include "test_cert_def_11_signer.h" + +const uint8_t g_test_cert_template_12_device[443] = { + 0x30, 0x82, 0x01, 0xb7, 0x30, 0x82, 0x01, 0x5c, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x52, + 0xac, 0x02, 0x60, 0x69, 0x65, 0xa9, 0xc8, 0xc6, 0xa1, 0x95, 0xd2, 0x11, 0xc7, 0xff, 0xed, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x28, 0x31, 0x0d, 0x30, + 0x0b, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x04, 0x74, 0x65, 0x73, 0x74, 0x31, 0x17, 0x30, 0x15, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x46, 0x46, 0x46, 0x46, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x34, 0x30, 0x37, 0x30, 0x38, 0x30, + 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x33, 0x34, 0x30, 0x37, 0x30, 0x38, + 0x30, 0x34, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x2e, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x04, 0x0a, 0x0c, 0x04, 0x74, 0x65, 0x73, 0x74, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x03, 0x55, 0x04, + 0x03, 0x0c, 0x14, 0x73, 0x6e, 0x30, 0x31, 0x32, 0x33, 0x30, 0x33, 0x30, 0x34, 0x30, 0x35, 0x30, + 0x36, 0x30, 0x37, 0x30, 0x38, 0x45, 0x45, 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, 0x71, 0xf1, 0xa7, 0x0d, 0xa3, 0x79, 0xa3, 0xfd, 0xed, 0x6b, 0x50, 0x10, 0xbd, 0xad, + 0x6e, 0x1f, 0xb9, 0xe8, 0xeb, 0xa7, 0xdf, 0x2c, 0x4b, 0x5c, 0x67, 0xd3, 0x5e, 0xba, 0x84, 0xda, + 0x09, 0xe7, 0x7a, 0xe8, 0xdb, 0x2c, 0xcb, 0x96, 0x28, 0xee, 0xeb, 0x85, 0xcd, 0xaa, 0xb3, 0x5c, + 0x92, 0xe5, 0x3e, 0x1c, 0x44, 0xd5, 0x5a, 0x2b, 0xa7, 0xa0, 0x24, 0xaa, 0x92, 0x60, 0x3b, 0x68, + 0x94, 0x8a, 0xa3, 0x60, 0x30, 0x5e, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, + 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, + 0x03, 0x02, 0x03, 0x88, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x1a, + 0x90, 0xb2, 0x22, 0x37, 0xa4, 0x51, 0xb7, 0x57, 0xdd, 0x36, 0xd1, 0x3a, 0x85, 0x2b, 0xe1, 0x3d, + 0x2e, 0xf2, 0xca, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, + 0xd0, 0x2e, 0x45, 0x9a, 0x0d, 0x3c, 0xeb, 0x03, 0x15, 0x78, 0xc2, 0x1e, 0x57, 0x75, 0x5e, 0x3d, + 0xc5, 0x9a, 0x4c, 0xda, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + 0x03, 0x49, 0x00, 0x30, 0x46, 0x02, 0x21, 0x00, 0xff, 0xac, 0x3a, 0xde, 0xe0, 0x52, 0xcb, 0xc6, + 0x98, 0x18, 0x4c, 0x16, 0xf3, 0x52, 0xdd, 0x6e, 0x1a, 0x2b, 0x2e, 0xe4, 0xbc, 0x6d, 0x83, 0xbe, + 0x63, 0x6c, 0xe4, 0x6c, 0x15, 0x66, 0xdd, 0x11, 0x02, 0x21, 0x00, 0x9b, 0x78, 0x68, 0x3f, 0x0c, + 0x20, 0x53, 0x2d, 0x99, 0xff, 0x6c, 0xcc, 0x1d, 0xa4, 0xe0, 0xac, 0x4c, 0x80, 0xde, 0xa8, 0x60, + 0xfc, 0x8a, 0xa1, 0x6a, 0x4c, 0xe0, 0xc2, 0xe4, 0x0e, 0xc2, 0x32, +}; + +const atcacert_cert_element_t g_cert_elements_12_device[1] = { + { + .id = "SN08", + .device_loc = { + .zone = DEVZONE_CONFIG, + .slot = 0, + .is_genkey = 0, + .offset = 0, + .count = 9 + }, + .cert_loc = { + .offset = 149, + .count = 18 + }, + .transforms = { + TF_BIN2HEX_UC, + TF_NONE + } + } +}; + +const atcacert_def_t g_test_cert_def_12_device = { + .type = CERTTYPE_X509, + .template_id = 3, + .chain_id = 0, + .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_UTC, + .expire_date_format = DATEFMT_RFC5280_GEN, + .tbs_cert_loc = { + .offset = 4, + .count = 352 + }, + .expire_years = 10, + .public_key_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 1, + .is_genkey = 0, //1 + .offset = 256, + .count = 64 + }, + .comp_cert_dev_loc = { + .zone = DEVZONE_DATA, + .slot = 1, + .is_genkey = 0, + .offset = 96, + .count = 72 + }, + .std_cert_elements = { + { // STDCERT_PUBLIC_KEY + .offset = 194, + .count = 64 + }, + { // STDCERT_SIGNATURE + .offset = 368, + .count = 75 + }, + { // STDCERT_ISSUE_DATE + .offset = 89, + .count = 13 + }, + { // STDCERT_EXPIRE_DATE + .offset = 104, + .count = 15 + }, + { // STDCERT_SIGNER_ID + .offset = 81, + .count = 4 + }, + { // STDCERT_CERT_SN + .offset = 15, + .count = 16 + }, + { // STDCERT_AUTH_KEY_ID + .offset = 336, + .count = 20 + }, + { // STDCERT_SUBJ_KEY_ID + .offset = 303, + .count = 20 + }, + }, + .cert_elements = g_cert_elements_12_device, + .cert_elements_count = sizeof(g_cert_elements_12_device) / sizeof(g_cert_elements_12_device[0]), + .cert_template = g_test_cert_template_12_device, + .cert_template_size = sizeof(g_test_cert_template_12_device), + .ca_cert_def = &g_test_cert_def_11_signer +}; +#endif \ No newline at end of file diff --git a/test/atcacert/test_cert_def_12_device.h b/test/atcacert/test_cert_def_12_device.h new file mode 100644 index 000000000..cb407d285 --- /dev/null +++ b/test/atcacert/test_cert_def_12_device.h @@ -0,0 +1,9 @@ +#ifndef TEST_CERT_DEF_12_DEVICE_H +#define TEST_CERT_DEF_12_DEVICE_H + +#include "atcacert/atcacert_def.h" + +extern const uint8_t g_test_signer_12_ca_public_key[]; +extern const atcacert_def_t g_test_cert_def_12_device; + +#endif diff --git a/test/cmd-processor.c b/test/cmd-processor.c index aa373a5e6..25cd378b4 100644 --- a/test/cmd-processor.c +++ b/test/cmd-processor.c @@ -45,21 +45,23 @@ #include "atcacert/test_atcacert.h" #endif -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) #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" +#ifndef LIBRARY_USAGE_EN +/* Common API Testing - atcab_ is the classic Cryptoauthlib API */ +#include "api_atcab/test_atcab.h" + /* Library Integration Tests - Tests to ensure the library accesses device properly*/ #include "integration/test_integration.h" /* Hal layer testing */ #include "hal/test_hal.h" +#endif /* JWT Support */ #include "jwt/test_jwt.h" @@ -107,12 +109,14 @@ static t_menu_info mas_menu_info[] = #ifdef ATCA_TA101_SUPPORT { "ta101", "Set Target Device to TA101", select_device }, #endif +#ifndef LIBRARY_USAGE_EN { "info", "Get the Chip Revision", info }, { "sernum", "Get the Chip Serial Number", read_sernum }, - { "rand", "Generate Some Random Numbers", do_randoms }, { "readcfg", "Read the Config Zone", read_config }, - { "lockstat", "Zone Lock Status", lock_status }, { "hal", "Tests hal drivers functionality", hal_tests }, +#endif + { "rand", "Generate Some Random Numbers", do_randoms }, + { "lockstat", "Zone Lock Status", lock_status }, #ifdef ATCA_TEST_LOCK_ENABLE { "lockcfg", "Lock the Config Zone", lock_config }, { "lockdata", "Lock Data and OTP Zones", lock_data }, diff --git a/test/hal/test_hal_basic.c b/test/hal/test_hal_basic.c index ac77499f9..940ebb968 100644 --- a/test/hal/test_hal_basic.c +++ b/test/hal/test_hal_basic.c @@ -141,8 +141,10 @@ TEST(hal, ta_single_and_multi_part_write_read) status = talib_handle_init_data(&attr_data_handle, write_element_size); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#if TALIB_CREATE_SHARED_DATA_EN status = talib_create_element(atcab_get_device(), &attr_data_handle, &data_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif //Reset data buffers... Read buffer with 0's and Write buffer with random data memset(read_data_buf.buf, 0x0, read_data_buf.len); @@ -157,8 +159,10 @@ TEST(hal, ta_single_and_multi_part_write_read) TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); TEST_ASSERT_EQUAL_MEMORY(write_data_buf.buf, read_data_buf.buf, write_element_size); +#if TALIB_DELETE_EN status = talib_delete_handle(atcab_get_device(), (uint32_t)data_handle); TEST_ASSERT_EQUAL(ATCA_SUCCESS, status); +#endif } } #endif diff --git a/test/tng/tng_atcacert_client_test.c b/test/tng/tng_atcacert_client_test.c index 78f58d46b..192622fa8 100644 --- a/test/tng/tng_atcacert_client_test.c +++ b/test/tng/tng_atcacert_client_test.c @@ -183,6 +183,7 @@ TEST(tng_atcacert_client, tng_atcacert_signer_public_key_no_cert) size_t cert_size = 0; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); ret = tng_atcacert_max_signer_cert_size(&cert_size); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); @@ -197,7 +198,7 @@ TEST(tng_atcacert_client, tng_atcacert_signer_public_key_no_cert) &g_tngtls_cert_def_1_signer, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); ret = tng_atcacert_signer_public_key(public_key, NULL); @@ -212,6 +213,7 @@ TEST(tng_atcacert_client, tng_atcacert_signer_public_key_cert) size_t cert_size = 0; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); ret = tng_atcacert_max_signer_cert_size(&cert_size); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); @@ -226,7 +228,7 @@ TEST(tng_atcacert_client, tng_atcacert_signer_public_key_cert) &g_tngtls_cert_def_1_signer, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); ret = tng_atcacert_signer_public_key(public_key, cert); @@ -480,6 +482,7 @@ TEST(tng_atcacert_client, tng_atcacert_device_public_key_no_cert) const atcacert_def_t* cert_def = NULL; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); ret = tng_atcacert_max_device_cert_size(&cert_size); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); @@ -494,7 +497,7 @@ TEST(tng_atcacert_client, tng_atcacert_device_public_key_no_cert) cert_def, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); ret = tng_atcacert_device_public_key(public_key, NULL); @@ -510,6 +513,7 @@ TEST(tng_atcacert_client, tng_atcacert_device_public_key_cert) const atcacert_def_t* cert_def = NULL; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); ret = tng_atcacert_max_device_cert_size(&cert_size); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); @@ -524,7 +528,7 @@ TEST(tng_atcacert_client, tng_atcacert_device_public_key_cert) cert_def, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_EQUAL(ATCA_SUCCESS, ret); ret = tng_atcacert_device_public_key(public_key, cert); diff --git a/test/vectors/vector_utils.c b/test/vectors/vector_utils.c index dff5230d5..19fa2d1a3 100644 --- a/test/vectors/vector_utils.c +++ b/test/vectors/vector_utils.c @@ -58,7 +58,7 @@ static void hex_to_data(const char* hex_str, uint8_t* data, size_t data_size) } } -static char line[16384]; +static char line[25608]; ATCA_STATUS read_rsp_match_value(FILE* file, const char* name, const char* match) { diff --git a/test/vectors/vectors_config_check.h b/test/vectors/vectors_config_check.h index 52b18663b..fc1c2bd46 100644 --- a/test/vectors/vectors_config_check.h +++ b/test/vectors/vectors_config_check.h @@ -34,7 +34,7 @@ #include "calib/calib_config_check.h" #endif -#if ATCA_TA_SUPPORT +#if ATCA_TA_SUPPORT && !defined(LIBRARY_USAGE_EN) #include "api_talib/test_talib_vectors.h" #endif diff --git a/test/wpc/wpc_apis_test.c b/test/wpc/wpc_apis_test.c index 86f5a1210..866f2589d 100644 --- a/test/wpc/wpc_apis_test.c +++ b/test/wpc/wpc_apis_test.c @@ -35,7 +35,9 @@ TEST_GROUP(wpc_apis); TEST_SETUP(wpc_apis) { atcab_init(gCfg); +#if !ATCA_CA2_SUPPORT test_assert_data_is_locked(); +#endif } TEST_TEAR_DOWN(wpc_apis) @@ -76,7 +78,7 @@ TEST(wpc_apis, wpc_get_digests_request_response) TEST(wpc_apis, wpc_get_certificate_request_response) { int ret; - uint8_t request[2]; + uint8_t request[4]; uint8_t response[1024]; uint8_t buffer[512]; uint16_t buflen; @@ -130,12 +132,17 @@ TEST(wpc_apis, wpc_challenge_request_response) /* Verify the challenge response */ } +bool test_wpc_api_cond(void) +{ + return (ATECC608 == atca_test_get_device_type() || atcab_is_ca2_device(atca_test_get_device_type())); +} + // *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)}, + { REGISTER_TEST_CASE(wpc_apis, wpc_get_digests_request_response), test_wpc_api_cond}, + { REGISTER_TEST_CASE(wpc_apis, wpc_get_certificate_request_response), test_wpc_api_cond}, + { REGISTER_TEST_CASE(wpc_apis, wpc_challenge_request_response), test_wpc_api_cond}, { (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 index 53b39a46b..c1f3b3c47 100644 --- a/test/wpc/wpccert_client_test.c +++ b/test/wpc/wpccert_client_test.c @@ -35,7 +35,9 @@ TEST_GROUP(wpccert_client); TEST_SETUP(wpccert_client) { atcab_init(gCfg); +#if !ATCA_CA2_SUPPORT test_assert_data_is_locked(); +#endif } TEST_TEAR_DOWN(wpccert_client) @@ -72,23 +74,24 @@ TEST(wpccert_client, wpccert_mfg_public_key_no_cert) size_t cert_size = 0; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); const atcacert_def_t* cert_def; ATCADevice device = atcab_get_device(); - ret = wpccert_get_slot_info(NULL, &cert_def, 0); + ret = wpccert_get_slot_info(NULL, &cert_def, NULL, NULL, 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_def->ca_cert_def, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_SUCCESS(ret); - ret = wpccert_public_key(cert_def, public_key, NULL); + ret = wpccert_public_key(cert_def->ca_cert_def, public_key, NULL); TEST_ASSERT_SUCCESS(ret); TEST_ASSERT_EQUAL_MEMORY(cert_public_key, public_key, sizeof(public_key)); } @@ -100,10 +103,11 @@ TEST(wpccert_client, wpccert_mfg_public_key_cert) size_t cert_size = 0; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); const atcacert_def_t* cert_def; ATCADevice device = atcab_get_device(); - ret = wpccert_get_slot_info(NULL, &cert_def, 0); + ret = wpccert_get_slot_info(NULL, &cert_def, NULL, NULL, 0); TEST_ASSERT_SUCCESS(ret); ret = wpccert_read_mfg_cert(device, cert, &cert_size, 0); @@ -113,10 +117,10 @@ TEST(wpccert_client, wpccert_mfg_public_key_cert) cert_def->ca_cert_def, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_SUCCESS(ret); - ret = wpccert_public_key(cert_def, public_key, cert); + ret = wpccert_public_key(cert_def->ca_cert_def, public_key, cert); TEST_ASSERT_SUCCESS(ret); TEST_ASSERT_EQUAL_MEMORY(cert_public_key, public_key, sizeof(public_key)); } @@ -129,12 +133,15 @@ TEST(wpccert_client, wpccert_pdu_public_key_no_cert) size_t cert_size = 0; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); const atcacert_def_t* cert_def; ATCADevice device = atcab_get_device(); - ret = wpccert_get_slot_info(NULL, &cert_def, 0); + ret = wpccert_get_slot_info(NULL, &cert_def, NULL, NULL, 0); TEST_ASSERT_SUCCESS(ret); + ret = wpccert_read_cert_size(device, cert_def, &cert_size); + ret = wpccert_read_pdu_cert(device, cert, &cert_size, 0); TEST_ASSERT_SUCCESS(ret); @@ -142,7 +149,7 @@ TEST(wpccert_client, wpccert_pdu_public_key_no_cert) cert_def, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_SUCCESS(ret); ret = wpccert_public_key(cert_def, public_key, NULL); @@ -157,10 +164,14 @@ TEST(wpccert_client, wpccert_pdu_public_key_cert) size_t cert_size = 0; uint8_t public_key[ATCA_ECCP256_PUBKEY_SIZE]; uint8_t cert_public_key[ATCA_ECCP256_PUBKEY_SIZE]; + cal_buffer cert_pubkey = CAL_BUF_INIT(sizeof(cert_public_key), cert_public_key); const atcacert_def_t* cert_def; ATCADevice device = atcab_get_device(); - ret = wpccert_get_slot_info(NULL, &cert_def, 0); + ret = wpccert_get_slot_info(NULL, &cert_def, NULL, NULL, 0); + TEST_ASSERT_SUCCESS(ret); + + ret = wpccert_read_cert_size(device, cert_def, &cert_size); TEST_ASSERT_SUCCESS(ret); ret = wpccert_read_pdu_cert(device, cert, &cert_size, 0); @@ -170,7 +181,7 @@ TEST(wpccert_client, wpccert_pdu_public_key_cert) cert_def, cert, cert_size, - cert_public_key); + &cert_pubkey); TEST_ASSERT_EQUAL(ATCACERT_E_SUCCESS, ret); ret = wpccert_public_key(cert_def, public_key, cert); @@ -178,15 +189,25 @@ TEST(wpccert_client, wpccert_pdu_public_key_cert) TEST_ASSERT_EQUAL_MEMORY(cert_public_key, public_key, sizeof(public_key)); } +/** \brief Configured device is ECC608 */ +bool test_wpc_cond(void) +{ + return (ATECC608 == atca_test_get_device_type() || atcab_is_ca2_device(atca_test_get_device_type())); +} + // *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)}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_read_mfg_cert), test_wpc_cond}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_read_pdu_cert), test_wpc_cond}, +#if ATCA_ECC_SUPPORT + { REGISTER_TEST_CASE(wpccert_client, wpccert_mfg_public_key_no_cert), atca_test_cond_ecc608}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_mfg_public_key_cert), atca_test_cond_ecc608}, +#endif +#if (ATCA_ECC_SUPPORT || (ATCA_CA2_SUPPORT && ATCACERT_INTEGRATION_EN)) + { REGISTER_TEST_CASE(wpccert_client, wpccert_pdu_public_key_no_cert), test_wpc_cond}, + { REGISTER_TEST_CASE(wpccert_client, wpccert_pdu_public_key_cert), test_wpc_cond}, +#endif { (fp_test_case)NULL, (uint8_t)0 }, }; // *INDENT-ON* diff --git a/third_party/wolfssl_settings.h.in b/third_party/wolfssl_settings.h.in index d3b38b6e1..460ba8545 100644 --- a/third_party/wolfssl_settings.h.in +++ b/third_party/wolfssl_settings.h.in @@ -52,6 +52,14 @@ #define NO_PWDBASED +#define WOLFSSL_SHA384 + +#define WOLFSSL_SHA512 + +#define WOLFSSL_NOSHA512_224 + +#define WOLFSSL_NOSHA512_256 + #ifdef __cplusplus } /* extern "C" */ #endif