diff --git a/.gitmodules b/.gitmodules index 9fffcaf184..1e7dd564c0 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,10 +25,6 @@ path = libraries/aws/device-defender-for-aws-iot-embedded-sdk branch = main url = https://github.com/aws/device-defender-for-aws-iot-embedded-sdk.git -[submodule "libraries/standard/corePKCS11"] - path = libraries/standard/corePKCS11 - branch = main - url = https://github.com/FreeRTOS/corePKCS11.git [submodule "libraries/standard/backoffAlgorithm"] path = libraries/standard/backoffAlgorithm branch = main diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/CMakeLists.txt b/demos/fleet_provisioning/fleet_provisioning_csr/CMakeLists.txt similarity index 59% rename from demos/fleet_provisioning/fleet_provisioning_with_csr/CMakeLists.txt rename to demos/fleet_provisioning/fleet_provisioning_csr/CMakeLists.txt index 451ca2857a..1dd9f41f52 100644 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/CMakeLists.txt +++ b/demos/fleet_provisioning/fleet_provisioning_csr/CMakeLists.txt @@ -10,17 +10,6 @@ include( ${CMAKE_SOURCE_DIR}/libraries/standard/backoffAlgorithm/backoffAlgorith include( ${CMAKE_SOURCE_DIR}/libraries/aws/fleet-provisioning-for-aws-iot-embedded-sdk/fleetprovisioningFilePaths.cmake ) -# Set path to corePKCS11 and it's third party libraries. -set(COREPKCS11_LOCATION "${CMAKE_SOURCE_DIR}/libraries/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") - -# Include PKCS #11 library's source and header path variables. -include( ${COREPKCS11_LOCATION}/pkcsFilePaths.cmake ) - -list(APPEND PKCS_SOURCES - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c" -) - # CPP files are searched for supporting CI build checks that verify C++ linkage of the Fleet Provisioning library file( GLOB DEMO_SRCS "*.c*" ) @@ -30,35 +19,25 @@ add_executable( ${DEMO_NAME} ${MQTT_SOURCES} ${MQTT_SERIALIZER_SOURCES} ${BACKOFF_ALGORITHM_SOURCES} - ${PKCS_SOURCES} - ${PKCS_PAL_POSIX_SOURCES} ${FLEET_PROVISIONING_SOURCES} ) target_link_libraries( ${DEMO_NAME} PRIVATE tinycbor mbedtls clock_posix - transport_mbedtls_pkcs11_posix ) + transport_mbedtls_posix ) target_include_directories( ${DEMO_NAME} PUBLIC ${LOGGING_INCLUDE_DIRS} ${MQTT_INCLUDE_PUBLIC_DIRS} ${BACKOFF_ALGORITHM_INCLUDE_PUBLIC_DIRS} - ${PKCS_INCLUDE_PUBLIC_DIRS} - ${PKCS_PAL_INCLUDE_PUBLIC_DIRS} ${AWS_DEMO_INCLUDE_DIRS} - "${FLEET_PROVISIONING_INCLUDE_PUBLIC_DIRS}" - "${DEMOS_DIR}/pkcs11/common/include" # corePKCS11 config - "${CMAKE_SOURCE_DIR}/platform/include" - "${CMAKE_CURRENT_LIST_DIR}" - PRIVATE - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils" ) + ${FLEET_PROVISIONING_INCLUDE_PUBLIC_DIRS} + ${CMAKE_SOURCE_DIR}/platform/include + ${CMAKE_CURRENT_LIST_DIR} ) set_macro_definitions(TARGETS ${DEMO_NAME} - OPTIONAL - "DOWNLOADED_CERT_WRITE_PATH" - "GENERATED_PRIVATE_KEY_WRITE_PATH" REQUIRED "AWS_IOT_ENDPOINT" "ROOT_CA_CERT_PATH" @@ -70,4 +49,6 @@ set_macro_definitions(TARGETS ${DEMO_NAME} "CLIENT_IDENTIFIER" "OS_NAME" "OS_VERSION" - "HARDWARE_PLATFORM_NAME") + "HARDWARE_PLATFORM_NAME" + "CLIENT_PRIVATE_KEY_PATH" + "CLIENT_CERT_PATH") diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/core_mqtt_config.h b/demos/fleet_provisioning/fleet_provisioning_csr/core_mqtt_config.h similarity index 100% rename from demos/fleet_provisioning/fleet_provisioning_keys_cert/core_mqtt_config.h rename to demos/fleet_provisioning/fleet_provisioning_csr/core_mqtt_config.h diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/demo_config.h b/demos/fleet_provisioning/fleet_provisioning_csr/demo_config.h similarity index 100% rename from demos/fleet_provisioning/fleet_provisioning_with_csr/demo_config.h rename to demos/fleet_provisioning/fleet_provisioning_csr/demo_config.h diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/example_claim_policy.json b/demos/fleet_provisioning/fleet_provisioning_csr/example_claim_policy.json similarity index 100% rename from demos/fleet_provisioning/fleet_provisioning_with_csr/example_claim_policy.json rename to demos/fleet_provisioning/fleet_provisioning_csr/example_claim_policy.json diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/example_demo_template.json b/demos/fleet_provisioning/fleet_provisioning_csr/example_demo_template.json similarity index 100% rename from demos/fleet_provisioning/fleet_provisioning_keys_cert/example_demo_template.json rename to demos/fleet_provisioning/fleet_provisioning_csr/example_demo_template.json diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_config.h b/demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_config.h similarity index 100% rename from demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_config.h rename to demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_config.h diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_serializer.c b/demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_serializer.c similarity index 100% rename from demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_serializer.c rename to demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_serializer.c diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_serializer.h b/demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_serializer.h similarity index 100% rename from demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_serializer.h rename to demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_serializer.h diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_with_csr_demo.c b/demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_with_csr_demo.c similarity index 87% rename from demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_with_csr_demo.c rename to demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_with_csr_demo.c index f950f0abd8..0cab93fba4 100644 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_with_csr_demo.c +++ b/demos/fleet_provisioning/fleet_provisioning_csr/fleet_provisioning_with_csr_demo.c @@ -58,24 +58,16 @@ #include #include -#if defined( DOWNLOADED_CERT_WRITE_PATH ) - #include -#endif // DOWNLOADED_CERT_WRITE_PATH - /* Demo config. */ #include "demo_config.h" -/* corePKCS11 includes. */ -#include "core_pkcs11.h" -#include "core_pkcs11_config.h" - /* AWS IoT Fleet Provisioning Library. */ #include "fleet_provisioning.h" /* Demo includes. */ #include "mqtt_operations.h" -#include "pkcs11_operations.h" #include "fleet_provisioning_serializer.h" +#include "mbedtls_posix.h" /** * These configurations are required. Throw compilation error if it is not @@ -483,14 +475,14 @@ int main( int argc, char ownershipToken[ OWNERSHIP_TOKEN_BUFFER_LENGTH ]; size_t ownershipTokenLength; bool connectionEstablished = false; - CK_SESSION_HANDLE p11Session; int demoRunCount = 0; - CK_RV pkcs11ret = CKR_OK; /* Silence compiler warnings about unused variables. */ ( void ) argc; ( void ) argv; + psa_crypto_init(); + do { /* Initialize the buffer lengths to their max lengths. */ @@ -498,29 +490,6 @@ int main( int argc, certificateIdLength = CERT_ID_BUFFER_LENGTH; ownershipTokenLength = OWNERSHIP_TOKEN_BUFFER_LENGTH; - /* Initialize the PKCS #11 module */ - pkcs11ret = xInitializePkcs11Session( &p11Session ); - - if( pkcs11ret != CKR_OK ) - { - LogError( ( "Failed to initialize PKCS #11." ) ); - status = false; - } - else - { - /* Insert the claim credentials into the PKCS #11 module */ - status = loadClaimCredentials( p11Session, - CLAIM_CERT_PATH, - pkcs11configLABEL_CLAIM_CERTIFICATE, - CLAIM_PRIVATE_KEY_PATH, - pkcs11configLABEL_CLAIM_PRIVATE_KEY ); - - if( status == false ) - { - LogError( ( "Failed to provision PKCS #11 with claim credentials." ) ); - } - } - /**** Connect to AWS IoT Core with provisioning claim credentials *****/ /* We first use the claim credentials to connect to the broker. These @@ -528,26 +497,22 @@ int main( int argc, * CreateCertificatefromCsr or CreateKeysAndCertificate. * In this demo we use CreateCertificatefromCsr. */ - if( status == true ) - { - /* Attempts to connect to the AWS IoT MQTT broker. If the - * connection fails, retries after a timeout. Timeout value will - * exponentially increase until maximum attempts are reached. */ - LogInfo( ( "Establishing MQTT session with claim certificate..." ) ); - status = EstablishMqttSession( provisioningPublishCallback, - p11Session, - pkcs11configLABEL_CLAIM_CERTIFICATE, - pkcs11configLABEL_CLAIM_PRIVATE_KEY ); + /* Attempts to connect to the AWS IoT MQTT broker. If the + * connection fails, retries after a timeout. Timeout value will + * exponentially increase until maximum attempts are reached. */ + LogInfo( ( "Establishing MQTT session with claim certificate..." ) ); + status = EstablishMqttSession( provisioningPublishCallback, + CLAIM_CERT_PATH, + CLAIM_PRIVATE_KEY_PATH ); - if( status == false ) - { - LogError( ( "Failed to establish MQTT session." ) ); - } - else - { - LogInfo( ( "Established connection with claim credentials." ) ); - connectionEstablished = true; - } + if( status == false ) + { + LogError( ( "Failed to establish MQTT session." ) ); + } + else + { + LogInfo( ( "Established connection with claim credentials." ) ); + connectionEstablished = true; } /**** Call the CreateCertificateFromCsr API ***************************/ @@ -565,13 +530,22 @@ int main( int argc, if( status == true ) { - /* Create a new key and CSR. */ - status = generateKeyAndCsr( p11Session, - pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS, - pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS, - csr, - CSR_BUFFER_LENGTH, - &csrLength ); + if( Mbedtls_GenerateECKey( CLIENT_PRIVATE_KEY_PATH ) != MBEDTLS_SUCCESS ) + { + status = false; + } + } + + if( status == true ) + { + if( Mbedtls_GenerateCSR( CLIENT_PRIVATE_KEY_PATH, csr, CSR_BUFFER_LENGTH ) != MBEDTLS_SUCCESS ) + { + status = false; + } + else + { + csrLength = strnlen( csr, CSR_BUFFER_LENGTH ); + } } if( status == true ) @@ -628,11 +602,26 @@ int main( int argc, if( status == true ) { - /* Save the certificate into PKCS #11. */ - status = loadCertificate( p11Session, - certificate, - pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS, - certificateLength ); + FILE * pFile = fopen(CLIENT_CERT_PATH, "w"); + + if( pFile == NULL ) + { + status = false; + } + else + { + size_t bytesWritten = fwrite( certificate, 1, certificateLength, pFile ); + if( bytesWritten != certificateLength ) + { + status = false; + LogError( ( "Failed to write device certificate to file %s.", CLIENT_CERT_PATH ) ); + } + else + { + LogInfo( ( "Wrote client certificate to path: %s, length: %lu", CLIENT_CERT_PATH, ( unsigned long ) certificateLength ) ); + } + fclose( pFile ); + } } if( status == true ) @@ -725,9 +714,8 @@ int main( int argc, { LogInfo( ( "Establishing MQTT session with provisioned certificate..." ) ); status = EstablishMqttSession( provisioningPublishCallback, - p11Session, - pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS, - pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS ); + CLIENT_CERT_PATH, + CLIENT_PRIVATE_KEY_PATH ); if( status != true ) { @@ -752,8 +740,6 @@ int main( int argc, connectionEstablished = false; } - pkcs11CloseSession( p11Session ); - /**** Retry in case of failure ****************************************/ /* Increment the demo run count. */ @@ -781,34 +767,6 @@ int main( int argc, if( status == true ) { LogInfo( ( "Demo completed successfully." ) ); - - #if defined( DOWNLOADED_CERT_WRITE_PATH ) - { - int fd = open( DOWNLOADED_CERT_WRITE_PATH, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR ); - - if( -1 != fd ) - { - const ssize_t writtenBytes = write( fd, certificate, certificateLength ); - - if( writtenBytes == certificateLength ) - { - LogInfo( ( "Written %s successfully.", DOWNLOADED_CERT_WRITE_PATH ) ); - } - else - { - LogError( ( "Could not write to %s. Error: %s.", DOWNLOADED_CERT_WRITE_PATH, strerror( errno ) ) ); - } - - close( fd ); - } - else - { - LogError( ( "Could not open %s. Error: %s.", DOWNLOADED_CERT_WRITE_PATH, strerror( errno ) ) ); - } - } - #else /* if defined( DOWNLOADED_CERT_WRITE_PATH ) */ - LogInfo( ( "NOTE: define DOWNLOADED_CERT_WRITE_PATH in order to have the certificate written to disk." ) ); - #endif // DOWNLOADED_CERT_WRITE_PATH } return ( status == true ) ? EXIT_SUCCESS : EXIT_FAILURE; diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/mqtt_operations.c b/demos/fleet_provisioning/fleet_provisioning_csr/mqtt_operations.c similarity index 93% rename from demos/fleet_provisioning/fleet_provisioning_keys_cert/mqtt_operations.c rename to demos/fleet_provisioning/fleet_provisioning_csr/mqtt_operations.c index f62e79e0c8..694e6c4fe3 100644 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/mqtt_operations.c +++ b/demos/fleet_provisioning/fleet_provisioning_csr/mqtt_operations.c @@ -48,7 +48,7 @@ #include "mqtt_operations.h" /* MbedTLS transport include. */ -#include "mbedtls_pkcs11_posix.h" +#include "mbedtls_posix.h" /*Include backoff algorithm header for retry logic.*/ #include "backoff_algorithm.h" @@ -145,7 +145,7 @@ /** * @brief Timeout in milliseconds for transport send and receive. */ -#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 1000U ) +#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 2000U ) /** * @brief The MQTT metrics string expected by AWS IoT MQTT Broker. @@ -190,7 +190,7 @@ typedef struct PublishPackets /* Each compilation unit must define the NetworkContext struct. */ struct NetworkContext { - MbedtlsPkcs11Context_t * pParams; + MbedtlsContext_t * pParams; }; /*-----------------------------------------------------------*/ @@ -243,7 +243,7 @@ static NetworkContext_t networkContext = { 0 }; /** * @brief The parameters for MbedTLS operation. */ -static MbedtlsPkcs11Context_t tlsContext = { 0 }; +static MbedtlsContext_t tlsContext = { 0 }; /** * @brief The flag to indicate that the mqtt session is established. @@ -275,14 +275,6 @@ static MQTTPubAckInfo_t pOutgoingPublishRecords[ OUTGOING_PUBLISH_RECORD_LEN ]; static MQTTPubAckInfo_t pIncomingPublishRecords[ INCOMING_PUBLISH_RECORD_LEN ]; /*-----------------------------------------------------------*/ -/** - * @brief The random number generator to use for exponential backoff with - * jitter retry logic. - * - * @return The generated random number. - */ -static uint32_t generateRandomNumber( void ); - /** * @brief Connect to the MQTT broker with reconnection retries. * @@ -291,16 +283,14 @@ static uint32_t generateRandomNumber( void ); * of attempts are exhausted. * * @param[out] pNetworkContext The created network context. - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pClientCertLabel The client certificate PKCS #11 label to use. - * @param[in] pPrivateKeyLabel The private key PKCS #11 label for the client certificate. + * @param[in] pClientCertPath Path to the client certificate to use. + * @param[in] pPrivateKeyPath Path to the private key of the client certificate. * * @return false on failure; true on successful connection. */ static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContext, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ); + const char * pClientCertPath, + const char * pPrivateKeyPath ); /** * @brief Get the free index in the #outgoingPublishPackets array at which an @@ -374,24 +364,18 @@ static bool handlePublishResend( MQTTContext_t * pMqttContext ); static bool waitForPacketAck( MQTTContext_t * pMqttContext, uint16_t usPacketIdentifier, uint32_t ulTimeout ); -/*-----------------------------------------------------------*/ -static uint32_t generateRandomNumber() -{ - return( ( uint32_t ) rand() ); -} /*-----------------------------------------------------------*/ static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContext, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ) + const char * pClientCertPath, + const char * pPrivateKeyPath ) { bool returnStatus = false; BackoffAlgorithmStatus_t backoffAlgStatus = BackoffAlgorithmSuccess; - MbedtlsPkcs11Status_t tlsStatus = MBEDTLS_PKCS11_SUCCESS; + MbedtlsStatus_t tlsStatus = MBEDTLS_SUCCESS; BackoffAlgorithmContext_t reconnectParams; - MbedtlsPkcs11Credentials_t tlsCredentials = { 0 }; + MbedtlsCredentials_t tlsCredentials = { 0 }; uint16_t nextRetryBackOff = 0U; /* Set the pParams member of the network context with desired transport. */ @@ -399,9 +383,8 @@ static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContex /* Initialize credentials for establishing TLS session. */ tlsCredentials.pRootCaPath = ROOT_CA_CERT_PATH; - tlsCredentials.pClientCertLabel = pClientCertLabel; - tlsCredentials.pPrivateKeyLabel = pPrivateKeyLabel; - tlsCredentials.p11Session = p11Session; + tlsCredentials.pClientCertPath = pClientCertPath; + tlsCredentials.pPrivateKeyPath = pPrivateKeyPath; /* AWS IoT requires devices to send the Server Name Indication (SNI) * extension to the Transport Layer Security (TLS) protocol and provide @@ -439,13 +422,13 @@ static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContex AWS_IOT_ENDPOINT, AWS_MQTT_PORT ) ); - tlsStatus = Mbedtls_Pkcs11_Connect( pNetworkContext, + tlsStatus = Mbedtls_Connect( pNetworkContext, AWS_IOT_ENDPOINT, AWS_MQTT_PORT, &tlsCredentials, TRANSPORT_SEND_RECV_TIMEOUT_MS ); - if( tlsStatus == MBEDTLS_PKCS11_SUCCESS ) + if( tlsStatus == MBEDTLS_SUCCESS ) { /* Connection successful. */ returnStatus = true; @@ -453,7 +436,7 @@ static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContex else { /* Generate a random number and get back-off value (in milliseconds) for the next connection retry. */ - backoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &reconnectParams, generateRandomNumber(), &nextRetryBackOff ); + backoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &reconnectParams, ( uint32_t ) rand(), &nextRetryBackOff ); if( backoffAlgStatus == BackoffAlgorithmRetriesExhausted ) { @@ -467,7 +450,7 @@ static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContex Clock_SleepMs( nextRetryBackOff ); } } - } while( ( tlsStatus != MBEDTLS_PKCS11_SUCCESS ) && ( backoffAlgStatus == BackoffAlgorithmSuccess ) ); + } while( ( tlsStatus != MBEDTLS_SUCCESS ) && ( backoffAlgStatus == BackoffAlgorithmSuccess ) ); return returnStatus; } @@ -728,16 +711,14 @@ static bool waitForPacketAck( MQTTContext_t * pMqttContext, /*-----------------------------------------------------------*/ bool EstablishMqttSession( MQTTPublishCallback_t publishCallback, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ) + char * pClientCertPath, + char * pPrivateKeyPath ) { bool returnStatus = false; MQTTStatus_t mqttStatus; MQTTConnectInfo_t connectInfo; MQTTFixedBuffer_t networkBuffer; TransportInterface_t transport = { NULL }; - bool createCleanSession = false; MQTTContext_t * pMqttContext = &mqttContext; NetworkContext_t * pNetworkContext = &networkContext; bool sessionPresent = false; @@ -750,9 +731,8 @@ bool EstablishMqttSession( MQTTPublishCallback_t publishCallback, ( void ) memset( pNetworkContext, 0U, sizeof( NetworkContext_t ) ); returnStatus = connectToBrokerWithBackoffRetries( pNetworkContext, - p11Session, - pClientCertLabel, - pPrivateKeyLabel ); + pClientCertPath, + pPrivateKeyPath ); if( returnStatus != true ) { @@ -768,8 +748,8 @@ bool EstablishMqttSession( MQTTPublishCallback_t publishCallback, * For this demo, TCP sockets are used to send and receive data * from the network. pNetworkContext is an SSL context for OpenSSL.*/ transport.pNetworkContext = pNetworkContext; - transport.send = Mbedtls_Pkcs11_Send; - transport.recv = Mbedtls_Pkcs11_Recv; + transport.send = Mbedtls_Send; + transport.recv = Mbedtls_Recv; transport.writev = NULL; /* Fill the values for network buffer. */ @@ -810,11 +790,7 @@ bool EstablishMqttSession( MQTTPublishCallback_t publishCallback, { /* Establish an MQTT session by sending a CONNECT packet. */ - /* If #createCleanSession is true, start with a clean session - * i.e. direct the MQTT broker to discard any previous session data. - * If #createCleanSession is false, direct the broker to attempt to - * reestablish a session which was already present. */ - connectInfo.cleanSession = createCleanSession; + connectInfo.cleanSession = false; /* The client identifier is used to uniquely identify this MQTT client to * the MQTT broker. In a production device the identifier can be something @@ -923,7 +899,7 @@ bool DisconnectMqttSession( void ) } /* End TLS session, then close TCP connection. */ - ( void ) Mbedtls_Pkcs11_Disconnect( pNetworkContext ); + ( void ) Mbedtls_Disconnect( pNetworkContext ); return returnStatus; } diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/mqtt_operations.h b/demos/fleet_provisioning/fleet_provisioning_csr/mqtt_operations.h similarity index 89% rename from demos/fleet_provisioning/fleet_provisioning_keys_cert/mqtt_operations.h rename to demos/fleet_provisioning/fleet_provisioning_csr/mqtt_operations.h index d9cdad7528..bdd15eed94 100644 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/mqtt_operations.h +++ b/demos/fleet_provisioning/fleet_provisioning_csr/mqtt_operations.h @@ -26,9 +26,6 @@ /* MQTT API header. */ #include "core_mqtt.h" -/* corePKCS11 include. */ -#include "core_pkcs11.h" - /** * @brief Application callback type to handle the incoming publishes. * @@ -43,17 +40,15 @@ typedef void (* MQTTPublishCallback_t )( MQTTPublishInfo_t * pPublishInfo, * * @param[in] publishCallback The callback function to receive incoming * publishes from the MQTT broker. - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pClientCertLabel The client certificate PKCS #11 label to use. - * @param[in] pPrivateKeyLabel The private key PKCS #11 label for the client certificate. + * @param[in] pClientCertPath The client certificate PKCS #11 label to use. + * @param[in] pPrivateKeyPath The private key PKCS #11 label for the client certificate. * * @return true if an MQTT session is established; * false otherwise. */ bool EstablishMqttSession( MQTTPublishCallback_t publishCallback, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ); + char * pClientCertPath, + char * pPrivateKeyPath ); /** * @brief Disconnect the MQTT connection. diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/CMakeLists.txt b/demos/fleet_provisioning/fleet_provisioning_keys_cert/CMakeLists.txt deleted file mode 100644 index 1a2dd0a33a..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/CMakeLists.txt +++ /dev/null @@ -1,73 +0,0 @@ -set( DEMO_NAME "fleet_provisioning_keys_cert_demo" ) - -# Include MQTT library's source and header path variables. -include( ${CMAKE_SOURCE_DIR}/libraries/standard/coreMQTT/mqttFilePaths.cmake ) - -# Include backoffAlgorithm library file path configuration. -include( ${CMAKE_SOURCE_DIR}/libraries/standard/backoffAlgorithm/backoffAlgorithmFilePaths.cmake ) - -# Include Fleet Provisioning library's source and header path variables. -include( - ${CMAKE_SOURCE_DIR}/libraries/aws/fleet-provisioning-for-aws-iot-embedded-sdk/fleetprovisioningFilePaths.cmake ) - -# Set path to corePKCS11 and it's third party libraries. -set(COREPKCS11_LOCATION "${CMAKE_SOURCE_DIR}/libraries/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") - -# Include PKCS #11 library's source and header path variables. -include( ${COREPKCS11_LOCATION}/pkcsFilePaths.cmake ) - -list(APPEND PKCS_SOURCES - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c" -) - -# CPP files are searched for supporting CI build checks that verify C++ linkage of the Fleet Provisioning library -file( GLOB DEMO_SRCS "*.c*" ) - -# Demo target. -add_executable( ${DEMO_NAME} - ${DEMO_SRCS} - ${MQTT_SOURCES} - ${MQTT_SERIALIZER_SOURCES} - ${BACKOFF_ALGORITHM_SOURCES} - ${PKCS_SOURCES} - ${PKCS_PAL_POSIX_SOURCES} - ${FLEET_PROVISIONING_SOURCES} ) - -target_link_libraries( ${DEMO_NAME} PRIVATE - tinycbor - mbedtls - clock_posix - transport_mbedtls_pkcs11_posix ) - -target_include_directories( ${DEMO_NAME} - PUBLIC - ${LOGGING_INCLUDE_DIRS} - ${MQTT_INCLUDE_PUBLIC_DIRS} - ${BACKOFF_ALGORITHM_INCLUDE_PUBLIC_DIRS} - ${PKCS_INCLUDE_PUBLIC_DIRS} - ${PKCS_PAL_INCLUDE_PUBLIC_DIRS} - ${AWS_DEMO_INCLUDE_DIRS} - "${FLEET_PROVISIONING_INCLUDE_PUBLIC_DIRS}" - "${DEMOS_DIR}/pkcs11/common/include" # corePKCS11 config - "${CMAKE_SOURCE_DIR}/platform/include" - "${CMAKE_CURRENT_LIST_DIR}" - PRIVATE - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils" ) - -set_macro_definitions(TARGETS ${DEMO_NAME} - OPTIONAL - "DOWNLOADED_CERT_WRITE_PATH" - "DOWNLOADED_PRIVATE_KEY_WRITE_PATH" - REQUIRED - "AWS_IOT_ENDPOINT" - "ROOT_CA_CERT_PATH" - "CLAIM_CERT_PATH" - "CLAIM_PRIVATE_KEY_PATH" - "PROVISIONING_TEMPLATE_NAME" - "DEVICE_SERIAL_NUMBER" - "CSR_SUBJECT_NAME" - "CLIENT_IDENTIFIER" - "OS_NAME" - "OS_VERSION" - "HARDWARE_PLATFORM_NAME") diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/demo_config.h b/demos/fleet_provisioning/fleet_provisioning_keys_cert/demo_config.h deleted file mode 100644 index e095e21592..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/demo_config.h +++ /dev/null @@ -1,214 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef DEMO_CONFIG_H_ -#define DEMO_CONFIG_H_ - -/**************************************************/ -/******* DO NOT CHANGE the following order ********/ -/**************************************************/ - -/* Include logging header files and define logging macros in the following order: - * 1. Include the header file "logging_levels.h". - * 2. Define LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL. - * 3. Include the header file "logging_stack.h". - */ - -/* Include header that defines log levels. */ -#include "logging_levels.h" - -/* Logging configuration for the Demo. */ -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "FLEET_PROVISIONING_DEMO" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/************ End of logging configuration ****************/ - -/** - * @brief Details of the MQTT broker to connect to. - * - * This is the Thing's Rest API Endpoint for AWS IoT. - * - * @note Your AWS IoT Core endpoint can be found in the AWS IoT console under - * Settings/Custom Endpoint, or using the describe-endpoint API. - * - * #define AWS_IOT_ENDPOINT "...insert here..." - */ - -/** - * @brief AWS IoT MQTT broker port number. - * - * In general, port 8883 is for secured MQTT connections. - * - * @note Port 443 requires use of the ALPN TLS extension with the ALPN protocol - * name. When using port 8883, ALPN is not required. - */ -#define AWS_MQTT_PORT ( 8883 ) - -/** - * @brief Path of the file containing the server's root CA certificate. - * - * This certificate is used to identify the AWS IoT server and is publicly - * available. Refer to the AWS documentation available in the link below - * https://docs.aws.amazon.com/iot/latest/developerguide/server-authentication.html#server-authentication-certs - * - * Amazon's root CA certificate is automatically downloaded to the certificates - * directory from @ref https://www.amazontrust.com/repository/AmazonRootCA1.pem - * using the CMake build system. - * - * @note This certificate should be PEM-encoded. - * @note This path is relative from the demo binary created. Update - * ROOT_CA_CERT_PATH to the absolute path if this demo is executed from elsewhere. - */ -#ifndef ROOT_CA_CERT_PATH - #define ROOT_CA_CERT_PATH "certificates/AmazonRootCA1.crt" -#endif - -/** - * @brief Path of the file containing the provisioning claim certificate. This - * certificate is used to connect to AWS IoT Core and use Fleet Provisioning - * APIs to provision the client device. This is used for the "Provisioning by - * Claim" provisioning workflow. - * - * For information about provisioning by claim, see the following AWS documentation: - * https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html#claim-based - * - * @note This certificate should be PEM-encoded. The certificate should be - * registered on AWS IoT Core beforehand. It should have an AWS IoT policy to - * allow it to access only the Fleet Provisioning APIs. An example policy for - * the claim certificates for this demo is available in the - * example_claim_policy.json file in the demo directory. In the example, - * replace with your AWS region, with your - * account ID, and with the name of your provisioning template. - * - * #define CLAIM_CERT_PATH "...insert here..." - */ - -/** - * @brief Path of the file containing the provisioning claim private key. This - * key corresponds to the provisioning claim certificate and is used to - * authenticate with AWS IoT for provisioning by claim. - * - * For information about provisioning by claim, see the following AWS documentation: - * https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html#claim-based - * - * @note This private key should be PEM-encoded. - * - * #define CLAIM_PRIVATE_KEY_PATH "...insert here..." - */ - -/** - * @brief Name of the provisioning template to use for the RegisterThing - * portion of the Fleet Provisioning workflow. - * - * For information about provisioning templates, see the following AWS documentation: - * https://docs.aws.amazon.com/iot/latest/developerguide/provision-template.html#fleet-provision-template - * - * The example template used for this demo is available in the - * example_demo_template.json file in the demo directory. In the example, - * replace with the policy provisioned devices - * should have. The demo template uses Fn::Join to construct the Thing name by - * concatenating fp_demo_ and the serial number sent by the demo. - * - * @note The provisioning template MUST be created in AWS IoT before running the - * demo. - * - * #define PROVISIONING_TEMPLATE_NAME "...insert here..." - */ - -/** - * @brief Serial number to send in the request to the Fleet Provisioning - * RegisterThing API. - * - * This is sent as a parameter to the provisioning template, which uses it to - * generate a unique Thing name. This should be unique per device. - * - * #define DEVICE_SERIAL_NUMBER "...insert here..." - */ - -/** - * @brief Subject name to use when creating the certificate signing request (CSR) - * for provisioning the demo client with using the Fleet Provisioning - * CreateCertificateFromCsr APIs. - * - * This is passed to MbedTLS; see https://tls.mbed.org/api/x509__csr_8h.html#a954eae166b125cea2115b7db8c896e90 - */ -#ifndef CSR_SUBJECT_NAME - #define CSR_SUBJECT_NAME "CN=Fleet Provisioning Demo" -#endif - -/** - * @brief MQTT client identifier. - * - * No two clients may use the same client identifier simultaneously. - * - * @note The client identifier should match the Thing name per - * AWS IoT Security best practices: - * https://docs.aws.amazon.com/iot/latest/developerguide/security-best-practices.html - * However, it is not required for the demo to run. - */ -#ifndef CLIENT_IDENTIFIER - #define CLIENT_IDENTIFIER DEVICE_SERIAL_NUMBER -#endif - -/** - * @brief Size of the network buffer for MQTT packets. Must be large enough to - * hold the GetCertificateFromCsr response, which, among other things, includes - * a PEM encoded certificate. - */ -#define NETWORK_BUFFER_SIZE ( 4096U ) - -/** - * @brief The name of the operating system that the application is running on. - * The current value is given as an example. Please update for your specific - * operating system. - */ -#define OS_NAME "Ubuntu" - -/** - * @brief The version of the operating system that the application is running - * on. The current value is given as an example. Please update for your specific - * operating system version. - */ -#define OS_VERSION "18.04 LTS" - -/** - * @brief The name of the hardware platform the application is running on. The - * current value is given as an example. Please update for your specific - * hardware platform. - */ -#define HARDWARE_PLATFORM_NAME "PC" - -/** - * @brief The name of the MQTT library used and its version, following an "@" - * symbol. - */ -#include "core_mqtt.h" -#define MQTT_LIB "core-mqtt@" MQTT_LIBRARY_VERSION - -#endif /* ifndef DEMO_CONFIG_H_ */ diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/example_claim_policy.json b/demos/fleet_provisioning/fleet_provisioning_keys_cert/example_claim_policy.json deleted file mode 100644 index ec2b52eef9..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/example_claim_policy.json +++ /dev/null @@ -1,31 +0,0 @@ - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": [ - "iot:Connect" - ], - "Resource": "*" - }, - { - "Effect": "Allow", - "Action": [ - "iot:Publish", - "iot:Receive" - ], - "Resource": [ - "arn:aws:iot:::topic/$aws/certificates/create/*", - "arn:aws:iot:::topic/$aws/provisioning-templates//provision/*" - ] - }, - { - "Effect": "Allow", - "Action": "iot:Subscribe", - "Resource": [ - "arn:aws:iot:::topicfilter/$aws/certificates/create/*", - "arn:aws:iot:::topicfilter/$aws/provisioning-templates//provision/*" - ] - } - ] - } diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_keys_cert_demo.c b/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_keys_cert_demo.c deleted file mode 100644 index 3cb3feac27..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_keys_cert_demo.c +++ /dev/null @@ -1,833 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * Demo for showing use of the Fleet Provisioning library to use the Fleet - * Provisioning feature of AWS IoT Core for provisioning devices with - * credentials. This demo shows how a device can be provisioned with AWS IoT - * Core using the Certificate Signing Request workflow of the Fleet - * Provisioning feature. - * - * The Fleet Provisioning library provides macros and helper functions for - * assembling MQTT topics strings, and for determining whether an incoming MQTT - * message is related to the Fleet Provisioning API of AWS IoT Core. The Fleet - * Provisioning library does not depend on any particular MQTT library, - * therefore the functionality for MQTT operations is placed in another file - * (mqtt_operations.c). This demo uses the coreMQTT library. If needed, - * mqtt_operations.c can be modified to replace coreMQTT with another MQTT - * library. This demo requires using the AWS IoT Core broker as Fleet - * Provisioning is an AWS IoT Core feature. - * - * This demo provisions a device certificate using the provisioning by claim - * workflow with a Keys and Certificate Request. The demo connects to AWS - * IoT Core using provided claim credentials (whose certificate needs to be - * registered with IoT Core before running this demo), subscribes to the - * CreateKeysAndCertificate topics, and obtains keys and certificate. It then - * subscribes to the RegisterThing topics and activates the certificate and - * obtains a Thing using the provisioning template. Finally, it reconnects to - * AWS IoT Core using the new credentials. - */ - -/* Standard includes. */ -#include -#include -#include -#include - -/* POSIX includes. */ -#include -#include - -#if defined( DOWNLOADED_CERT_WRITE_PATH ) || defined( DOWNLOADED_PRIVATE_KEY_WRITE_PATH ) - #include -#endif - -/* Demo config. */ -#include "demo_config.h" - -/* corePKCS11 includes. */ -#include "core_pkcs11.h" -#include "core_pkcs11_config.h" - -/* AWS IoT Fleet Provisioning Library. */ -#include "fleet_provisioning.h" - -/* Demo includes. */ -#include "mqtt_operations.h" -#include "pkcs11_operations.h" -#include "fleet_provisioning_serializer.h" - -/** - * These configurations are required. Throw compilation error if it is not - * defined. - */ -#ifndef PROVISIONING_TEMPLATE_NAME - #error "Please define PROVISIONING_TEMPLATE_NAME to the template name registered with AWS IoT Core in demo_config.h." -#endif -#ifndef CLAIM_CERT_PATH - #error "Please define path to claim certificate (CLAIM_CERT_PATH) in demo_config.h." -#endif -#ifndef CLAIM_PRIVATE_KEY_PATH - #error "Please define path to claim private key (CLAIM_PRIVATE_KEY_PATH) in demo_config.h." -#endif -#ifndef DEVICE_SERIAL_NUMBER - #error "Please define a serial number (DEVICE_SERIAL_NUMBER) in demo_config.h." -#endif - -/** - * @brief The length of #PROVISIONING_TEMPLATE_NAME. - */ -#define PROVISIONING_TEMPLATE_NAME_LENGTH ( ( uint16_t ) ( sizeof( PROVISIONING_TEMPLATE_NAME ) - 1 ) ) - -/** - * @brief The length of #DEVICE_SERIAL_NUMBER. - */ -#define DEVICE_SERIAL_NUMBER_LENGTH ( ( uint16_t ) ( sizeof( DEVICE_SERIAL_NUMBER ) - 1 ) ) - -/** - * @brief Size of AWS IoT Thing name buffer. - * - * See https://docs.aws.amazon.com/iot/latest/apireference/API_CreateThing.html#iot-CreateThing-request-thingName - */ -#define MAX_THING_NAME_LENGTH 128 - -/** - * @brief The maximum number of times to run the loop in this demo. - * - * @note The demo loop is attempted to re-run only if it fails in an iteration. - * Once the demo loop succeeds in an iteration, the demo exits successfully. - */ -#ifndef FLEET_PROV_MAX_DEMO_LOOP_COUNT - #define FLEET_PROV_MAX_DEMO_LOOP_COUNT ( 3 ) -#endif - -/** - * @brief Time in seconds to wait between retries of the demo loop if - * demo loop fails. - */ -#define DELAY_BETWEEN_DEMO_RETRY_ITERATIONS_SECONDS ( 5 ) - -/** - * @brief Size of buffer in which to hold the private key. - */ -#define PRIV_KEY_BUFFER_LENGTH 2048 - -/** - * @brief Size of buffer in which to hold the certificate. - */ -#define CERT_BUFFER_LENGTH 2048 - -/** - * @brief Size of buffer in which to hold the certificate id. - * - * See https://docs.aws.amazon.com/iot/latest/apireference/API_Certificate.html#iot-Type-Certificate-certificateId - */ -#define CERT_ID_BUFFER_LENGTH 64 - -/** - * @brief Size of buffer in which to hold the certificate ownership token. - */ -#define OWNERSHIP_TOKEN_BUFFER_LENGTH 512 - -/** - * @brief Status values of the Fleet Provisioning response. - */ -typedef enum -{ - ResponseNotReceived, - ResponseAccepted, - ResponseRejected -} ResponseStatus_t; - -/*-----------------------------------------------------------*/ - -/** - * @brief Status reported from the MQTT publish callback. - */ -static ResponseStatus_t responseStatus; - -/** - * @brief Buffer to hold the provisioned AWS IoT Thing name. - */ -static char thingName[ MAX_THING_NAME_LENGTH ]; - -/** - * @brief Length of the AWS IoT Thing name. - */ -static size_t thingNameLength; - -/** - * @brief Buffer to hold responses received from the AWS IoT Fleet Provisioning - * APIs. When the MQTT publish callback receives an expected Fleet Provisioning - * accepted payload, it copies it into this buffer. - */ -static uint8_t payloadBuffer[ NETWORK_BUFFER_SIZE ]; - -/** - * @brief Length of the payload stored in #payloadBuffer. This is set by the - * MQTT publish callback when it copies a received payload into #payloadBuffer. - */ -static size_t payloadLength; - -/*-----------------------------------------------------------*/ - -/** - * @brief Callback to receive the incoming publish messages from the MQTT - * broker. Sets responseStatus if an expected CreateKeysAndCertificate or - * RegisterThing response is received, and copies the response into - * responseBuffer if the response is an accepted one. - * - * @param[in] pPublishInfo Pointer to publish info of the incoming publish. - * @param[in] packetIdentifier Packet identifier of the incoming publish. - */ -static void provisioningPublishCallback( MQTTPublishInfo_t * pPublishInfo, - uint16_t packetIdentifier ); - -/** - * @brief Run the MQTT process loop to get a response. - */ -static bool waitForResponse( void ); - -/** - * @brief Subscribe to the CreateKeysAndCertificate accepted and rejected topics. - */ -static bool subscribeToKeysCertResponseTopics( void ); - -/** - * @brief Unsubscribe from the CreateKeysAndCertificate accepted and rejected topics. - */ -static bool unsubscribeFromKeysCertResponseTopics( void ); - -/** - * @brief Subscribe to the RegisterThing accepted and rejected topics. - */ -static bool subscribeToRegisterThingResponseTopics( void ); - -/** - * @brief Unsubscribe from the RegisterThing accepted and rejected topics. - */ -static bool unsubscribeFromRegisterThingResponseTopics( void ); - -/*-----------------------------------------------------------*/ - -static void provisioningPublishCallback( MQTTPublishInfo_t * pPublishInfo, - uint16_t packetIdentifier ) -{ - FleetProvisioningStatus_t status; - FleetProvisioningTopic_t api; - const char * cborDump; - - /* Silence compiler warnings about unused variables. */ - ( void ) packetIdentifier; - - status = FleetProvisioning_MatchTopic( pPublishInfo->pTopicName, - pPublishInfo->topicNameLength, &api ); - - if( status != FleetProvisioningSuccess ) - { - LogWarn( ( "Unexpected publish message received. Topic: %.*s.", - ( int ) pPublishInfo->topicNameLength, - ( const char * ) pPublishInfo->pTopicName ) ); - } - else - { - if( api == FleetProvCborCreateKeysAndCertAccepted ) - { - LogInfo( ( "Received accepted response from Fleet Provisioning CreateKeysAndCertificate API." ) ); - - cborDump = getStringFromCbor( ( const uint8_t * ) pPublishInfo->pPayload, pPublishInfo->payloadLength ); - LogDebug( ( "Payload: %s", cborDump ) ); - free( ( void * ) cborDump ); - - responseStatus = ResponseAccepted; - - /* Copy the payload from the MQTT library's buffer to #payloadBuffer. */ - ( void ) memcpy( ( void * ) payloadBuffer, - ( const void * ) pPublishInfo->pPayload, - ( size_t ) pPublishInfo->payloadLength ); - - payloadLength = pPublishInfo->payloadLength; - } - else if( api == FleetProvCborCreateKeysAndCertRejected ) - { - LogError( ( "Received rejected response from Fleet Provisioning CreateKeysAndCertificate API." ) ); - - cborDump = getStringFromCbor( ( const uint8_t * ) pPublishInfo->pPayload, pPublishInfo->payloadLength ); - LogError( ( "Payload: %s", cborDump ) ); - free( ( void * ) cborDump ); - - responseStatus = ResponseRejected; - } - else if( api == FleetProvCborRegisterThingAccepted ) - { - LogInfo( ( "Received accepted response from Fleet Provisioning RegisterThing API." ) ); - - cborDump = getStringFromCbor( ( const uint8_t * ) pPublishInfo->pPayload, pPublishInfo->payloadLength ); - LogDebug( ( "Payload: %s", cborDump ) ); - free( ( void * ) cborDump ); - - responseStatus = ResponseAccepted; - - /* Copy the payload from the MQTT library's buffer to #payloadBuffer. */ - ( void ) memcpy( ( void * ) payloadBuffer, - ( const void * ) pPublishInfo->pPayload, - ( size_t ) pPublishInfo->payloadLength ); - - payloadLength = pPublishInfo->payloadLength; - } - else if( api == FleetProvCborRegisterThingRejected ) - { - LogError( ( "Received rejected response from Fleet Provisioning RegisterThing API." ) ); - - cborDump = getStringFromCbor( ( const uint8_t * ) pPublishInfo->pPayload, pPublishInfo->payloadLength ); - LogError( ( "Payload: %s", cborDump ) ); - free( ( void * ) cborDump ); - - responseStatus = ResponseRejected; - } - else - { - LogError( ( "Received message on unexpected Fleet Provisioning topic. Topic: %.*s.", - ( int ) pPublishInfo->topicNameLength, - ( const char * ) pPublishInfo->pTopicName ) ); - } - } -} -/*-----------------------------------------------------------*/ - -static bool waitForResponse( void ) -{ - bool status = false; - - responseStatus = ResponseNotReceived; - - /* responseStatus is updated from the MQTT publish callback. */ - ( void ) ProcessLoopWithTimeout(); - - if( responseStatus == ResponseNotReceived ) - { - LogError( ( "Timed out waiting for response." ) ); - } - - if( responseStatus == ResponseAccepted ) - { - status = true; - } - - return status; -} -/*-----------------------------------------------------------*/ - -static bool subscribeToKeysCertResponseTopics( void ) -{ - bool status; - - status = SubscribeToTopic( FP_CBOR_CREATE_KEYS_ACCEPTED_TOPIC, - FP_CBOR_CREATE_KEYS_ACCEPTED_LENGTH ); - - if( status == false ) - { - LogError( ( "Failed to subscribe to fleet provisioning topic: %.*s.", - FP_CBOR_CREATE_KEYS_ACCEPTED_LENGTH, - FP_CBOR_CREATE_KEYS_ACCEPTED_TOPIC ) ); - } - - if( status == true ) - { - status = SubscribeToTopic( FP_CBOR_CREATE_KEYS_REJECTED_TOPIC, - FP_CBOR_CREATE_KEYS_REJECTED_LENGTH ); - - if( status == false ) - { - LogError( ( "Failed to subscribe to fleet provisioning topic: %.*s.", - FP_CBOR_CREATE_KEYS_REJECTED_LENGTH, - FP_CBOR_CREATE_KEYS_REJECTED_TOPIC ) ); - } - } - - return status; -} -/*-----------------------------------------------------------*/ - -static bool unsubscribeFromKeysCertResponseTopics( void ) -{ - bool status; - - status = UnsubscribeFromTopic( FP_CBOR_CREATE_KEYS_ACCEPTED_TOPIC, - FP_CBOR_CREATE_KEYS_ACCEPTED_LENGTH ); - - if( status == false ) - { - LogError( ( "Failed to unsubscribe from fleet provisioning topic: %.*s.", - FP_CBOR_CREATE_KEYS_ACCEPTED_LENGTH, - FP_CBOR_CREATE_KEYS_ACCEPTED_TOPIC ) ); - } - - if( status == true ) - { - status = UnsubscribeFromTopic( FP_CBOR_CREATE_KEYS_REJECTED_TOPIC, - FP_CBOR_CREATE_KEYS_REJECTED_LENGTH ); - - if( status == false ) - { - LogError( ( "Failed to unsubscribe from fleet provisioning topic: %.*s.", - FP_CBOR_CREATE_KEYS_REJECTED_LENGTH, - FP_CBOR_CREATE_KEYS_REJECTED_TOPIC ) ); - } - } - - return status; -} -/*-----------------------------------------------------------*/ - -static bool subscribeToRegisterThingResponseTopics( void ) -{ - bool status; - - status = SubscribeToTopic( FP_CBOR_REGISTER_ACCEPTED_TOPIC( PROVISIONING_TEMPLATE_NAME ), - FP_CBOR_REGISTER_ACCEPTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ) ); - - if( status == false ) - { - LogError( ( "Failed to subscribe to fleet provisioning topic: %.*s.", - FP_CBOR_REGISTER_ACCEPTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ), - FP_CBOR_REGISTER_ACCEPTED_TOPIC( PROVISIONING_TEMPLATE_NAME ) ) ); - } - - if( status == true ) - { - status = SubscribeToTopic( FP_CBOR_REGISTER_REJECTED_TOPIC( PROVISIONING_TEMPLATE_NAME ), - FP_CBOR_REGISTER_REJECTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ) ); - - if( status == false ) - { - LogError( ( "Failed to subscribe to fleet provisioning topic: %.*s.", - FP_CBOR_REGISTER_REJECTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ), - FP_CBOR_REGISTER_REJECTED_TOPIC( PROVISIONING_TEMPLATE_NAME ) ) ); - } - } - - return status; -} -/*-----------------------------------------------------------*/ - -static bool unsubscribeFromRegisterThingResponseTopics( void ) -{ - bool status; - - status = UnsubscribeFromTopic( FP_CBOR_REGISTER_ACCEPTED_TOPIC( PROVISIONING_TEMPLATE_NAME ), - FP_CBOR_REGISTER_ACCEPTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ) ); - - if( status == false ) - { - LogError( ( "Failed to unsubscribe from fleet provisioning topic: %.*s.", - FP_CBOR_REGISTER_ACCEPTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ), - FP_CBOR_REGISTER_ACCEPTED_TOPIC( PROVISIONING_TEMPLATE_NAME ) ) ); - } - - if( status == true ) - { - status = UnsubscribeFromTopic( FP_CBOR_REGISTER_REJECTED_TOPIC( PROVISIONING_TEMPLATE_NAME ), - FP_CBOR_REGISTER_REJECTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ) ); - - if( status == false ) - { - LogError( ( "Failed to unsubscribe from fleet provisioning topic: %.*s.", - FP_CBOR_REGISTER_REJECTED_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ), - FP_CBOR_REGISTER_REJECTED_TOPIC( PROVISIONING_TEMPLATE_NAME ) ) ); - } - } - - return status; -} -/*-----------------------------------------------------------*/ - -/* This example uses a single application task, which shows that how to use - * the Fleet Provisioning library to generate and validate AWS IoT Fleet - * Provisioning MQTT topics, and use the coreMQTT library to communicate with - * the AWS IoT Fleet Provisioning APIs. */ -int main( int argc, - char ** argv ) -{ - bool status = false; - /* Buffer for holding received certificate until it is saved. */ - char certificate[ CERT_BUFFER_LENGTH ]; - size_t certificateLength; - /* Buffer for holding received private key until it is saved. */ - char privatekey[ PRIV_KEY_BUFFER_LENGTH ]; - size_t privatekeyLength; - /* Buffer for holding the certificate ID. */ - char certificateId[ CERT_ID_BUFFER_LENGTH ]; - size_t certificateIdLength; - /* Buffer for holding the certificate ownership token. */ - char ownershipToken[ OWNERSHIP_TOKEN_BUFFER_LENGTH ]; - size_t ownershipTokenLength; - bool connectionEstablished = false; - CK_SESSION_HANDLE p11Session; - int demoRunCount = 0; - CK_RV pkcs11ret = CKR_OK; - - /* Silence compiler warnings about unused variables. */ - ( void ) argc; - ( void ) argv; - - do - { - /* Initialize the buffer lengths to their max lengths. */ - certificateLength = CERT_BUFFER_LENGTH; - privatekeyLength = PRIV_KEY_BUFFER_LENGTH; - certificateIdLength = CERT_ID_BUFFER_LENGTH; - ownershipTokenLength = OWNERSHIP_TOKEN_BUFFER_LENGTH; - - /* Initialize the PKCS #11 module */ - pkcs11ret = xInitializePkcs11Session( &p11Session ); - - if( pkcs11ret != CKR_OK ) - { - LogError( ( "Failed to initialize PKCS #11." ) ); - status = false; - } - else - { - /* Insert the claim credentials into the PKCS #11 module */ - status = loadClaimCredentials( p11Session, - CLAIM_CERT_PATH, - pkcs11configLABEL_CLAIM_CERTIFICATE, - CLAIM_PRIVATE_KEY_PATH, - pkcs11configLABEL_CLAIM_PRIVATE_KEY ); - - if( status == false ) - { - LogError( ( "Failed to provision PKCS #11 with claim credentials." ) ); - } - } - - /**** Connect to AWS IoT Core with provisioning claim credentials *****/ - - /* We first use the claim credentials to connect to the broker. These - * credentials should allow use of the RegisterThing API and one of the - * CreateCertificatefromCsr or CreateKeysAndCertificate. - * In this demo we use CreateKeysAndCertificate. */ - - if( status == true ) - { - /* Attempts to connect to the AWS IoT MQTT broker. If the - * connection fails, retries after a timeout. Timeout value will - * exponentially increase until maximum attempts are reached. */ - LogInfo( ( "Establishing MQTT session with claim certificate..." ) ); - status = EstablishMqttSession( provisioningPublishCallback, - p11Session, - pkcs11configLABEL_CLAIM_CERTIFICATE, - pkcs11configLABEL_CLAIM_PRIVATE_KEY ); - - if( status == false ) - { - LogError( ( "Failed to establish MQTT session." ) ); - } - else - { - LogInfo( ( "Established connection with claim credentials." ) ); - connectionEstablished = true; - } - } - - /**** Call the CreateKeysAndCertificate API ***************************/ - - /* We use the CreateKeysAndCertificate API to obtain a client certificate - * and private key. */ - if( status == true ) - { - /* Subscribe to the CreateKeysAndCertificate accepted and rejected - * topics. In this demo we use CBOR encoding for the payloads, - * so we use the CBOR variants of the topics. */ - status = subscribeToKeysCertResponseTopics(); - } - - if( status == true ) - { - /* Publish an empty payload to the CreateKeysAndCertificate API. */ - status = PublishToTopic( FP_CBOR_CREATE_KEYS_PUBLISH_TOPIC, - FP_CBOR_CREATE_KEYS_PUBLISH_LENGTH, - "", - 0 ); - - if( status == false ) - { - LogError( ( "Failed to publish to fleet provisioning topic: %.*s.", - FP_CBOR_CREATE_KEYS_PUBLISH_LENGTH, - FP_CBOR_CREATE_KEYS_PUBLISH_TOPIC ) ); - } - } - - if( status == true ) - { - /* Get the response to the CreateKeysAndCertificate request. */ - status = waitForResponse(); - } - - if( status == true ) - { - /* From the response, extract the certificate, certificate ID, and - * certificate ownership token. */ - status = parseKeyCertResponse( payloadBuffer, - payloadLength, - certificate, - &certificateLength, - privatekey, - &privatekeyLength, - certificateId, - &certificateIdLength, - ownershipToken, - &ownershipTokenLength ); - - if( status == true ) - { - LogInfo( ( "Received privatekey and certificate with Id: %.*s", ( int ) certificateIdLength, certificateId ) ); - } - } - - if( status == true ) - { - /* Save the private key into PKCS #11. */ - status = loadPrivateKey( p11Session, - privatekey, - pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS, - privatekeyLength ); - } - - if( status == true ) - { - /* Save the certificate into PKCS #11. */ - status = loadCertificate( p11Session, - certificate, - pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS, - certificateLength ); - } - - if( status == true ) - { - /* Unsubscribe from the CreateKeysAndCertificate topics. */ - status = unsubscribeFromKeysCertResponseTopics(); - } - - /**** Call the RegisterThing API **************************************/ - - /* We then use the RegisterThing API to activate the received certificate, - * provision AWS IoT resources according to the provisioning template, and - * receive device configuration. */ - if( status == true ) - { - /* Create the request payload to publish to the RegisterThing API. */ - status = generateRegisterThingRequest( payloadBuffer, - NETWORK_BUFFER_SIZE, - ownershipToken, - ownershipTokenLength, - DEVICE_SERIAL_NUMBER, - DEVICE_SERIAL_NUMBER_LENGTH, - &payloadLength ); - } - - if( status == true ) - { - /* Subscribe to the RegisterThing response topics. */ - status = subscribeToRegisterThingResponseTopics(); - } - - if( status == true ) - { - /* Publish the RegisterThing request. */ - status = PublishToTopic( FP_CBOR_REGISTER_PUBLISH_TOPIC( PROVISIONING_TEMPLATE_NAME ), - FP_CBOR_REGISTER_PUBLISH_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ), - ( char * ) payloadBuffer, - payloadLength ); - - if( status == false ) - { - LogError( ( "Failed to publish to fleet provisioning topic: %.*s.", - FP_CBOR_REGISTER_PUBLISH_LENGTH( PROVISIONING_TEMPLATE_NAME_LENGTH ), - FP_CBOR_REGISTER_PUBLISH_TOPIC( PROVISIONING_TEMPLATE_NAME ) ) ); - } - } - - if( status == true ) - { - /* Get the response to the RegisterThing request. */ - status = waitForResponse(); - } - - if( status == true ) - { - /* Extract the Thing name from the response. */ - thingNameLength = MAX_THING_NAME_LENGTH; - status = parseRegisterThingResponse( payloadBuffer, - payloadLength, - thingName, - &thingNameLength ); - - if( status == true ) - { - LogInfo( ( "Received AWS IoT Thing name: %.*s", ( int ) thingNameLength, thingName ) ); - } - } - - if( status == true ) - { - /* Unsubscribe from the RegisterThing topics. */ - unsubscribeFromRegisterThingResponseTopics(); - } - - /**** Disconnect from AWS IoT Core ************************************/ - - /* As we have completed the provisioning workflow, we disconnect from - * the connection using the provisioning claim credentials. We will - * establish a new MQTT connection with the newly provisioned - * credentials. */ - if( connectionEstablished == true ) - { - DisconnectMqttSession(); - connectionEstablished = false; - } - - /**** Connect to AWS IoT Core with provisioned certificate ************/ - - if( status == true ) - { - LogInfo( ( "Establishing MQTT session with provisioned certificate..." ) ); - status = EstablishMqttSession( provisioningPublishCallback, - p11Session, - pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS, - pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS ); - - if( status != true ) - { - LogError( ( "Failed to establish MQTT session with provisioned " - "credentials. Verify on your AWS account that the " - "new certificate is active and has an attached IoT " - "Policy that allows the \"iot:Connect\" action." ) ); - } - else - { - LogInfo( ( "Sucessfully established connection with provisioned credentials." ) ); - connectionEstablished = true; - } - } - - /**** Finish **********************************************************/ - - if( connectionEstablished == true ) - { - /* Close the connection. */ - DisconnectMqttSession(); - connectionEstablished = false; - } - - pkcs11CloseSession( p11Session ); - - /**** Retry in case of failure ****************************************/ - - /* Increment the demo run count. */ - demoRunCount++; - - if( status == true ) - { - LogInfo( ( "Demo iteration %d is successful.", demoRunCount ) ); - } - /* Attempt to retry a failed iteration of demo for up to #FLEET_PROV_MAX_DEMO_LOOP_COUNT times. */ - else if( demoRunCount < FLEET_PROV_MAX_DEMO_LOOP_COUNT ) - { - LogWarn( ( "Demo iteration %d failed. Retrying...", demoRunCount ) ); - sleep( DELAY_BETWEEN_DEMO_RETRY_ITERATIONS_SECONDS ); - } - /* Failed all #FLEET_PROV_MAX_DEMO_LOOP_COUNT demo iterations. */ - else - { - LogError( ( "All %d demo iterations failed.", FLEET_PROV_MAX_DEMO_LOOP_COUNT ) ); - break; - } - } while( status != true ); - - /* Log demo success. */ - if( status == true ) - { - LogInfo( ( "Demo completed successfully." ) ); - - #if defined( DOWNLOADED_CERT_WRITE_PATH ) - { - int fd = open( DOWNLOADED_CERT_WRITE_PATH, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR ); - - if( -1 != fd ) - { - const ssize_t writtenBytes = write( fd, certificate, certificateLength ); - - if( writtenBytes == certificateLength ) - { - LogInfo( ( "Written %s successfully.", DOWNLOADED_CERT_WRITE_PATH ) ); - } - else - { - LogError( ( "Could not write to %s. Error: %s.", DOWNLOADED_CERT_WRITE_PATH, strerror( errno ) ) ); - } - - close( fd ); - } - else - { - LogError( ( "Could not open %s. Error: %s.", DOWNLOADED_CERT_WRITE_PATH, strerror( errno ) ) ); - } - } - #else /* if defined( DOWNLOADED_CERT_WRITE_PATH ) */ - LogInfo( ( "NOTE: define DOWNLOADED_CERT_WRITE_PATH in order to have the certificate written to disk." ) ); - #endif // DOWNLOADED_CERT_WRITE_PATH - - #if defined( DOWNLOADED_PRIVATE_KEY_WRITE_PATH ) - { - int fd = open( DOWNLOADED_PRIVATE_KEY_WRITE_PATH, O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR ); - - if( -1 != fd ) - { - const ssize_t writtenBytes = write( fd, privatekey, privatekeyLength ); - - if( writtenBytes == privatekeyLength ) - { - LogInfo( ( "Written %s successfully.", DOWNLOADED_PRIVATE_KEY_WRITE_PATH ) ); - } - else - { - LogError( ( "Could not write to %s. Error: %s.", DOWNLOADED_PRIVATE_KEY_WRITE_PATH, strerror( errno ) ) ); - } - - close( fd ); - } - else - { - LogError( ( "Could not open %s. Error: %s.", DOWNLOADED_PRIVATE_KEY_WRITE_PATH, strerror( errno ) ) ); - } - } - #else /* if defined( DOWNLOADED_PRIVATE_KEY_WRITE_PATH ) */ - LogInfo( ( "NOTE: define DOWNLOADED_PRIVATE_KEY_WRITE_PATH in order to have the private key written to disk." ) ); - #endif // DOWNLOADED_PRIVATE_KEY_WRITE_PATH - } - - return ( status == true ) ? EXIT_SUCCESS : EXIT_FAILURE; -} -/*-----------------------------------------------------------*/ diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_serializer.c b/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_serializer.c deleted file mode 100644 index b3f1e9fab6..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_serializer.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* Standard includes */ -#include - -/* TinyCBOR library for CBOR encoding and decoding operations. */ -#include "cbor.h" - -/* Demo config. */ -#include "demo_config.h" - -/* AWS IoT Fleet Provisioning Library. */ -#include "fleet_provisioning.h" - -/* Header include. */ -#include "fleet_provisioning_serializer.h" - -/*-----------------------------------------------------------*/ - -/** - * @brief Context passed to tinyCBOR for #cborPrinter. Initial - * state should be zeroed. - */ -typedef struct -{ - const char * str; - size_t length; -} CborPrintContext_t; - -/*-----------------------------------------------------------*/ - -/** - * @brief Printing function to pass to tinyCBOR. - * - * cbor_value_to_pretty_stream calls it multiple times to print a textual CBOR - * representation. - * - * @param token Context for the function. - * @param fmt Printf style format string. - * @param ... Printf style args after format string. - */ -static CborError cborPrinter( void * token, - const char * fmt, - ... ); - -/*-----------------------------------------------------------*/ - -bool generateRegisterThingRequest( uint8_t * pBuffer, - size_t bufferLength, - const char * pCertificateOwnershipToken, - size_t certificateOwnershipTokenLength, - const char * pSerial, - size_t serialLength, - size_t * pOutLengthWritten ) -{ - CborEncoder encoder, mapEncoder, parametersEncoder; - CborError cborRet; - - assert( pBuffer != NULL ); - assert( pCertificateOwnershipToken != NULL ); - assert( pSerial != NULL ); - assert( pOutLengthWritten != NULL ); - - /* For details on the RegisterThing request payload format, see: - * https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#register-thing-request-payload - */ - cbor_encoder_init( &encoder, pBuffer, bufferLength, 0 ); - /* The RegisterThing request payload is a map with two keys. */ - cborRet = cbor_encoder_create_map( &encoder, &mapEncoder, 2 ); - - if( cborRet == CborNoError ) - { - cborRet = cbor_encode_text_stringz( &mapEncoder, "certificateOwnershipToken" ); - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_encode_text_string( &mapEncoder, pCertificateOwnershipToken, certificateOwnershipTokenLength ); - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_encode_text_stringz( &mapEncoder, "parameters" ); - } - - if( cborRet == CborNoError ) - { - /* Parameters in this example is length 1. */ - cborRet = cbor_encoder_create_map( &mapEncoder, ¶metersEncoder, 1 ); - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_encode_text_stringz( ¶metersEncoder, "SerialNumber" ); - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_encode_text_string( ¶metersEncoder, pSerial, serialLength ); - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_encoder_close_container( &mapEncoder, ¶metersEncoder ); - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_encoder_close_container( &encoder, &mapEncoder ); - } - - if( cborRet == CborNoError ) - { - *pOutLengthWritten = cbor_encoder_get_buffer_size( &encoder, ( uint8_t * ) pBuffer ); - } - else - { - LogError( ( "Error during CBOR encoding: %s", cbor_error_string( cborRet ) ) ); - - if( ( cborRet & CborErrorOutOfMemory ) != 0 ) - { - LogError( ( "Cannot fit RegisterThing request payload into buffer." ) ); - } - } - - return( cborRet == CborNoError ); -} -/*-----------------------------------------------------------*/ - -bool parseKeyCertResponse( const uint8_t * pResponse, - size_t length, - char * pCertificateBuffer, - size_t * pCertificateBufferLength, - char * pPrivateKeyBuffer, - size_t * pPrivateKeyBufferLength, - char * pCertificateIdBuffer, - size_t * pCertificateIdBufferLength, - char * pOwnershipTokenBuffer, - size_t * pOwnershipTokenBufferLength ) -{ - CborError cborRet; - CborParser parser; - CborValue map; - CborValue value; - - assert( pResponse != NULL ); - assert( pCertificateBuffer != NULL ); - assert( pCertificateBufferLength != NULL ); - assert( pPrivateKeyBuffer != NULL ); - assert( pPrivateKeyBufferLength != NULL ); - assert( pCertificateIdBuffer != NULL ); - assert( pCertificateIdBufferLength != NULL ); - assert( *pCertificateIdBufferLength >= 64 ); - assert( pOwnershipTokenBuffer != NULL ); - assert( pOwnershipTokenBufferLength != NULL ); - - /* For details on the CreateCertificatefromCsr response payload format, see: - * https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#register-thing-response-payload - */ - cborRet = cbor_parser_init( pResponse, length, 0, &parser, &map ); - - if( cborRet != CborNoError ) - { - LogError( ( "Error initializing parser for CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - else if( !cbor_value_is_map( &map ) ) - { - LogError( ( "CreateKeysAndCertificate response is not a valid map container type." ) ); - } - else - { - cborRet = cbor_value_map_find_value( &map, "certificatePem", &value ); - - if( cborRet != CborNoError ) - { - LogError( ( "Error searching CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - else if( value.type == CborInvalidType ) - { - LogError( ( "\"certificatePem\" not found in CreateKeysAndCertificate response." ) ); - } - else if( value.type != CborTextStringType ) - { - LogError( ( "Value for \"certificatePem\" key in CreateKeysAndCertificate response is not a text string type." ) ); - } - else - { - cborRet = cbor_value_copy_text_string( &value, pCertificateBuffer, pCertificateBufferLength, NULL ); - - if( cborRet == CborErrorOutOfMemory ) - { - size_t requiredLen = 0; - ( void ) cbor_value_calculate_string_length( &value, &requiredLen ); - LogError( ( "Certificate buffer insufficiently large. Certificate length: %lu", ( unsigned long ) requiredLen ) ); - } - else if( cborRet != CborNoError ) - { - LogError( ( "Failed to parse \"certificatePem\" value from CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - } - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_value_map_find_value( &map, "certificateId", &value ); - - if( cborRet != CborNoError ) - { - LogError( ( "Error searching CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - else if( value.type == CborInvalidType ) - { - LogError( ( "\"certificateId\" not found in CreateKeysAndCertificate response." ) ); - } - else if( value.type != CborTextStringType ) - { - LogError( ( "\"certificateId\" is an unexpected type in CreateKeysAndCertificate response." ) ); - } - else - { - cborRet = cbor_value_copy_text_string( &value, pCertificateIdBuffer, pCertificateIdBufferLength, NULL ); - - if( cborRet == CborErrorOutOfMemory ) - { - size_t requiredLen = 0; - ( void ) cbor_value_calculate_string_length( &value, &requiredLen ); - LogError( ( "Certificate ID buffer insufficiently large. Certificate ID length: %lu", ( unsigned long ) requiredLen ) ); - } - else if( cborRet != CborNoError ) - { - LogError( ( "Failed to parse \"certificateId\" value from CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - } - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_value_map_find_value( &map, "privateKey", &value ); - - if( cborRet != CborNoError ) - { - LogError( ( "Error searching CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - else if( value.type == CborInvalidType ) - { - LogError( ( "\"privateKey\" not found in CreateKeysAndCertificate response." ) ); - } - else if( value.type != CborTextStringType ) - { - LogError( ( "\"privateKey\" is an unexpected type in CreateKeysAndCertificate response." ) ); - } - else - { - cborRet = cbor_value_copy_text_string( &value, pPrivateKeyBuffer, pPrivateKeyBufferLength, NULL ); - - if( cborRet == CborErrorOutOfMemory ) - { - size_t requiredLen = 0; - ( void ) cbor_value_calculate_string_length( &value, &requiredLen ); - LogError( ( "Certificate ID buffer insufficiently large. Certificate ID length: %lu", ( unsigned long ) requiredLen ) ); - } - else if( cborRet != CborNoError ) - { - LogError( ( "Failed to parse \"certificateId\" value from CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - } - } - - if( cborRet == CborNoError ) - { - cborRet = cbor_value_map_find_value( &map, "certificateOwnershipToken", &value ); - - if( cborRet != CborNoError ) - { - LogError( ( "Error searching CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - else if( value.type == CborInvalidType ) - { - LogError( ( "\"certificateOwnershipToken\" not found in CreateKeysAndCertificate response." ) ); - } - else if( value.type != CborTextStringType ) - { - LogError( ( "\"certificateOwnershipToken\" is an unexpected type in CreateKeysAndCertificate response." ) ); - } - else - { - cborRet = cbor_value_copy_text_string( &value, pOwnershipTokenBuffer, pOwnershipTokenBufferLength, NULL ); - - if( cborRet == CborErrorOutOfMemory ) - { - size_t requiredLen = 0; - ( void ) cbor_value_calculate_string_length( &value, &requiredLen ); - LogError( ( "Certificate ownership token buffer insufficiently large. Certificate ownership token buffer length: %lu", ( unsigned long ) requiredLen ) ); - } - else if( cborRet != CborNoError ) - { - LogError( ( "Failed to parse \"certificateOwnershipToken\" value from CreateKeysAndCertificate response: %s.", cbor_error_string( cborRet ) ) ); - } - } - } - - return( cborRet == CborNoError ); -} -/*-----------------------------------------------------------*/ - -bool parseRegisterThingResponse( const uint8_t * pResponse, - size_t length, - char * pThingNameBuffer, - size_t * pThingNameBufferLength ) -{ - CborError cborRet; - CborParser parser; - CborValue map; - CborValue value; - - assert( pResponse != NULL ); - assert( pThingNameBuffer != NULL ); - assert( pThingNameBufferLength != NULL ); - - /* For details on the RegisterThing response payload format, see: - * https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#register-thing-response-payload - */ - cborRet = cbor_parser_init( pResponse, length, 0, &parser, &map ); - - if( cborRet != CborNoError ) - { - LogError( ( "Error initializing parser for RegisterThing response: %s.", cbor_error_string( cborRet ) ) ); - } - else if( !cbor_value_is_map( &map ) ) - { - LogError( ( "RegisterThing response not a map type." ) ); - } - else - { - cborRet = cbor_value_map_find_value( &map, "thingName", &value ); - - if( cborRet != CborNoError ) - { - LogError( ( "Error searching RegisterThing response: %s.", cbor_error_string( cborRet ) ) ); - } - else if( value.type == CborInvalidType ) - { - LogError( ( "\"thingName\" not found in RegisterThing response." ) ); - } - else if( value.type != CborTextStringType ) - { - LogError( ( "\"thingName\" is an unexpected type in RegisterThing response." ) ); - } - else - { - cborRet = cbor_value_copy_text_string( &value, pThingNameBuffer, pThingNameBufferLength, NULL ); - - if( cborRet == CborErrorOutOfMemory ) - { - size_t requiredLen = 0; - ( void ) cbor_value_calculate_string_length( &value, &requiredLen ); - LogError( ( "Thing name buffer insufficiently large. Thing name length: %lu", ( unsigned long ) requiredLen ) ); - } - else if( cborRet != CborNoError ) - { - LogError( ( "Failed to parse \"thingName\" value from RegisterThing response: %s.", cbor_error_string( cborRet ) ) ); - } - } - } - - return( cborRet == CborNoError ); -} -/*-----------------------------------------------------------*/ - -static CborError cborPrinter( void * token, - const char * fmt, - ... ) -{ - int result; - va_list args; - CborPrintContext_t * ctx = ( CborPrintContext_t * ) token; - - va_start( args, fmt ); - - /* Compute length to write. */ - result = vsnprintf( NULL, 0, fmt, args ); - - va_end( args ); - - if( result < 0 ) - { - LogError( ( "Error formatting CBOR string." ) ); - } - else - { - size_t newLen = ( unsigned ) result; - size_t oldLen = ctx->length; - char * newPtr; - - ctx->length = oldLen + newLen; - newPtr = ( char * ) realloc( ( void * ) ctx->str, ctx->length + 1 ); - - if( newPtr == NULL ) - { - LogError( ( "Failed to reallocate CBOR string." ) ); - result = -1; - } - else - { - va_start( args, fmt ); - - result = vsnprintf( newPtr + oldLen, newLen + 1, fmt, args ); - - va_end( args ); - - ctx->str = newPtr; - - if( result < 0 ) - { - LogError( ( "Error printing CBOR string." ) ); - } - } - } - - return ( result < 0 ) ? CborErrorIO : CborNoError; -} -/*-----------------------------------------------------------*/ - -const char * getStringFromCbor( const uint8_t * cbor, - size_t length ) -{ - CborPrintContext_t printCtx = { 0 }; - CborParser parser; - CborValue value; - CborError error; - - error = cbor_parser_init( cbor, length, 0, &parser, &value ); - - if( error == CborNoError ) - { - error = cbor_value_to_pretty_stream( cborPrinter, &printCtx, &value, CborPrettyDefaultFlags ); - } - - if( error != CborNoError ) - { - LogError( ( "Error printing CBOR payload." ) ); - printCtx.str = ""; - } - - return printCtx.str; -} -/*-----------------------------------------------------------*/ diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_serializer.h b/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_serializer.h deleted file mode 100644 index c47dc9cfe0..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/fleet_provisioning_serializer.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/** - * This file declares functions for serializing and parsing CBOR encoded Fleet - * Provisioning API payloads. - */ - -/* Standard includes. */ -#include -#include -#include - -/** - * @brief Creates the request payload to be published to the RegisterThing API - * in order to activate the provisioned certificate and receive a Thing name. - * - * @param[in] pBuffer Buffer into which to write the publish request payload. - * @param[in] bufferLength Length of #buffer. - * @param[in] pCertificateOwnershipToken The certificate's certificate - * ownership token. - * @param[in] certificateOwnershipTokenLength Length of - * #certificateOwnershipToken. - * @param[out] pOutLengthWritten The length of the publish request payload. - */ -bool generateRegisterThingRequest( uint8_t * pBuffer, - size_t bufferLength, - const char * pCertificateOwnershipToken, - size_t certificateOwnershipTokenLength, - const char * pSerial, - size_t serialLength, - size_t * pOutLengthWritten ); - -/** - * @brief Extracts the certificate, certificate ID, and certificate ownership - * token from a CreateCertificateFromCsr accepted response. These are copied - * to the provided buffers so that they can outlive the data in the response - * buffer and as CBOR strings may be chunked. - * - * @param[in] pResponse The response payload. - * @param[in] length Length of #pResponse. - * @param[in] pCertificateBuffer The buffer to which to write the certificate. - * @param[in,out] pCertificateBufferLength The length of #pCertificateBuffer. - * The length written is output here. - * @param[in] pCertificateIdBuffer The buffer to which to write the certificate - * ID. - * @param[in,out] pCertificateIdBufferLength The length of - * #pCertificateIdBuffer. The length written is output here. - * @param[in] pOwnershipTokenBuffer The buffer to which to write the - * certificate ownership token. - * @param[in,out] pOwnershipTokenBufferLength The length of - * #pOwnershipTokenBuffer. The length written is output here. - */ -bool parseKeyCertResponse( const uint8_t * pResponse, - size_t length, - char * pCertificateBuffer, - size_t * pCertificateBufferLength, - char * pPrivateKeyBuffer, - size_t * pPrivateKeyBufferLength, - char * pCertificateIdBuffer, - size_t * pCertificateIdBufferLength, - char * pOwnershipTokenBuffer, - size_t * pOwnershipTokenBufferLength ); - -/** - * @brief Extracts the Thing name from a RegisterThing accepted response. - * - * @param[in] pResponse The response document. - * @param[in] length Length of #pResponse. - * @param[in] pThingNameBuffer The buffer to which to write the Thing name. - * @param[in,out] pThingNameBufferLength The length of #pThingNameBuffer. The - * written length is output here. - */ -bool parseRegisterThingResponse( const uint8_t * pResponse, - size_t length, - char * pThingNameBuffer, - size_t * pThingNameBufferLength ); - -/** - * @brief Converts a CBOR document into a pretty printed string. - * - * @param[in] cbor The CBOR document. - * @param[in] length The length of the CBOR document. - * - * @returns The pretty printed string on success. "" on error. - */ -const char * getStringFromCbor( const uint8_t * cbor, - size_t length ); diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/pkcs11_operations.c b/demos/fleet_provisioning/fleet_provisioning_keys_cert/pkcs11_operations.c deleted file mode 100644 index a8a853225c..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/pkcs11_operations.c +++ /dev/null @@ -1,797 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * @file pkcs11_operations.c - * - * @brief This file provides wrapper functions for PKCS11 operations. - */ - -/* Standard includes. */ -#include -#include - -/* Config include. */ -#include "demo_config.h" - -/* Interface include. */ -#include "pkcs11_operations.h" - -/* PKCS #11 include. */ -#include "core_pkcs11_config.h" -#include "core_pki_utils.h" -#include "mbedtls_utils.h" - -/* MbedTLS include. */ -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/entropy.h" -#include "mbedtls/entropy_poll.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/pk.h" -#include "mbedtls/pk_internal.h" -#include "mbedtls/sha256.h" -#include "mbedtls/x509_crt.h" -#include "mbedtls/x509_csr.h" - -/** - * @brief Size of buffer in which to hold the certificate signing request (CSR). - */ -#define CLAIM_CERT_BUFFER_LENGTH 2048 - -/** - * @brief Size of buffer in which to hold the certificate signing request (CSR). - */ -#define CLAIM_PRIVATE_KEY_BUFFER_LENGTH 2048 - -/* Length parameters for importing RSA-2048 private keys. */ -#define MODULUS_LENGTH pkcs11RSA_2048_MODULUS_BITS / 8 -#define E_LENGTH 3 -#define D_LENGTH pkcs11RSA_2048_MODULUS_BITS / 8 -#define PRIME_1_LENGTH 128 -#define PRIME_2_LENGTH 128 -#define EXPONENT_1_LENGTH 128 -#define EXPONENT_2_LENGTH 128 -#define COEFFICIENT_LENGTH 128 - -#define EC_PARAMS_LENGTH 10 -#define EC_D_LENGTH 32 - -/** - * @brief Struct for holding parsed RSA-2048 private keys. - */ -typedef struct RsaParams_t -{ - CK_BYTE modulus[ MODULUS_LENGTH + 1 ]; - CK_BYTE e[ E_LENGTH + 1 ]; - CK_BYTE d[ D_LENGTH + 1 ]; - CK_BYTE prime1[ PRIME_1_LENGTH + 1 ]; - CK_BYTE prime2[ PRIME_2_LENGTH + 1 ]; - CK_BYTE exponent1[ EXPONENT_1_LENGTH + 1 ]; - CK_BYTE exponent2[ EXPONENT_2_LENGTH + 1 ]; - CK_BYTE coefficient[ COEFFICIENT_LENGTH + 1 ]; -} RsaParams_t; - -/** - * @brief Struct containing parameters needed by the signing callback. - */ -typedef struct SigningCallbackContext -{ - CK_SESSION_HANDLE p11Session; - CK_OBJECT_HANDLE p11PrivateKey; -} SigningCallbackContext_t; - -/*-----------------------------------------------------------*/ - -/** - * @brief Reads a file into the given buffer. - * - * @param[in] path Path of the file. - * @param[out] pBuffer Buffer to read file contents into. - * @param[in] bufferLength Length of #pBuffer. - * @param[out] pOutWrittenLength Length of contents written to #pBuffer. - */ -static bool readFile( const char * path, - char * pBuffer, - size_t bufferLength, - size_t * pOutWrittenLength ); - -/** - * @brief Delete the specified crypto object from storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] pkcsLabelsPtr The list of labels to remove. - * @param[in] pClass The list of corresponding classes. - * @param[in] count The length of #pkcsLabelsPtr and #pClass. - */ -static CK_RV destroyProvidedObjects( CK_SESSION_HANDLE session, - CK_BYTE_PTR * pkcsLabelsPtr, - CK_OBJECT_CLASS * pClass, - CK_ULONG count ); - - -/** - * @brief Import the specified ECDSA private key into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] label The label to store the key. - * @param[in] mbedPkContext The private key to store. - */ -static CK_RV provisionPrivateECKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ); - - - -/** - * @brief Import the specified RSA private key into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] label The label to store the key. - * @param[in] mbedPkContext The private key to store. - */ -static CK_RV provisionPrivateRSAKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ); - - -/** - * @brief Import the specified private key into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] privateKey The private key to store, in PEM format. - * @param[in] privateKeyLength The length of the key, including null terminator. - * @param[in] label The label to store the key. - */ -static CK_RV provisionPrivateKey( CK_SESSION_HANDLE session, - const char * privateKey, - size_t privateKeyLength, - const char * label ); - -/** - * @brief Import the specified X.509 client certificate into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] certificate The certificate to store, in PEM format. - * @param[in] certificateLength The length of the certificate, including the null terminator. - * @param[in] label The label to store the certificate. - */ -static CK_RV provisionCertificate( CK_SESSION_HANDLE session, - const char * certificate, - size_t certificateLength, - const char * label ); - -/*-----------------------------------------------------------*/ - -static bool readFile( const char * path, - char * pBuffer, - size_t bufferLength, - size_t * pOutWrittenLength ) -{ - FILE * file; - size_t length = 0; - bool status = true; - - /* Get the file descriptor for the CSR file. */ - file = fopen( path, "rb" ); - - if( file == NULL ) - { - LogError( ( "Error opening file at path: %s. Error: %s.", - path, strerror( errno ) ) ); - status = false; - } - else - { - int result; - /* Seek to the end of the file, so that we can get the file size. */ - result = fseek( file, 0L, SEEK_END ); - - if( result == -1 ) - { - LogError( ( "Failed while moving to end of file. Path: %s. Error: %s.", - path, strerror( errno ) ) ); - status = false; - } - else - { - long lenResult = -1; - /* Get the current position which is the file size. */ - lenResult = ftell( file ); - - if( lenResult == -1 ) - { - LogError( ( "Failed to get length of file. Path: %s. Error: %s.", path, - strerror( errno ) ) ); - status = false; - } - else - { - length = ( size_t ) lenResult; - } - } - - if( status == true ) - { - if( length > bufferLength ) - { - LogError( ( "Buffer too small for file. Buffer size: %ld. Required size: %ld.", - bufferLength, length ) ); - status = false; - } - } - - if( status == true ) - { - /* Return to the beginning of the file. */ - result = fseek( file, 0L, SEEK_SET ); - - if( result == -1 ) - { - LogError( ( "Failed to move to beginning of file. Path: %s. Error: %s.", - path, strerror( errno ) ) ); - status = false; - } - } - - if( status == true ) - { - size_t written = 0; - /* Read the CSR into our buffer. */ - written = fread( pBuffer, 1, length, file ); - - if( written != length ) - { - LogError( ( "Failed reading file. Path: %s. Error: %s.", path, - strerror( errno ) ) ); - status = false; - } - else - { - *pOutWrittenLength = length; - } - } - - fclose( file ); - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static CK_RV destroyProvidedObjects( CK_SESSION_HANDLE session, - CK_BYTE_PTR * pkcsLabelsPtr, - CK_OBJECT_CLASS * pClass, - CK_ULONG count ) -{ - CK_RV result; - CK_FUNCTION_LIST_PTR functionList; - CK_OBJECT_HANDLE objectHandle; - CK_BYTE * labelPtr; - CK_ULONG index = 0; - - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - for( index = 0; index < count; index++ ) - { - labelPtr = pkcsLabelsPtr[ index ]; - - result = xFindObjectWithLabelAndClass( session, ( char * ) labelPtr, - strlen( ( char * ) labelPtr ), - pClass[ index ], &objectHandle ); - - while( ( result == CKR_OK ) && ( objectHandle != CK_INVALID_HANDLE ) ) - { - result = functionList->C_DestroyObject( session, objectHandle ); - - /* PKCS #11 allows a module to maintain multiple objects with the same - * label and type. The intent of this loop is to try to delete all of - * them. However, to avoid getting stuck, we won't try to find another - * object of the same label/type if the previous delete failed. */ - if( result == CKR_OK ) - { - result = xFindObjectWithLabelAndClass( session, ( char * ) labelPtr, - strlen( ( char * ) labelPtr ), - pClass[ index ], &objectHandle ); - } - else - { - break; - } - } - } - } - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionPrivateECKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ) -{ - CK_RV result = CKR_OK; - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_BYTE * DPtr = NULL; /* Private value D. */ - CK_BYTE * ecParamsPtr = NULL; /* DER-encoding of an ANSI X9.62 Parameters value */ - int mbedResult = 0; - CK_BBOOL trueObject = CK_TRUE; - CK_KEY_TYPE privateKeyType = CKK_EC; - CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY; - CK_OBJECT_HANDLE objectHandle = CK_INVALID_HANDLE; - mbedtls_ecp_keypair * keyPair = ( mbedtls_ecp_keypair * ) mbedPkContext->pk_ctx; - - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - DPtr = ( CK_BYTE * ) malloc( EC_D_LENGTH ); - - if( DPtr == NULL ) - { - result = CKR_HOST_MEMORY; - } - } - - if( result == CKR_OK ) - { - mbedResult = mbedtls_mpi_write_binary( &( keyPair->d ), DPtr, EC_D_LENGTH ); - - if( mbedResult != 0 ) - { - LogError( ( "Failed to parse EC private key components." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - } - - if( result == CKR_OK ) - { - if( keyPair->grp.id == MBEDTLS_ECP_DP_SECP256R1 ) - { - ecParamsPtr = ( CK_BYTE * ) ( "\x06\x08" MBEDTLS_OID_EC_GRP_SECP256R1 ); - } - else - { - result = CKR_CURVE_NOT_SUPPORTED; - } - } - - if( result == CKR_OK ) - { - CK_ATTRIBUTE privateKeyTemplate[] = - { - { CKA_CLASS, NULL /* &privateKeyClass*/, sizeof( CK_OBJECT_CLASS ) }, - { CKA_KEY_TYPE, NULL /* &privateKeyType*/, sizeof( CK_KEY_TYPE ) }, - { CKA_LABEL, ( void * ) label, ( CK_ULONG ) strlen( label ) }, - { CKA_TOKEN, NULL /* &trueObject*/, sizeof( CK_BBOOL ) }, - { CKA_SIGN, NULL /* &trueObject*/, sizeof( CK_BBOOL ) }, - { CKA_EC_PARAMS, NULL /* ecParamsPtr*/, EC_PARAMS_LENGTH }, - { CKA_VALUE, NULL /* DPtr*/, EC_D_LENGTH } - }; - - /* Aggregate initializers must not use the address of an automatic variable. */ - privateKeyTemplate[ 0 ].pValue = &privateKeyClass; - privateKeyTemplate[ 1 ].pValue = &privateKeyType; - privateKeyTemplate[ 3 ].pValue = &trueObject; - privateKeyTemplate[ 4 ].pValue = &trueObject; - privateKeyTemplate[ 5 ].pValue = ecParamsPtr; - privateKeyTemplate[ 6 ].pValue = DPtr; - - result = functionList->C_CreateObject( session, - ( CK_ATTRIBUTE_PTR ) &privateKeyTemplate, - sizeof( privateKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - &objectHandle ); - } - - if( DPtr != NULL ) - { - free( DPtr ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionPrivateRSAKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ) -{ - CK_RV result = CKR_OK; - CK_FUNCTION_LIST_PTR functionList = NULL; - int mbedResult = 0; - CK_KEY_TYPE privateKeyType = CKK_RSA; - mbedtls_rsa_context * rsaContext = ( mbedtls_rsa_context * ) mbedPkContext->pk_ctx; - CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY; - RsaParams_t * rsaParams = NULL; - CK_BBOOL trueObject = CK_TRUE; - CK_OBJECT_HANDLE objectHandle = CK_INVALID_HANDLE; - - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - rsaParams = ( RsaParams_t * ) malloc( sizeof( RsaParams_t ) ); - - if( rsaParams == NULL ) - { - result = CKR_HOST_MEMORY; - } - } - - if( result == CKR_OK ) - { - memset( rsaParams, 0, sizeof( RsaParams_t ) ); - - mbedResult = mbedtls_rsa_export_raw( rsaContext, - rsaParams->modulus, MODULUS_LENGTH + 1, - rsaParams->prime1, PRIME_1_LENGTH + 1, - rsaParams->prime2, PRIME_2_LENGTH + 1, - rsaParams->d, D_LENGTH + 1, - rsaParams->e, E_LENGTH + 1 ); - - if( mbedResult != 0 ) - { - LogError( ( "Failed to parse RSA private key components." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* Export Exponent 1, Exponent 2, Coefficient. */ - mbedResult |= mbedtls_mpi_write_binary( ( mbedtls_mpi const * ) &rsaContext->DP, rsaParams->exponent1, EXPONENT_1_LENGTH + 1 ); - mbedResult |= mbedtls_mpi_write_binary( ( mbedtls_mpi const * ) &rsaContext->DQ, rsaParams->exponent2, EXPONENT_2_LENGTH + 1 ); - mbedResult |= mbedtls_mpi_write_binary( ( mbedtls_mpi const * ) &rsaContext->QP, rsaParams->coefficient, COEFFICIENT_LENGTH + 1 ); - - if( mbedResult != 0 ) - { - LogError( ( "Failed to parse RSA private key Chinese Remainder Theorem variables." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - } - - if( result == CKR_OK ) - { - /* When importing the fields, the pointer is incremented by 1 - * to remove the leading 0 padding (if it existed) and the original field - * length is used */ - - CK_ATTRIBUTE privateKeyTemplate[] = - { - { CKA_CLASS, NULL /* &privateKeyClass */, sizeof( CK_OBJECT_CLASS ) }, - { CKA_KEY_TYPE, NULL /* &privateKeyType */, sizeof( CK_KEY_TYPE ) }, - { CKA_LABEL, ( void * ) label, ( CK_ULONG ) strlen( label ) }, - { CKA_TOKEN, NULL /* &trueObject */, sizeof( CK_BBOOL ) }, - { CKA_SIGN, NULL /* &trueObject */, sizeof( CK_BBOOL ) }, - { CKA_MODULUS, rsaParams->modulus + 1, MODULUS_LENGTH }, - { CKA_PRIVATE_EXPONENT, rsaParams->d + 1, D_LENGTH }, - { CKA_PUBLIC_EXPONENT, rsaParams->e + 1, E_LENGTH }, - { CKA_PRIME_1, rsaParams->prime1 + 1, PRIME_1_LENGTH }, - { CKA_PRIME_2, rsaParams->prime2 + 1, PRIME_2_LENGTH }, - { CKA_EXPONENT_1, rsaParams->exponent1 + 1, EXPONENT_1_LENGTH }, - { CKA_EXPONENT_2, rsaParams->exponent2 + 1, EXPONENT_2_LENGTH }, - { CKA_COEFFICIENT, rsaParams->coefficient + 1, COEFFICIENT_LENGTH } - }; - - /* Aggregate initializers must not use the address of an automatic variable. */ - privateKeyTemplate[ 0 ].pValue = &privateKeyClass; - privateKeyTemplate[ 1 ].pValue = &privateKeyType; - privateKeyTemplate[ 3 ].pValue = &trueObject; - privateKeyTemplate[ 4 ].pValue = &trueObject; - - result = functionList->C_CreateObject( session, - ( CK_ATTRIBUTE_PTR ) &privateKeyTemplate, - sizeof( privateKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - &objectHandle ); - } - - if( NULL != rsaParams ) - { - free( rsaParams ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionPrivateKey( CK_SESSION_HANDLE session, - const char * privateKey, - size_t privateKeyLength, - const char * label ) -{ - CK_RV result = CKR_OK; - mbedtls_pk_type_t mbedKeyType = MBEDTLS_PK_NONE; - int mbedResult = 0; - mbedtls_pk_context mbedPkContext = { 0 }; - - mbedtls_pk_init( &mbedPkContext ); - mbedResult = mbedtls_pk_parse_key( &mbedPkContext, ( const uint8_t * ) privateKey, - privateKeyLength, NULL, 0 ); - - if( mbedResult != 0 ) - { - LogError( ( "Unable to parse private key." ) ); - result = CKR_ARGUMENTS_BAD; - } - - /* Determine whether the key to be imported is RSA or EC. */ - if( result == CKR_OK ) - { - mbedKeyType = mbedtls_pk_get_type( &mbedPkContext ); - - if( mbedKeyType == MBEDTLS_PK_RSA ) - { - result = provisionPrivateRSAKey( session, label, &mbedPkContext ); - } - else if( ( mbedKeyType == MBEDTLS_PK_ECDSA ) || - ( mbedKeyType == MBEDTLS_PK_ECKEY ) || - ( mbedKeyType == MBEDTLS_PK_ECKEY_DH ) ) - { - result = provisionPrivateECKey( session, label, &mbedPkContext ); - } - else - { - LogError( ( "Invalid private key type provided. Only RSA-2048 and " - "EC P-256 keys are supported." ) ); - result = CKR_ARGUMENTS_BAD; - } - } - - mbedtls_pk_free( &mbedPkContext ); - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionCertificate( CK_SESSION_HANDLE session, - const char * certificate, - size_t certificateLength, - const char * label ) -{ - PKCS11_CertificateTemplate_t certificateTemplate; - CK_OBJECT_CLASS certificateClass = CKO_CERTIFICATE; - CK_CERTIFICATE_TYPE certificateType = CKC_X_509; - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_RV result = CKR_OK; - uint8_t * derObject = NULL; - int32_t conversion = 0; - size_t derLen = 0; - CK_BBOOL tokenStorage = CK_TRUE; - CK_BYTE subject[] = "TestSubject"; - CK_OBJECT_HANDLE objectHandle = CK_INVALID_HANDLE; - - /* Initialize the client certificate template. */ - certificateTemplate.xObjectClass.type = CKA_CLASS; - certificateTemplate.xObjectClass.pValue = &certificateClass; - certificateTemplate.xObjectClass.ulValueLen = sizeof( certificateClass ); - certificateTemplate.xSubject.type = CKA_SUBJECT; - certificateTemplate.xSubject.pValue = subject; - certificateTemplate.xSubject.ulValueLen = strlen( ( const char * ) subject ); - certificateTemplate.xValue.type = CKA_VALUE; - certificateTemplate.xValue.pValue = ( CK_VOID_PTR ) certificate; - certificateTemplate.xValue.ulValueLen = ( CK_ULONG ) certificateLength; - certificateTemplate.xLabel.type = CKA_LABEL; - certificateTemplate.xLabel.pValue = ( CK_VOID_PTR ) label; - certificateTemplate.xLabel.ulValueLen = strlen( label ); - certificateTemplate.xCertificateType.type = CKA_CERTIFICATE_TYPE; - certificateTemplate.xCertificateType.pValue = &certificateType; - certificateTemplate.xCertificateType.ulValueLen = sizeof( CK_CERTIFICATE_TYPE ); - certificateTemplate.xTokenObject.type = CKA_TOKEN; - certificateTemplate.xTokenObject.pValue = &tokenStorage; - certificateTemplate.xTokenObject.ulValueLen = sizeof( tokenStorage ); - - if( certificate == NULL ) - { - LogError( ( "Certificate cannot be null." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - - if( result == CKR_OK ) - { - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - } - - if( result == CKR_OK ) - { - /* Convert the certificate to DER format from PEM. The DER key should - * be about 3/4 the size of the PEM key, so mallocing the PEM key size - * is sufficient. */ - derObject = ( uint8_t * ) malloc( certificateTemplate.xValue.ulValueLen ); - derLen = certificateTemplate.xValue.ulValueLen; - - if( derObject != NULL ) - { - conversion = convert_pem_to_der( ( unsigned char * ) certificateTemplate.xValue.pValue, - certificateTemplate.xValue.ulValueLen, - derObject, &derLen ); - - if( 0 != conversion ) - { - LogError( ( "Failed to convert provided certificate." ) ); - result = CKR_ARGUMENTS_BAD; - } - } - else - { - LogError( ( "Failed to allocate buffer for converting certificate to DER." ) ); - result = CKR_HOST_MEMORY; - } - } - - if( result == CKR_OK ) - { - /* Set the template pointers to refer to the DER converted objects. */ - certificateTemplate.xValue.pValue = derObject; - certificateTemplate.xValue.ulValueLen = derLen; - - /* Best effort clean-up of the existing object, if it exists. */ - destroyProvidedObjects( session, ( CK_BYTE_PTR * ) &label, &certificateClass, 1 ); - - /* Create an object using the encoded client certificate. */ - LogInfo( ( "Writing certificate into label \"%s\".", label ) ); - - result = functionList->C_CreateObject( session, - ( CK_ATTRIBUTE_PTR ) &certificateTemplate, - sizeof( certificateTemplate ) / sizeof( CK_ATTRIBUTE ), - &objectHandle ); - } - - if( derObject != NULL ) - { - free( derObject ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -bool loadClaimCredentials( CK_SESSION_HANDLE p11Session, - const char * pClaimCertPath, - const char * pClaimCertLabel, - const char * pClaimPrivKeyPath, - const char * pClaimPrivKeyLabel ) -{ - bool status; - char claimCert[ CLAIM_CERT_BUFFER_LENGTH ] = { 0 }; - size_t claimCertLength = 0; - char claimPrivateKey[ CLAIM_PRIVATE_KEY_BUFFER_LENGTH ] = { 0 }; - size_t claimPrivateKeyLength = 0; - CK_RV ret; - - assert( pClaimCertPath != NULL ); - assert( pClaimCertLabel != NULL ); - assert( pClaimPrivKeyPath != NULL ); - assert( pClaimPrivKeyLabel != NULL ); - - status = readFile( pClaimCertPath, claimCert, CLAIM_CERT_BUFFER_LENGTH, - &claimCertLength ); - - if( status == true ) - { - status = readFile( pClaimPrivKeyPath, claimPrivateKey, - CLAIM_PRIVATE_KEY_BUFFER_LENGTH, &claimPrivateKeyLength ); - } - - if( status == true ) - { - ret = provisionPrivateKey( p11Session, claimPrivateKey, - claimPrivateKeyLength + 1, /* MbedTLS includes null character in length for PEM objects. */ - pClaimPrivKeyLabel ); - status = ( ret == CKR_OK ); - } - - if( status == true ) - { - ret = provisionCertificate( p11Session, claimCert, - claimCertLength + 1, /* MbedTLS includes null character in length for PEM objects. */ - pClaimCertLabel ); - status = ( ret == CKR_OK ); - } - - return status; -} - -/*-----------------------------------------------------------*/ - -bool loadCertificate( CK_SESSION_HANDLE p11Session, - const char * pCertificate, - const char * pLabel, - size_t certificateLength ) -{ - CK_RV ret; - - assert( pCertificate != NULL ); - assert( pLabel != NULL ); - - ret = provisionCertificate( p11Session, - pCertificate, - certificateLength + 1, /* MbedTLS includes null character in length for PEM objects. */ - pLabel ); - - return( ret == CKR_OK ); -} - -/*-----------------------------------------------------------*/ - -bool loadPrivateKey( CK_SESSION_HANDLE p11Session, - const char * pPrivateKey, - const char * pLabel, - size_t privateKeyLength ) -{ - CK_RV ret; - - assert( pPrivateKey != NULL ); - assert( pLabel != NULL ); - - ret = provisionPrivateKey( p11Session, - pPrivateKey, - privateKeyLength + 1, /* MbedTLS includes null character in length for PEM objects. */ - pLabel ); - - return( ret == CKR_OK ); -} - -/*-----------------------------------------------------------*/ - -bool pkcs11CloseSession( CK_SESSION_HANDLE p11Session ) -{ - CK_RV result = CKR_OK; - CK_FUNCTION_LIST_PTR functionList = NULL; - - result = C_GetFunctionList( &functionList ); - - if( result == CKR_OK ) - { - result = functionList->C_CloseSession( p11Session ); - } - - if( result == CKR_OK ) - { - result = functionList->C_Finalize( NULL ); - } - - return( result == CKR_OK ); -} - -/*-----------------------------------------------------------*/ diff --git a/demos/fleet_provisioning/fleet_provisioning_keys_cert/pkcs11_operations.h b/demos/fleet_provisioning/fleet_provisioning_keys_cert/pkcs11_operations.h deleted file mode 100644 index c22b94f60f..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_keys_cert/pkcs11_operations.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef PKCS11_OPERATIONS_H_ -#define PKCS11_OPERATIONS_H_ - -/* Standard includes. */ -#include -#include - -/* corePKCS11 include. */ -#include "core_pkcs11.h" - -/** - * @brief Loads the claim credentials into the PKCS #11 module. Claim - * credentials are used in "Provisioning by Claim" workflow of Fleet - * Provisioning feature of AWS IoT Core. For more information, refer to the - * [AWS documentation](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html#claim-based) - * - * Note: This function is for demonstration purposes, and the claim credentials - * should be securely stored in production devices. For example, the - * shared claim credentials could be loaded into a secure element on the devices - * in your fleet at the time of manufacturing. - * - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pClaimCertPath Path to the claim certificate. - * @param[in] pClaimCertLabel PKCS #11 label for the claim certificate. - * @param[in] pClaimPrivKeyPath Path to the claim private key. - * @param[in] pClaimPrivKeyLabel PKCS #11 label for the claim private key. - * - * @return True on success. - */ -bool loadClaimCredentials( CK_SESSION_HANDLE p11Session, - const char * pClaimCertPath, - const char * pClaimCertLabel, - const char * pClaimPrivKeyPath, - const char * pClaimPrivKeyLabel ); - -/** - * @brief Save the device client certificate into the PKCS #11 module. - * - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pCertificate The certificate to load. - * @param[in] pLabel PKCS #11 label for the certificate. - * @param[in] certificateLength Length of #pCertificate. - * - * @return True on success. - */ -bool loadCertificate( CK_SESSION_HANDLE p11Session, - const char * pCertificate, - const char * pLabel, - size_t certificateLength ); - -/** - * @brief Save the device client certificate into the PKCS #11 module. - * - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pPrivateKey The private key to load. - * @param[in] pLabel PKCS #11 label for the private key. - * @param[in] privateKeyLength Length of #pPrivateKey. - * - * @return True on success. - */ -bool loadPrivateKey( CK_SESSION_HANDLE p11Session, - const char * pPrivateKey, - const char * pLabel, - size_t privateKeyLength ); - -/** - * @brief Close the PKCS #11 session. - * - * @param[in] p11Session The PKCS #11 session to use. - * - * @return True on success. - */ -bool pkcs11CloseSession( CK_SESSION_HANDLE p11Session ); - -#endif /* ifndef PKCS11_OPERATIONS_H_ */ diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/core_mqtt_config.h b/demos/fleet_provisioning/fleet_provisioning_with_csr/core_mqtt_config.h deleted file mode 100644 index 629e7dc688..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/core_mqtt_config.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef CORE_MQTT_CONFIG_H_ -#define CORE_MQTT_CONFIG_H_ - -/**************************************************/ -/******* DO NOT CHANGE the following order ********/ -/**************************************************/ - -/* Include logging header files and define logging macros in the following order: - * 1. Include the header file "logging_levels.h". - * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros. - * 3. Include the header file "logging_stack.h". - */ - -#include "logging_levels.h" - -/* Logging configuration for the MQTT library. */ -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "MQTT" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_WARN -#endif - -#include "logging_stack.h" - -/************ End of logging configuration ****************/ - -/** - * @brief Determines the maximum number of MQTT PUBLISH messages, pending - * acknowledgement at a time, that are supported for incoming and outgoing - * direction of messages, separately. - * - * QoS 1 and 2 MQTT PUBLISHes require acknowledgement from the server before - * they can be completed. While they are awaiting the acknowledgement, the - * client must maintain information about their state. The value of this - * macro sets the limit on how many simultaneous PUBLISH states an MQTT - * context maintains, separately, for both incoming and outgoing direction of - * PUBLISHes. - * - * @note The MQTT context maintains separate state records for outgoing - * and incoming PUBLISHes, and thus, 2 * MQTT_STATE_ARRAY_MAX_COUNT amount - * of memory is statically allocated for the state records. - */ -#define MQTT_STATE_ARRAY_MAX_COUNT ( 10U ) - -/** - * @brief Number of milliseconds to wait for a ping response to a ping - * request as part of the keep-alive mechanism. - * - * If a ping response is not received before this timeout, then - * #MQTT_ProcessLoop will return #MQTTKeepAliveTimeout. - */ -#define MQTT_PINGRESP_TIMEOUT_MS ( 5000U ) - -#endif /* ifndef CORE_MQTT_CONFIG_H_ */ diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/example_demo_template.json b/demos/fleet_provisioning/fleet_provisioning_with_csr/example_demo_template.json deleted file mode 100644 index 78d7fca2a8..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/example_demo_template.json +++ /dev/null @@ -1,54 +0,0 @@ - { - "Parameters": { - "SerialNumber": { - "Type": "String" - }, - "AWS::IoT::Certificate::Id": { - "Type": "String" - } - }, - "Resources": { - "certificate": { - "Properties": { - "CertificateId": { - "Ref": "AWS::IoT::Certificate::Id" - }, - "Status": "Active" - }, - "Type": "AWS::IoT::Certificate" - }, - "policy": { - "Properties": { - "PolicyName": "" - }, - "Type": "AWS::IoT::Policy" - }, - "thing": { - "OverrideSettings": { - "AttributePayload": "MERGE", - "ThingGroups": "DO_NOTHING", - "ThingTypeName": "REPLACE" - }, - "Properties": { - "AttributePayload": {}, - "ThingGroups": [], - "ThingName": { - "Fn::Join": [ - "", - [ - "fp_demo_", - { - "Ref": "SerialNumber" - } - ] - ] - }, - "ThingTypeName": "fp_demo_things" - }, - "Type": "AWS::IoT::Thing" - } - }, - "DeviceConfiguration": { - "Foo": "Bar" - } - } diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_config.h b/demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_config.h deleted file mode 100644 index aa7ef33a3f..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/fleet_provisioning_config.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef FLEET_PROVISIONING_CONFIG_H_ -#define FLEET_PROVISIONING_CONFIG_H_ - -/**************************************************/ -/******* DO NOT CHANGE the following order ********/ -/**************************************************/ - -/* Include logging header files and define logging macros in the following order: - * 1. Include the header file "logging_levels.h". - * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros. - * 3. Include the header file "logging_stack.h". - */ - -#include "logging_levels.h" - -/* Logging configuration for the Fleet Provisioning library. */ -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "FleetProvisioning" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/************ End of logging configuration ****************/ - -#endif /* ifndef FLEET_PROVISIONING_CONFIG_H_ */ diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/mqtt_operations.c b/demos/fleet_provisioning/fleet_provisioning_with_csr/mqtt_operations.c deleted file mode 100644 index f62e79e0c8..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/mqtt_operations.c +++ /dev/null @@ -1,1138 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * @file mqtt_operations.c - * - * @brief This file provides wrapper functions for MQTT operations on a mutually - * authenticated TLS connection. - * - * A mutually authenticated TLS connection is used to connect to the AWS IoT - * MQTT message broker in this example. Define ROOT_CA_CERT_PATH, - * CLIENT_CERT_PATH, and CLIENT_PRIVATE_KEY_PATH in demo_config.h to achieve - * mutual authentication. - */ - -/* Standard includes. */ -#include -#include -#include -#include - -/* POSIX includes. */ -#include - -/* Config include. */ -#include "demo_config.h" - -/* Interface include. */ -#include "mqtt_operations.h" - -/* MbedTLS transport include. */ -#include "mbedtls_pkcs11_posix.h" - -/*Include backoff algorithm header for retry logic.*/ -#include "backoff_algorithm.h" - -/* Clock for timer. */ -#include "clock.h" - -/* AWS IoT Core TLS ALPN definitions for MQTT authentication */ -#include "aws_iot_alpn_defs.h" - -/** - * These configurations are required. Throw compilation error if the below - * configs are not defined. - */ -#ifndef AWS_IOT_ENDPOINT - #error "Please define AWS IoT MQTT broker endpoint(AWS_IOT_ENDPOINT) in demo_config.h." -#endif -#ifndef ROOT_CA_CERT_PATH - #error "Please define path to Root CA certificate of the MQTT broker(ROOT_CA_CERT_PATH) in demo_config.h." -#endif -#ifndef CLIENT_IDENTIFIER - #error "Please define a unique CLIENT_IDENTIFIER." -#endif - -/** - * Provide default values for undefined configuration settings. - */ -#ifndef AWS_MQTT_PORT - #define AWS_MQTT_PORT ( 8883 ) -#endif - -#ifndef NETWORK_BUFFER_SIZE - #define NETWORK_BUFFER_SIZE ( 1024U ) -#endif - -/** - * @brief Length of the AWS IoT endpoint. - */ -#define AWS_IOT_ENDPOINT_LENGTH ( ( uint16_t ) ( sizeof( AWS_IOT_ENDPOINT ) - 1 ) ) - -/** - * @brief Length of the client identifier. - */ -#define CLIENT_IDENTIFIER_LENGTH ( ( uint16_t ) ( sizeof( CLIENT_IDENTIFIER ) - 1 ) ) - -/** - * @brief The maximum number of retries for connecting to server. - */ -#define CONNECTION_RETRY_MAX_ATTEMPTS ( 5U ) - -/** - * @brief The maximum back-off delay (in milliseconds) for retrying connection to server. - */ -#define CONNECTION_RETRY_MAX_BACKOFF_DELAY_MS ( 5000U ) - -/** - * @brief The base back-off delay (in milliseconds) to use for connection retry attempts. - */ -#define CONNECTION_RETRY_BACKOFF_BASE_MS ( 500U ) - -/** - * @brief Timeout for receiving CONNACK packet in milliseconds. - */ -#define CONNACK_RECV_TIMEOUT_MS ( 1000U ) - -/** - * @brief Maximum number of outgoing publishes maintained in the application - * until an ack is received from the broker. - */ -#define MAX_OUTGOING_PUBLISHES ( 5U ) - -/** - * @brief Invalid packet identifier for the MQTT packets. Zero is always an - * invalid packet identifier as per MQTT 3.1.1 spec. - */ -#define MQTT_PACKET_ID_INVALID ( ( uint16_t ) 0U ) - -/** - * @brief Timeout for MQTT_ProcessLoop function in milliseconds. - */ -#define MQTT_PROCESS_LOOP_TIMEOUT_MS ( 1000U ) - -/** - * @brief The maximum time interval in seconds which is allowed to elapse - * between two Control Packets. - * - * It is the responsibility of the client to ensure that the interval between - * control packets being sent does not exceed the this keep-alive value. In the - * absence of sending any other control packets, the client MUST send a - * PINGREQ packet. - */ -#define MQTT_KEEP_ALIVE_INTERVAL_SECONDS ( 60U ) - -/** - * @brief Timeout in milliseconds for transport send and receive. - */ -#define TRANSPORT_SEND_RECV_TIMEOUT_MS ( 1000U ) - -/** - * @brief The MQTT metrics string expected by AWS IoT MQTT Broker. - */ -#define METRICS_STRING "?SDK=" OS_NAME "&Version=" OS_VERSION "&Platform=" HARDWARE_PLATFORM_NAME "&MQTTLib=" MQTT_LIB - -/** - * @brief The length of the MQTT metrics string. - */ -#define METRICS_STRING_LENGTH ( ( uint16_t ) ( sizeof( METRICS_STRING ) - 1 ) ) - -/** - * @brief The length of the outgoing publish records array used by the coreMQTT - * library to track QoS > 0 packet ACKS for outgoing publishes. - */ -#define OUTGOING_PUBLISH_RECORD_LEN ( 10U ) - -/** - * @brief The length of the incoming publish records array used by the coreMQTT - * library to track QoS > 0 packet ACKS for incoming publishes. - */ -#define INCOMING_PUBLISH_RECORD_LEN ( 10U ) -/*-----------------------------------------------------------*/ - -/** - * @brief Structure to keep the MQTT publish packets until an ack is received - * for QoS1 publishes. - */ -typedef struct PublishPackets -{ - /** - * @brief Packet identifier of the publish packet. - */ - uint16_t packetId; - - /** - * @brief Publish info of the publish packet. - */ - MQTTPublishInfo_t pubInfo; -} PublishPackets_t; - -/* Each compilation unit must define the NetworkContext struct. */ -struct NetworkContext -{ - MbedtlsPkcs11Context_t * pParams; -}; -/*-----------------------------------------------------------*/ - -/** - * @brief Packet Identifier updated when an ACK packet is received. - * - * It is used to match an expected ACK for a transmitted packet. - */ -static uint16_t globalAckPacketIdentifier = 0U; - -/** - * @brief Packet Identifier generated when Subscribe request was sent to the broker. - * - * It is used to match received Subscribe ACK to the transmitted subscribe - * request. - */ -static uint16_t globalSubscribePacketIdentifier = 0U; - -/** - * @brief Packet Identifier generated when Unsubscribe request was sent to the broker. - * - * It is used to match received Unsubscribe ACK to the transmitted unsubscribe - * request. - */ -static uint16_t globalUnsubscribePacketIdentifier = 0U; - -/** - * @brief Array to keep the outgoing publish messages. - * - * These stored outgoing publish messages are kept until a successful ack - * is received. - */ -static PublishPackets_t outgoingPublishPackets[ MAX_OUTGOING_PUBLISHES ] = { 0 }; - -/** - * @brief The network buffer must remain valid for the lifetime of the MQTT context. - */ -static uint8_t buffer[ NETWORK_BUFFER_SIZE ]; - -/** - * @brief The MQTT context used for MQTT operation. - */ -static MQTTContext_t mqttContext = { 0 }; - -/** - * @brief The network context used for MbedTLS operation. - */ -static NetworkContext_t networkContext = { 0 }; - -/** - * @brief The parameters for MbedTLS operation. - */ -static MbedtlsPkcs11Context_t tlsContext = { 0 }; - -/** - * @brief The flag to indicate that the mqtt session is established. - */ -static bool mqttSessionEstablished = false; - -/** - * @brief Callback registered when calling EstablishMqttSession to get incoming - * publish messages. - */ -static MQTTPublishCallback_t appPublishCallback = NULL; - -/** - * @brief Array to track the outgoing publish records for outgoing publishes - * with QoS > 0. - * - * This is passed into #MQTT_InitStatefulQoS to allow for QoS > 0. - * - */ -static MQTTPubAckInfo_t pOutgoingPublishRecords[ OUTGOING_PUBLISH_RECORD_LEN ]; - -/** - * @brief Array to track the incoming publish records for incoming publishes - * with QoS > 0. - * - * This is passed into #MQTT_InitStatefulQoS to allow for QoS > 0. - * - */ -static MQTTPubAckInfo_t pIncomingPublishRecords[ INCOMING_PUBLISH_RECORD_LEN ]; -/*-----------------------------------------------------------*/ - -/** - * @brief The random number generator to use for exponential backoff with - * jitter retry logic. - * - * @return The generated random number. - */ -static uint32_t generateRandomNumber( void ); - -/** - * @brief Connect to the MQTT broker with reconnection retries. - * - * If connection fails, retry is attempted after a timeout. Timeout value - * exponentially increases until maximum timeout value is reached or the number - * of attempts are exhausted. - * - * @param[out] pNetworkContext The created network context. - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pClientCertLabel The client certificate PKCS #11 label to use. - * @param[in] pPrivateKeyLabel The private key PKCS #11 label for the client certificate. - * - * @return false on failure; true on successful connection. - */ -static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContext, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ); - -/** - * @brief Get the free index in the #outgoingPublishPackets array at which an - * outgoing publish can be stored. - * - * @param[out] pIndex The index at which an outgoing publish can be stored. - * - * @return false if no more publishes can be stored; - * true if an index to store the next outgoing publish is obtained. - */ -static bool getNextFreeIndexForOutgoingPublishes( uint8_t * pIndex ); - -/** - * @brief Clean up the outgoing publish at given index from the - * #outgoingPublishPackets array. - * - * @param[in] index The index at which a publish message has to be cleaned up. - */ -static void cleanupOutgoingPublishAt( uint8_t index ); - -/** - * @brief Clean up all the outgoing publishes in the #outgoingPublishPackets array. - */ -static void cleanupOutgoingPublishes( void ); - -/** - * @brief Clean up the publish packet with the given packet id in the - * #outgoingPublishPackets array. - * - * @param[in] packetId Packet id of the packet to be clean. - */ -static void cleanupOutgoingPublishWithPacketID( uint16_t packetId ); - -/** - * @brief Callback registered with the MQTT library. - * - * @param[in] pMqttContext MQTT context pointer. - * @param[in] pPacketInfo Packet Info pointer for the incoming packet. - * @param[in] pDeserializedInfo Deserialized information from the incoming packet. - */ -static void mqttCallback( MQTTContext_t * pMqttContext, - MQTTPacketInfo_t * pPacketInfo, - MQTTDeserializedInfo_t * pDeserializedInfo ); - -/** - * @brief Resend the publishes if a session is re-established with the broker. - * - * This function handles the resending of the QoS1 publish packets, which are - * maintained locally. - * - * @param[in] pMqttContext The MQTT context pointer. - * - * @return true if all the unacknowledged QoS1 publishes are re-sent successfully; - * false otherwise. - */ -static bool handlePublishResend( MQTTContext_t * pMqttContext ); - -/** - * @brief Wait for an expected ACK packet to be received. - * - * This function handles waiting for an expected ACK packet by calling - * #MQTT_ProcessLoop and waiting for #mqttCallback to set the global ACK - * packet identifier to the expected ACK packet identifier. - * - * @param[in] pMqttContext MQTT context pointer. - * @param[in] usPacketIdentifier Packet identifier for expected ACK packet. - * @param[in] ulTimeout Maximum duration to wait for expected ACK packet. - * - * @return true if the expected ACK packet was received, false otherwise. - */ -static bool waitForPacketAck( MQTTContext_t * pMqttContext, - uint16_t usPacketIdentifier, - uint32_t ulTimeout ); -/*-----------------------------------------------------------*/ - -static uint32_t generateRandomNumber() -{ - return( ( uint32_t ) rand() ); -} -/*-----------------------------------------------------------*/ - -static bool connectToBrokerWithBackoffRetries( NetworkContext_t * pNetworkContext, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ) -{ - bool returnStatus = false; - BackoffAlgorithmStatus_t backoffAlgStatus = BackoffAlgorithmSuccess; - MbedtlsPkcs11Status_t tlsStatus = MBEDTLS_PKCS11_SUCCESS; - BackoffAlgorithmContext_t reconnectParams; - MbedtlsPkcs11Credentials_t tlsCredentials = { 0 }; - uint16_t nextRetryBackOff = 0U; - - /* Set the pParams member of the network context with desired transport. */ - pNetworkContext->pParams = &tlsContext; - - /* Initialize credentials for establishing TLS session. */ - tlsCredentials.pRootCaPath = ROOT_CA_CERT_PATH; - tlsCredentials.pClientCertLabel = pClientCertLabel; - tlsCredentials.pPrivateKeyLabel = pPrivateKeyLabel; - tlsCredentials.p11Session = p11Session; - - /* AWS IoT requires devices to send the Server Name Indication (SNI) - * extension to the Transport Layer Security (TLS) protocol and provide - * the complete endpoint address in the host_name field. Details about - * SNI for AWS IoT can be found in the link below. - * https://docs.aws.amazon.com/iot/latest/developerguide/transport-security.html - */ - tlsCredentials.disableSni = false; - - if( AWS_MQTT_PORT == 443 ) - { - static const char * alpnProtoArray[] = AWS_IOT_ALPN_MQTT_CA_AUTH_MBEDTLS; - - /* Pass the ALPN protocol name depending on the port being used. - * Please see more details about the ALPN protocol for AWS IoT MQTT endpoint - * in the link below. - * https://aws.amazon.com/blogs/iot/mqtt-with-tls-client-authentication-on-port-443-why-it-is-useful-and-how-it-works/ - */ - tlsCredentials.pAlpnProtos = alpnProtoArray; - } - - /* Initialize reconnect attempts and interval */ - BackoffAlgorithm_InitializeParams( &reconnectParams, - CONNECTION_RETRY_BACKOFF_BASE_MS, - CONNECTION_RETRY_MAX_BACKOFF_DELAY_MS, - CONNECTION_RETRY_MAX_ATTEMPTS ); - - do - { - /* Establish a TLS session with the MQTT broker. This example connects - * to the MQTT broker as specified in AWS_IOT_ENDPOINT and AWS_MQTT_PORT - * at the demo config header. */ - LogDebug( ( "Establishing a TLS session to %.*s:%d.", - AWS_IOT_ENDPOINT_LENGTH, - AWS_IOT_ENDPOINT, - AWS_MQTT_PORT ) ); - - tlsStatus = Mbedtls_Pkcs11_Connect( pNetworkContext, - AWS_IOT_ENDPOINT, - AWS_MQTT_PORT, - &tlsCredentials, - TRANSPORT_SEND_RECV_TIMEOUT_MS ); - - if( tlsStatus == MBEDTLS_PKCS11_SUCCESS ) - { - /* Connection successful. */ - returnStatus = true; - } - else - { - /* Generate a random number and get back-off value (in milliseconds) for the next connection retry. */ - backoffAlgStatus = BackoffAlgorithm_GetNextBackoff( &reconnectParams, generateRandomNumber(), &nextRetryBackOff ); - - if( backoffAlgStatus == BackoffAlgorithmRetriesExhausted ) - { - LogError( ( "Connection to the broker failed, all attempts exhausted." ) ); - } - else if( backoffAlgStatus == BackoffAlgorithmSuccess ) - { - LogWarn( ( "Connection to the broker failed. Retrying connection " - "after %hu ms backoff.", - ( unsigned short ) nextRetryBackOff ) ); - Clock_SleepMs( nextRetryBackOff ); - } - } - } while( ( tlsStatus != MBEDTLS_PKCS11_SUCCESS ) && ( backoffAlgStatus == BackoffAlgorithmSuccess ) ); - - return returnStatus; -} -/*-----------------------------------------------------------*/ - -static bool getNextFreeIndexForOutgoingPublishes( uint8_t * pIndex ) -{ - bool returnStatus = false; - uint8_t index = 0; - - assert( outgoingPublishPackets != NULL ); - assert( pIndex != NULL ); - - for( index = 0; index < MAX_OUTGOING_PUBLISHES; index++ ) - { - /* A free index is marked by invalid packet id. Check if the the index - * has a free slot. */ - if( outgoingPublishPackets[ index ].packetId == MQTT_PACKET_ID_INVALID ) - { - returnStatus = true; - break; - } - } - - /* Copy the available index into the output param. */ - if( returnStatus == true ) - { - *pIndex = index; - } - - return returnStatus; -} -/*-----------------------------------------------------------*/ - -static void cleanupOutgoingPublishAt( uint8_t index ) -{ - assert( outgoingPublishPackets != NULL ); - assert( index < MAX_OUTGOING_PUBLISHES ); - - /* Clear the outgoing publish packet. */ - ( void ) memset( &( outgoingPublishPackets[ index ] ), - 0x00, - sizeof( outgoingPublishPackets[ index ] ) ); -} -/*-----------------------------------------------------------*/ - -static void cleanupOutgoingPublishes( void ) -{ - assert( outgoingPublishPackets != NULL ); - - /* Clean up all the outgoing publish packets. */ - ( void ) memset( outgoingPublishPackets, 0x00, sizeof( outgoingPublishPackets ) ); -} -/*-----------------------------------------------------------*/ - -static void cleanupOutgoingPublishWithPacketID( uint16_t packetId ) -{ - uint8_t index = 0; - - assert( outgoingPublishPackets != NULL ); - assert( packetId != MQTT_PACKET_ID_INVALID ); - - /* Clean up the saved outgoing publish with packet Id equal to packetId. */ - for( index = 0; index < MAX_OUTGOING_PUBLISHES; index++ ) - { - if( outgoingPublishPackets[ index ].packetId == packetId ) - { - cleanupOutgoingPublishAt( index ); - - LogDebug( ( "Cleaned up outgoing publish packet with packet id %u.", - packetId ) ); - - break; - } - } -} -/*-----------------------------------------------------------*/ - -static void mqttCallback( MQTTContext_t * pMqttContext, - MQTTPacketInfo_t * pPacketInfo, - MQTTDeserializedInfo_t * pDeserializedInfo ) -{ - uint16_t packetIdentifier; - - assert( pMqttContext != NULL ); - assert( pPacketInfo != NULL ); - assert( pDeserializedInfo != NULL ); - - /* Suppress the unused parameter warning when asserts are disabled in - * build. */ - ( void ) pMqttContext; - - packetIdentifier = pDeserializedInfo->packetIdentifier; - - /* Handle an incoming publish. The lower 4 bits of the publish packet - * type is used for the dup, QoS, and retain flags. Hence masking - * out the lower bits to check if the packet is publish. */ - if( ( pPacketInfo->type & 0xF0U ) == MQTT_PACKET_TYPE_PUBLISH ) - { - assert( pDeserializedInfo->pPublishInfo != NULL ); - - /* Invoke the application callback for incoming publishes. */ - if( appPublishCallback != NULL ) - { - appPublishCallback( pDeserializedInfo->pPublishInfo, packetIdentifier ); - } - } - else - { - /* Handle other packets. */ - switch( pPacketInfo->type ) - { - case MQTT_PACKET_TYPE_SUBACK: - LogDebug( ( "MQTT Packet type SUBACK received." ) ); - - /* Make sure the ACK packet identifier matches with the request - * packet identifier. */ - assert( globalSubscribePacketIdentifier == packetIdentifier ); - - /* Update the global ACK packet identifier. */ - globalAckPacketIdentifier = packetIdentifier; - break; - - case MQTT_PACKET_TYPE_UNSUBACK: - LogDebug( ( "MQTT Packet type UNSUBACK received." ) ); - - /* Make sure the ACK packet identifier matches with the request - * packet identifier. */ - assert( globalUnsubscribePacketIdentifier == packetIdentifier ); - - /* Update the global ACK packet identifier. */ - globalAckPacketIdentifier = packetIdentifier; - break; - - case MQTT_PACKET_TYPE_PINGRESP: - - /* We do not expect to receive PINGRESP as we are using - * MQTT_ProcessLoop. */ - LogWarn( ( "PINGRESP should not be received by the application " - "callback when using MQTT_ProcessLoop." ) ); - break; - - case MQTT_PACKET_TYPE_PUBACK: - LogDebug( ( "PUBACK received for packet id %u.", - packetIdentifier ) ); - - /* Update the global ACK packet identifier. */ - globalAckPacketIdentifier = packetIdentifier; - - /* Cleanup the publish packet from the #outgoingPublishPackets - * array when a PUBACK is received. */ - cleanupOutgoingPublishWithPacketID( packetIdentifier ); - break; - - /* Any other packet type is invalid. */ - default: - LogError( ( "Unknown packet type received:(%02x).", - pPacketInfo->type ) ); - } - } -} -/*-----------------------------------------------------------*/ - -static bool handlePublishResend( MQTTContext_t * pMqttContext ) -{ - bool returnStatus = false; - MQTTStatus_t mqttStatus = MQTTSuccess; - uint8_t index = 0U; - - assert( outgoingPublishPackets != NULL ); - - /* Resend all the QoS1 publishes still in the #outgoingPublishPackets array. - * These are the publishes that haven't received a PUBACK yet. When a PUBACK - * is received, the corresponding publish is removed from the array. */ - for( index = 0U; index < MAX_OUTGOING_PUBLISHES; index++ ) - { - if( outgoingPublishPackets[ index ].packetId != MQTT_PACKET_ID_INVALID ) - { - outgoingPublishPackets[ index ].pubInfo.dup = true; - - LogDebug( ( "Sending duplicate PUBLISH with packet id %u.", - outgoingPublishPackets[ index ].packetId ) ); - mqttStatus = MQTT_Publish( pMqttContext, - &outgoingPublishPackets[ index ].pubInfo, - outgoingPublishPackets[ index ].packetId ); - - if( mqttStatus != MQTTSuccess ) - { - LogError( ( "Sending duplicate PUBLISH for packet id %u " - " failed with status %s.", - outgoingPublishPackets[ index ].packetId, - MQTT_Status_strerror( mqttStatus ) ) ); - break; - } - else - { - LogDebug( ( "Sent duplicate PUBLISH successfully for packet id %u.", - outgoingPublishPackets[ index ].packetId ) ); - } - } - } - - /* Were all the unacknowledged QoS1 publishes successfully re-sent? */ - if( index == MAX_OUTGOING_PUBLISHES ) - { - returnStatus = true; - } - - return returnStatus; -} -/*-----------------------------------------------------------*/ - -static bool waitForPacketAck( MQTTContext_t * pMqttContext, - uint16_t usPacketIdentifier, - uint32_t ulTimeout ) -{ - uint32_t ulMqttProcessLoopEntryTime; - uint32_t ulMqttProcessLoopTimeoutTime; - uint32_t ulCurrentTime; - - MQTTStatus_t eMqttStatus = MQTTSuccess; - bool xStatus = false; - - /* Reset the ACK packet identifier being received. */ - globalAckPacketIdentifier = 0U; - - ulCurrentTime = pMqttContext->getTime(); - ulMqttProcessLoopEntryTime = ulCurrentTime; - ulMqttProcessLoopTimeoutTime = ulCurrentTime + ulTimeout; - - /* Call MQTT_ProcessLoop multiple times until the expected packet ACK - * is received, a timeout happens, or MQTT_ProcessLoop fails. */ - while( ( globalAckPacketIdentifier != usPacketIdentifier ) && - ( ulCurrentTime < ulMqttProcessLoopTimeoutTime ) && - ( eMqttStatus == MQTTSuccess || eMqttStatus == MQTTNeedMoreBytes ) ) - { - /* Event callback will set #globalAckPacketIdentifier when receiving - * appropriate packet. */ - eMqttStatus = MQTT_ProcessLoop( pMqttContext ); - ulCurrentTime = pMqttContext->getTime(); - } - - if( ( ( eMqttStatus != MQTTSuccess ) && ( eMqttStatus != MQTTNeedMoreBytes ) ) || - ( globalAckPacketIdentifier != usPacketIdentifier ) ) - { - LogError( ( "MQTT_ProcessLoop failed to receive ACK packet: Expected ACK Packet ID=%02X, LoopDuration=%u, Status=%s", - usPacketIdentifier, - ( ulCurrentTime - ulMqttProcessLoopEntryTime ), - MQTT_Status_strerror( eMqttStatus ) ) ); - } - else - { - xStatus = true; - } - - return xStatus; -} -/*-----------------------------------------------------------*/ - -bool EstablishMqttSession( MQTTPublishCallback_t publishCallback, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ) -{ - bool returnStatus = false; - MQTTStatus_t mqttStatus; - MQTTConnectInfo_t connectInfo; - MQTTFixedBuffer_t networkBuffer; - TransportInterface_t transport = { NULL }; - bool createCleanSession = false; - MQTTContext_t * pMqttContext = &mqttContext; - NetworkContext_t * pNetworkContext = &networkContext; - bool sessionPresent = false; - - assert( pMqttContext != NULL ); - assert( pNetworkContext != NULL ); - - /* Initialize the mqtt context and network context. */ - ( void ) memset( pMqttContext, 0U, sizeof( MQTTContext_t ) ); - ( void ) memset( pNetworkContext, 0U, sizeof( NetworkContext_t ) ); - - returnStatus = connectToBrokerWithBackoffRetries( pNetworkContext, - p11Session, - pClientCertLabel, - pPrivateKeyLabel ); - - if( returnStatus != true ) - { - /* Log an error to indicate connection failure after all - * reconnect attempts are over. */ - LogError( ( "Failed to connect to MQTT broker %.*s.", - AWS_IOT_ENDPOINT_LENGTH, - AWS_IOT_ENDPOINT ) ); - } - else - { - /* Fill in TransportInterface send and receive function pointers. - * For this demo, TCP sockets are used to send and receive data - * from the network. pNetworkContext is an SSL context for OpenSSL.*/ - transport.pNetworkContext = pNetworkContext; - transport.send = Mbedtls_Pkcs11_Send; - transport.recv = Mbedtls_Pkcs11_Recv; - transport.writev = NULL; - - /* Fill the values for network buffer. */ - networkBuffer.pBuffer = buffer; - networkBuffer.size = NETWORK_BUFFER_SIZE; - - /* Remember the publish callback supplied. */ - appPublishCallback = publishCallback; - - /* Initialize the MQTT library. */ - mqttStatus = MQTT_Init( pMqttContext, - &transport, - Clock_GetTimeMs, - mqttCallback, - &networkBuffer ); - - if( mqttStatus != MQTTSuccess ) - { - returnStatus = false; - LogError( ( "MQTT_Init failed with status %s.", - MQTT_Status_strerror( mqttStatus ) ) ); - } - else - { - mqttStatus = MQTT_InitStatefulQoS( pMqttContext, - pOutgoingPublishRecords, - OUTGOING_PUBLISH_RECORD_LEN, - pIncomingPublishRecords, - INCOMING_PUBLISH_RECORD_LEN ); - - if( mqttStatus != MQTTSuccess ) - { - returnStatus = false; - LogError( ( "MQTT_InitStatefulQoS failed with status %s.", - MQTT_Status_strerror( mqttStatus ) ) ); - } - else - { - /* Establish an MQTT session by sending a CONNECT packet. */ - - /* If #createCleanSession is true, start with a clean session - * i.e. direct the MQTT broker to discard any previous session data. - * If #createCleanSession is false, direct the broker to attempt to - * reestablish a session which was already present. */ - connectInfo.cleanSession = createCleanSession; - - /* The client identifier is used to uniquely identify this MQTT client to - * the MQTT broker. In a production device the identifier can be something - * unique, such as a device serial number. */ - connectInfo.pClientIdentifier = CLIENT_IDENTIFIER; - connectInfo.clientIdentifierLength = CLIENT_IDENTIFIER_LENGTH; - - /* The maximum time interval in seconds which is allowed to elapse - * between two Control Packets. - * It is the responsibility of the client to ensure that the interval between - * control packets being sent does not exceed the this keep-alive value. In the - * absence of sending any other control packets, the client MUST send a - * PINGREQ packet. */ - connectInfo.keepAliveSeconds = MQTT_KEEP_ALIVE_INTERVAL_SECONDS; - - /* Username and password for authentication. Not used in this demo. */ - connectInfo.pUserName = METRICS_STRING; - connectInfo.userNameLength = METRICS_STRING_LENGTH; - connectInfo.pPassword = NULL; - connectInfo.passwordLength = 0U; - - /* Send an MQTT CONNECT packet to the broker. */ - mqttStatus = MQTT_Connect( pMqttContext, - &connectInfo, - NULL, - CONNACK_RECV_TIMEOUT_MS, - &sessionPresent ); - - if( mqttStatus != MQTTSuccess ) - { - returnStatus = false; - LogError( ( "Connection with MQTT broker failed with status %s.", - MQTT_Status_strerror( mqttStatus ) ) ); - } - else - { - LogDebug( ( "MQTT connection successfully established with broker." ) ); - } - } - } - - if( returnStatus == true ) - { - /* Keep a flag for indicating if MQTT session is established. This - * flag will mark that an MQTT DISCONNECT has to be sent at the end - * of the demo even if there are intermediate failures. */ - mqttSessionEstablished = true; - } - - if( returnStatus == true ) - { - /* Check if a session is present and if there are any outgoing - * publishes that need to be resent. Resending unacknowledged - * publishes is needed only if the broker is re-establishing a - * session that was already present. */ - if( sessionPresent == true ) - { - LogDebug( ( "An MQTT session with broker is re-established. " - "Resending unacked publishes." ) ); - - /* Handle all the resend of publish messages. */ - returnStatus = handlePublishResend( &mqttContext ); - } - else - { - LogDebug( ( "A clean MQTT connection is established." - " Cleaning up all the stored outgoing publishes." ) ); - - /* Clean up the outgoing publishes waiting for ack as this new - * connection doesn't re-establish an existing session. */ - cleanupOutgoingPublishes(); - } - } - } - - return returnStatus; -} - -/*-----------------------------------------------------------*/ - -bool DisconnectMqttSession( void ) -{ - MQTTStatus_t mqttStatus = MQTTSuccess; - bool returnStatus = false; - MQTTContext_t * pMqttContext = &mqttContext; - NetworkContext_t * pNetworkContext = &networkContext; - - assert( pMqttContext != NULL ); - assert( pNetworkContext != NULL ); - - if( mqttSessionEstablished == true ) - { - /* Send DISCONNECT. */ - mqttStatus = MQTT_Disconnect( pMqttContext ); - - if( mqttStatus != MQTTSuccess ) - { - LogError( ( "Sending MQTT DISCONNECT failed with status=%u.", - mqttStatus ) ); - } - else - { - /* MQTT DISCONNECT sent successfully. */ - returnStatus = true; - } - } - - /* End TLS session, then close TCP connection. */ - ( void ) Mbedtls_Pkcs11_Disconnect( pNetworkContext ); - - return returnStatus; -} -/*-----------------------------------------------------------*/ - -bool SubscribeToTopic( const char * pTopicFilter, - uint16_t topicFilterLength ) -{ - bool returnStatus = false; - MQTTStatus_t mqttStatus; - MQTTContext_t * pMqttContext = &mqttContext; - MQTTSubscribeInfo_t pSubscriptionList[ 1 ]; - - assert( pMqttContext != NULL ); - assert( pTopicFilter != NULL ); - assert( topicFilterLength > 0 ); - - /* Start with everything at 0. */ - ( void ) memset( ( void * ) pSubscriptionList, 0x00, sizeof( pSubscriptionList ) ); - - /* This example subscribes to only one topic and uses QOS1. */ - pSubscriptionList[ 0 ].qos = MQTTQoS1; - pSubscriptionList[ 0 ].pTopicFilter = pTopicFilter; - pSubscriptionList[ 0 ].topicFilterLength = topicFilterLength; - - /* Generate packet identifier for the SUBSCRIBE packet. */ - globalSubscribePacketIdentifier = MQTT_GetPacketId( pMqttContext ); - - /* Send SUBSCRIBE packet. */ - mqttStatus = MQTT_Subscribe( pMqttContext, - pSubscriptionList, - sizeof( pSubscriptionList ) / sizeof( MQTTSubscribeInfo_t ), - globalSubscribePacketIdentifier ); - - if( mqttStatus != MQTTSuccess ) - { - LogError( ( "Failed to send SUBSCRIBE packet to broker with error = %s.", - MQTT_Status_strerror( mqttStatus ) ) ); - } - else - { - LogDebug( ( "SUBSCRIBE topic %.*s to broker.", - topicFilterLength, - pTopicFilter ) ); - - /* Process incoming packet from the broker. Acknowledgment for subscription - * ( SUBACK ) will be received here. However after sending the subscribe, the - * client may receive a publish before it receives a subscribe ack. Since this - * demo is subscribing to the topic to which no one is publishing, probability - * of receiving publish message before subscribe ack is zero; but application - * must be ready to receive any packet. This demo uses MQTT_ProcessLoop to - * receive packet from network. */ - returnStatus = waitForPacketAck( pMqttContext, - globalSubscribePacketIdentifier, - MQTT_PROCESS_LOOP_TIMEOUT_MS ); - } - - return returnStatus; -} -/*-----------------------------------------------------------*/ - -bool UnsubscribeFromTopic( const char * pTopicFilter, - uint16_t topicFilterLength ) -{ - bool returnStatus = false; - MQTTStatus_t mqttStatus; - MQTTContext_t * pMqttContext = &mqttContext; - MQTTSubscribeInfo_t pSubscriptionList[ 1 ]; - - assert( pMqttContext != NULL ); - assert( pTopicFilter != NULL ); - assert( topicFilterLength > 0 ); - - /* Start with everything at 0. */ - ( void ) memset( ( void * ) pSubscriptionList, 0x00, sizeof( pSubscriptionList ) ); - - /* This example subscribes to only one topic and uses QOS1. */ - pSubscriptionList[ 0 ].qos = MQTTQoS1; - pSubscriptionList[ 0 ].pTopicFilter = pTopicFilter; - pSubscriptionList[ 0 ].topicFilterLength = topicFilterLength; - - /* Generate packet identifier for the UNSUBSCRIBE packet. */ - globalUnsubscribePacketIdentifier = MQTT_GetPacketId( pMqttContext ); - - /* Send UNSUBSCRIBE packet. */ - mqttStatus = MQTT_Unsubscribe( pMqttContext, - pSubscriptionList, - sizeof( pSubscriptionList ) / sizeof( MQTTSubscribeInfo_t ), - globalUnsubscribePacketIdentifier ); - - if( mqttStatus != MQTTSuccess ) - { - LogError( ( "Failed to send UNSUBSCRIBE packet to broker with error = %s.", - MQTT_Status_strerror( mqttStatus ) ) ); - } - else - { - LogDebug( ( "UNSUBSCRIBE sent topic %.*s to broker.", - topicFilterLength, - pTopicFilter ) ); - - /* Process incoming packet from the broker. Acknowledgment for unsubscribe - * operation ( UNSUBACK ) will be received here. This demo uses - * MQTT_ProcessLoop to receive packet from network. */ - returnStatus = waitForPacketAck( pMqttContext, - globalUnsubscribePacketIdentifier, - MQTT_PROCESS_LOOP_TIMEOUT_MS ); - } - - return returnStatus; -} -/*-----------------------------------------------------------*/ - -bool PublishToTopic( const char * pTopicFilter, - uint16_t topicFilterLength, - const char * pPayload, - size_t payloadLength ) -{ - bool returnStatus = false; - MQTTStatus_t mqttStatus = MQTTSuccess; - uint8_t publishIndex = MAX_OUTGOING_PUBLISHES; - MQTTContext_t * pMqttContext = &mqttContext; - - assert( pMqttContext != NULL ); - assert( pTopicFilter != NULL ); - assert( topicFilterLength > 0 ); - - /* Get the next free index for the outgoing publish. All QoS1 outgoing - * publishes are stored until a PUBACK is received. These messages are - * stored for supporting a resend if a network connection is broken before - * receiving a PUBACK. */ - returnStatus = getNextFreeIndexForOutgoingPublishes( &publishIndex ); - - if( returnStatus == false ) - { - LogError( ( "Unable to find a free spot for outgoing PUBLISH message." ) ); - } - else - { - LogDebug( ( "Published payload: %.*s", - ( int ) payloadLength, - ( const char * ) pPayload ) ); - - /* This example publishes to only one topic and uses QOS1. */ - outgoingPublishPackets[ publishIndex ].pubInfo.qos = MQTTQoS1; - outgoingPublishPackets[ publishIndex ].pubInfo.pTopicName = pTopicFilter; - outgoingPublishPackets[ publishIndex ].pubInfo.topicNameLength = topicFilterLength; - outgoingPublishPackets[ publishIndex ].pubInfo.pPayload = pPayload; - outgoingPublishPackets[ publishIndex ].pubInfo.payloadLength = payloadLength; - - /* Get a new packet id. */ - outgoingPublishPackets[ publishIndex ].packetId = MQTT_GetPacketId( pMqttContext ); - - /* Send PUBLISH packet. */ - mqttStatus = MQTT_Publish( pMqttContext, - &outgoingPublishPackets[ publishIndex ].pubInfo, - outgoingPublishPackets[ publishIndex ].packetId ); - - if( mqttStatus != MQTTSuccess ) - { - LogError( ( "Failed to send PUBLISH packet to broker with error = %s.", - MQTT_Status_strerror( mqttStatus ) ) ); - cleanupOutgoingPublishAt( publishIndex ); - returnStatus = false; - } - else - { - LogDebug( ( "PUBLISH sent for topic %.*s to broker with packet ID %u.", - topicFilterLength, - pTopicFilter, - outgoingPublishPackets[ publishIndex ].packetId ) ); - } - } - - return returnStatus; -} -/*-----------------------------------------------------------*/ - -bool ProcessLoopWithTimeout( void ) -{ - uint32_t ulMqttProcessLoopTimeoutTime; - uint32_t ulCurrentTime; - - MQTTStatus_t eMqttStatus = MQTTSuccess; - bool returnStatus = false; - - ulCurrentTime = mqttContext.getTime(); - ulMqttProcessLoopTimeoutTime = ulCurrentTime + MQTT_PROCESS_LOOP_TIMEOUT_MS; - - /* Call MQTT_ProcessLoop multiple times until the timeout expires or - * #MQTT_ProcessLoop fails. */ - while( ( ulCurrentTime < ulMqttProcessLoopTimeoutTime ) && - ( eMqttStatus == MQTTSuccess || eMqttStatus == MQTTNeedMoreBytes ) ) - { - eMqttStatus = MQTT_ProcessLoop( &mqttContext ); - ulCurrentTime = mqttContext.getTime(); - } - - if( ( eMqttStatus != MQTTSuccess ) && ( eMqttStatus != MQTTNeedMoreBytes ) ) - { - LogError( ( "MQTT_ProcessLoop returned with status = %s.", - MQTT_Status_strerror( eMqttStatus ) ) ); - } - else - { - LogDebug( ( "MQTT_ProcessLoop successful." ) ); - returnStatus = true; - } - - return returnStatus; -} -/*-----------------------------------------------------------*/ diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/mqtt_operations.h b/demos/fleet_provisioning/fleet_provisioning_with_csr/mqtt_operations.h deleted file mode 100644 index d9cdad7528..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/mqtt_operations.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef MQTT_OPERATIONS_H_ -#define MQTT_OPERATIONS_H_ - -/* MQTT API header. */ -#include "core_mqtt.h" - -/* corePKCS11 include. */ -#include "core_pkcs11.h" - -/** - * @brief Application callback type to handle the incoming publishes. - * - * @param[in] pPublishInfo Pointer to publish info of the incoming publish. - * @param[in] packetIdentifier Packet identifier of the incoming publish. - */ -typedef void (* MQTTPublishCallback_t )( MQTTPublishInfo_t * pPublishInfo, - uint16_t packetIdentifier ); - -/** - * @brief Establish a MQTT connection. - * - * @param[in] publishCallback The callback function to receive incoming - * publishes from the MQTT broker. - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pClientCertLabel The client certificate PKCS #11 label to use. - * @param[in] pPrivateKeyLabel The private key PKCS #11 label for the client certificate. - * - * @return true if an MQTT session is established; - * false otherwise. - */ -bool EstablishMqttSession( MQTTPublishCallback_t publishCallback, - CK_SESSION_HANDLE p11Session, - char * pClientCertLabel, - char * pPrivateKeyLabel ); - -/** - * @brief Disconnect the MQTT connection. - * - * @return true if the MQTT session was successfully disconnected; - * false otherwise. - */ -bool DisconnectMqttSession( void ); - -/** - * @brief Subscribe to a MQTT topic filter. - * - * @param[in] pTopicFilter The topic filter to subscribe to. - * @param[in] topicFilterLength Length of the topic buffer. - * - * @return true if subscribe operation was successful; - * false otherwise. - */ -bool SubscribeToTopic( const char * pTopicFilter, - uint16_t topicFilterLength ); - -/** - * @brief Unsubscribe from a MQTT topic filter. - * - * @param[in] pTopicFilter The topic filter to unsubscribe from. - * @param[in] topicFilterLength Length of the topic buffer. - * - * @return true if unsubscribe operation was successful; - * false otherwise. - */ -bool UnsubscribeFromTopic( const char * pTopicFilter, - uint16_t topicFilterLength ); - -/** - * @brief Publish a message to a MQTT topic. - * - * @param[in] pTopic The topic to publish the message on. - * @param[in] topicLength Length of the topic. - * @param[in] pMessage The message to publish. - * @param[in] messageLength Length of the message. - * - * @return true if PUBLISH was successfully sent; - * false otherwise. - */ -bool PublishToTopic( const char * pTopic, - uint16_t topicLength, - const char * pMessage, - size_t messageLength ); - -/** - * @brief Invoke the core MQTT library's process loop function. - * - * @return true if process loop was successful; - * false otherwise. - */ -bool ProcessLoopWithTimeout( void ); - -#endif /* ifndef MQTT_OPERATIONS_H_ */ diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/pkcs11_operations.c b/demos/fleet_provisioning/fleet_provisioning_with_csr/pkcs11_operations.c deleted file mode 100644 index bc4c8b3d6d..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/pkcs11_operations.c +++ /dev/null @@ -1,1202 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * @file pkcs11_operations.c - * - * @brief This file provides wrapper functions for PKCS11 operations. - */ - -/* Standard includes. */ -#include -#include - -/* Config include. */ -#include "demo_config.h" - -/* Interface include. */ -#include "pkcs11_operations.h" - -/* PKCS #11 include. */ -#include "core_pkcs11_config.h" -#include "core_pki_utils.h" -#include "mbedtls_utils.h" - -/* MbedTLS include. */ -#include "mbedtls/ctr_drbg.h" -#include "mbedtls/entropy.h" -#include "mbedtls/entropy_poll.h" -#include "mbedtls/error.h" -#include "mbedtls/oid.h" -#include "mbedtls/pk.h" -#include "mbedtls/pk_internal.h" -#include "mbedtls/sha256.h" -#include "mbedtls/x509_crt.h" -#include "mbedtls/x509_csr.h" - -/** - * @brief Size of buffer in which to hold the certificate signing request (CSR). - */ -#define CLAIM_CERT_BUFFER_LENGTH 2048 - -/** - * @brief Size of buffer in which to hold the certificate signing request (CSR). - */ -#define CLAIM_PRIVATE_KEY_BUFFER_LENGTH 2048 - -/** - * @brief Represents string to be logged when mbedTLS returned error - * does not contain a high-level code. - */ -static const char * pNoHighLevelMbedTlsCodeStr = ""; - -/** - * @brief Represents string to be logged when mbedTLS returned error - * does not contain a low-level code. - */ -static const char * pNoLowLevelMbedTlsCodeStr = ""; - -/** - * @brief Utility for converting the high-level code in an mbedTLS error to - * string, if the code-contains a high-level code; otherwise, using a default - * string. - */ -#define mbedtlsHighLevelCodeOrDefault( mbedTlsCode ) \ - ( mbedtls_high_level_strerr( mbedTlsCode ) != NULL ) \ - ? mbedtls_high_level_strerr( mbedTlsCode ) \ - : pNoHighLevelMbedTlsCodeStr - -/** - * @brief Utility for converting the level-level code in an mbedTLS error to - * string, if the code-contains a level-level code; otherwise, using a default - * string. - */ -#define mbedtlsLowLevelCodeOrDefault( mbedTlsCode ) \ - ( mbedtls_low_level_strerr( mbedTlsCode ) != NULL ) \ - ? mbedtls_low_level_strerr( mbedTlsCode ) \ - : pNoLowLevelMbedTlsCodeStr - -/* Length parameters for importing RSA-2048 private keys. */ -#define MODULUS_LENGTH pkcs11RSA_2048_MODULUS_BITS / 8 -#define E_LENGTH 3 -#define D_LENGTH pkcs11RSA_2048_MODULUS_BITS / 8 -#define PRIME_1_LENGTH 128 -#define PRIME_2_LENGTH 128 -#define EXPONENT_1_LENGTH 128 -#define EXPONENT_2_LENGTH 128 -#define COEFFICIENT_LENGTH 128 - -#define EC_PARAMS_LENGTH 10 -#define EC_D_LENGTH 32 - -/** - * @brief Struct for holding parsed RSA-2048 private keys. - */ -typedef struct RsaParams_t -{ - CK_BYTE modulus[ MODULUS_LENGTH + 1 ]; - CK_BYTE e[ E_LENGTH + 1 ]; - CK_BYTE d[ D_LENGTH + 1 ]; - CK_BYTE prime1[ PRIME_1_LENGTH + 1 ]; - CK_BYTE prime2[ PRIME_2_LENGTH + 1 ]; - CK_BYTE exponent1[ EXPONENT_1_LENGTH + 1 ]; - CK_BYTE exponent2[ EXPONENT_2_LENGTH + 1 ]; - CK_BYTE coefficient[ COEFFICIENT_LENGTH + 1 ]; -} RsaParams_t; - -/** - * @brief Struct containing parameters needed by the signing callback. - */ -typedef struct SigningCallbackContext -{ - CK_SESSION_HANDLE p11Session; - CK_OBJECT_HANDLE p11PrivateKey; -} SigningCallbackContext_t; - -/** - * @brief Parameters for the signing callback. This needs to be global as - * MbedTLS passes the key context to the signing function, so we cannot pass - * our own. - */ -static SigningCallbackContext_t signingContext = { 0 }; - -/*-----------------------------------------------------------*/ - -/** - * @brief Reads a file into the given buffer. - * - * @param[in] path Path of the file. - * @param[out] pBuffer Buffer to read file contents into. - * @param[in] bufferLength Length of #pBuffer. - * @param[out] pOutWrittenLength Length of contents written to #pBuffer. - */ -static bool readFile( const char * path, - char * pBuffer, - size_t bufferLength, - size_t * pOutWrittenLength ); - -/** - * @brief Delete the specified crypto object from storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] pkcsLabelsPtr The list of labels to remove. - * @param[in] pClass The list of corresponding classes. - * @param[in] count The length of #pkcsLabelsPtr and #pClass. - */ -static CK_RV destroyProvidedObjects( CK_SESSION_HANDLE session, - CK_BYTE_PTR * pkcsLabelsPtr, - CK_OBJECT_CLASS * pClass, - CK_ULONG count ); - - -/** - * @brief Import the specified ECDSA private key into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] label The label to store the key. - * @param[in] mbedPkContext The private key to store. - */ -static CK_RV provisionPrivateECKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ); - - - -/** - * @brief Import the specified RSA private key into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] label The label to store the key. - * @param[in] mbedPkContext The private key to store. - */ -static CK_RV provisionPrivateRSAKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ); - - -/** - * @brief Import the specified private key into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] privateKey The private key to store, in PEM format. - * @param[in] privateKeyLength The length of the key, including null terminator. - * @param[in] label The label to store the key. - */ -static CK_RV provisionPrivateKey( CK_SESSION_HANDLE session, - const char * privateKey, - size_t privateKeyLength, - const char * label ); - -/** - * @brief Import the specified X.509 client certificate into storage. - * - * @param[in] session The PKCS #11 session. - * @param[in] certificate The certificate to store, in PEM format. - * @param[in] certificateLength The length of the certificate, including the null terminator. - * @param[in] label The label to store the certificate. - */ -static CK_RV provisionCertificate( CK_SESSION_HANDLE session, - const char * certificate, - size_t certificateLength, - const char * label ); - -/** - * @brief Read the specified ECDSA public key into the MbedTLS ECDSA context. - * - * @param[in] p11Session The PKCS #11 session. - * @param[in] pEcdsaContext The context in which to store the key. - * @param[in] publicKey The public key to read. - */ -static int extractEcPublicKey( CK_SESSION_HANDLE p11Session, - mbedtls_ecdsa_context * pEcdsaContext, - CK_OBJECT_HANDLE publicKey ); - -/** - * @brief MbedTLS callback for signing using the provisioned private key. Used for - * signing the CSR. - * - * @param[in] pContext Unused. - * @param[in] mdAlg Unused. - * @param[in] pHash Data to sign. - * @param[in] hashLen Length of #pHash. - * @param[out] pSig The signature - * @param[out] pSigLen The length of the signature. - * @param[in] pRng Unused. - * @param[in] pRngContext Unused. - */ -static int32_t privateKeySigningCallback( void * pContext, - mbedtls_md_type_t mdAlg, - const unsigned char * pHash, - size_t hashLen, - unsigned char * pSig, - size_t * pSigLen, - int ( * pRng )( void *, unsigned char *, size_t ), - void * pRngContext ); - -/** - * @brief MbedTLS random generation callback to generate random values with - * PKCS #11. - * - * @param[in] pCtx Pointer to the PKCS #11 session handle. - * @param[out] pRandom Buffer to write random data to. - * @param[in] randomLength Length of random data to write. - */ -static int randomCallback( void * pCtx, - unsigned char * pRandom, - size_t randomLength ); - -/** - * @brief Generate a new ECDSA key pair using PKCS #11. - * - * @param[in] session The PKCS #11 session. - * @param[in] privateKeyLabel The label to store the private key. - * @param[in] publicKeyLabel The label to store the public key. - * @param[out] privateKeyHandlePtr The handle of the private key. - * @param[out] publicKeyHandlePtr The handle of the public key. - */ -static CK_RV generateKeyPairEC( CK_SESSION_HANDLE session, - const char * privateKeyLabel, - const char * publicKeyLabel, - CK_OBJECT_HANDLE_PTR privateKeyHandlePtr, - CK_OBJECT_HANDLE_PTR publicKeyHandlePtr ); - -/*-----------------------------------------------------------*/ - -static bool readFile( const char * path, - char * pBuffer, - size_t bufferLength, - size_t * pOutWrittenLength ) -{ - FILE * file; - size_t length = 0; - bool status = true; - - /* Get the file descriptor for the CSR file. */ - file = fopen( path, "rb" ); - - if( file == NULL ) - { - LogError( ( "Error opening file at path: %s. Error: %s.", - path, strerror( errno ) ) ); - status = false; - } - else - { - int result; - /* Seek to the end of the file, so that we can get the file size. */ - result = fseek( file, 0L, SEEK_END ); - - if( result == -1 ) - { - LogError( ( "Failed while moving to end of file. Path: %s. Error: %s.", - path, strerror( errno ) ) ); - status = false; - } - else - { - long lenResult = -1; - /* Get the current position which is the file size. */ - lenResult = ftell( file ); - - if( lenResult == -1 ) - { - LogError( ( "Failed to get length of file. Path: %s. Error: %s.", path, - strerror( errno ) ) ); - status = false; - } - else - { - length = ( size_t ) lenResult; - } - } - - if( status == true ) - { - if( length > bufferLength ) - { - LogError( ( "Buffer too small for file. Buffer size: %ld. Required size: %ld.", - bufferLength, length ) ); - status = false; - } - } - - if( status == true ) - { - /* Return to the beginning of the file. */ - result = fseek( file, 0L, SEEK_SET ); - - if( result == -1 ) - { - LogError( ( "Failed to move to beginning of file. Path: %s. Error: %s.", - path, strerror( errno ) ) ); - status = false; - } - } - - if( status == true ) - { - size_t written = 0; - /* Read the CSR into our buffer. */ - written = fread( pBuffer, 1, length, file ); - - if( written != length ) - { - LogError( ( "Failed reading file. Path: %s. Error: %s.", path, - strerror( errno ) ) ); - status = false; - } - else - { - *pOutWrittenLength = length; - } - } - - fclose( file ); - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static CK_RV destroyProvidedObjects( CK_SESSION_HANDLE session, - CK_BYTE_PTR * pkcsLabelsPtr, - CK_OBJECT_CLASS * pClass, - CK_ULONG count ) -{ - CK_RV result; - CK_FUNCTION_LIST_PTR functionList; - CK_OBJECT_HANDLE objectHandle; - CK_BYTE * labelPtr; - CK_ULONG index = 0; - - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - for( index = 0; index < count; index++ ) - { - labelPtr = pkcsLabelsPtr[ index ]; - - result = xFindObjectWithLabelAndClass( session, ( char * ) labelPtr, - strlen( ( char * ) labelPtr ), - pClass[ index ], &objectHandle ); - - while( ( result == CKR_OK ) && ( objectHandle != CK_INVALID_HANDLE ) ) - { - result = functionList->C_DestroyObject( session, objectHandle ); - - /* PKCS #11 allows a module to maintain multiple objects with the same - * label and type. The intent of this loop is to try to delete all of - * them. However, to avoid getting stuck, we won't try to find another - * object of the same label/type if the previous delete failed. */ - if( result == CKR_OK ) - { - result = xFindObjectWithLabelAndClass( session, ( char * ) labelPtr, - strlen( ( char * ) labelPtr ), - pClass[ index ], &objectHandle ); - } - else - { - break; - } - } - } - } - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionPrivateECKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ) -{ - CK_RV result = CKR_OK; - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_BYTE * DPtr = NULL; /* Private value D. */ - CK_BYTE * ecParamsPtr = NULL; /* DER-encoding of an ANSI X9.62 Parameters value */ - int mbedResult = 0; - CK_BBOOL trueObject = CK_TRUE; - CK_KEY_TYPE privateKeyType = CKK_EC; - CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY; - CK_OBJECT_HANDLE objectHandle = CK_INVALID_HANDLE; - mbedtls_ecp_keypair * keyPair = ( mbedtls_ecp_keypair * ) mbedPkContext->pk_ctx; - - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - DPtr = ( CK_BYTE * ) malloc( EC_D_LENGTH ); - - if( DPtr == NULL ) - { - result = CKR_HOST_MEMORY; - } - } - - if( result == CKR_OK ) - { - mbedResult = mbedtls_mpi_write_binary( &( keyPair->d ), DPtr, EC_D_LENGTH ); - - if( mbedResult != 0 ) - { - LogError( ( "Failed to parse EC private key components." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - } - - if( result == CKR_OK ) - { - if( keyPair->grp.id == MBEDTLS_ECP_DP_SECP256R1 ) - { - ecParamsPtr = ( CK_BYTE * ) ( "\x06\x08" MBEDTLS_OID_EC_GRP_SECP256R1 ); - } - else - { - result = CKR_CURVE_NOT_SUPPORTED; - } - } - - if( result == CKR_OK ) - { - CK_ATTRIBUTE privateKeyTemplate[] = - { - { CKA_CLASS, NULL /* &privateKeyClass*/, sizeof( CK_OBJECT_CLASS ) }, - { CKA_KEY_TYPE, NULL /* &privateKeyType*/, sizeof( CK_KEY_TYPE ) }, - { CKA_LABEL, ( void * ) label, ( CK_ULONG ) strlen( label ) }, - { CKA_TOKEN, NULL /* &trueObject*/, sizeof( CK_BBOOL ) }, - { CKA_SIGN, NULL /* &trueObject*/, sizeof( CK_BBOOL ) }, - { CKA_EC_PARAMS, NULL /* ecParamsPtr*/, EC_PARAMS_LENGTH }, - { CKA_VALUE, NULL /* DPtr*/, EC_D_LENGTH } - }; - - /* Aggregate initializers must not use the address of an automatic variable. */ - privateKeyTemplate[ 0 ].pValue = &privateKeyClass; - privateKeyTemplate[ 1 ].pValue = &privateKeyType; - privateKeyTemplate[ 3 ].pValue = &trueObject; - privateKeyTemplate[ 4 ].pValue = &trueObject; - privateKeyTemplate[ 5 ].pValue = ecParamsPtr; - privateKeyTemplate[ 6 ].pValue = DPtr; - - result = functionList->C_CreateObject( session, - ( CK_ATTRIBUTE_PTR ) &privateKeyTemplate, - sizeof( privateKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - &objectHandle ); - } - - if( DPtr != NULL ) - { - free( DPtr ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionPrivateRSAKey( CK_SESSION_HANDLE session, - const char * label, - mbedtls_pk_context * mbedPkContext ) -{ - CK_RV result = CKR_OK; - CK_FUNCTION_LIST_PTR functionList = NULL; - int mbedResult = 0; - CK_KEY_TYPE privateKeyType = CKK_RSA; - mbedtls_rsa_context * rsaContext = ( mbedtls_rsa_context * ) mbedPkContext->pk_ctx; - CK_OBJECT_CLASS privateKeyClass = CKO_PRIVATE_KEY; - RsaParams_t * rsaParams = NULL; - CK_BBOOL trueObject = CK_TRUE; - CK_OBJECT_HANDLE objectHandle = CK_INVALID_HANDLE; - - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - rsaParams = ( RsaParams_t * ) malloc( sizeof( RsaParams_t ) ); - - if( rsaParams == NULL ) - { - result = CKR_HOST_MEMORY; - } - } - - if( result == CKR_OK ) - { - memset( rsaParams, 0, sizeof( RsaParams_t ) ); - - mbedResult = mbedtls_rsa_export_raw( rsaContext, - rsaParams->modulus, MODULUS_LENGTH + 1, - rsaParams->prime1, PRIME_1_LENGTH + 1, - rsaParams->prime2, PRIME_2_LENGTH + 1, - rsaParams->d, D_LENGTH + 1, - rsaParams->e, E_LENGTH + 1 ); - - if( mbedResult != 0 ) - { - LogError( ( "Failed to parse RSA private key components." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - - /* Export Exponent 1, Exponent 2, Coefficient. */ - mbedResult |= mbedtls_mpi_write_binary( ( mbedtls_mpi const * ) &rsaContext->DP, rsaParams->exponent1, EXPONENT_1_LENGTH + 1 ); - mbedResult |= mbedtls_mpi_write_binary( ( mbedtls_mpi const * ) &rsaContext->DQ, rsaParams->exponent2, EXPONENT_2_LENGTH + 1 ); - mbedResult |= mbedtls_mpi_write_binary( ( mbedtls_mpi const * ) &rsaContext->QP, rsaParams->coefficient, COEFFICIENT_LENGTH + 1 ); - - if( mbedResult != 0 ) - { - LogError( ( "Failed to parse RSA private key Chinese Remainder Theorem variables." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - } - - if( result == CKR_OK ) - { - /* When importing the fields, the pointer is incremented by 1 - * to remove the leading 0 padding (if it existed) and the original field - * length is used */ - - CK_ATTRIBUTE privateKeyTemplate[] = - { - { CKA_CLASS, NULL /* &privateKeyClass */, sizeof( CK_OBJECT_CLASS ) }, - { CKA_KEY_TYPE, NULL /* &privateKeyType */, sizeof( CK_KEY_TYPE ) }, - { CKA_LABEL, ( void * ) label, ( CK_ULONG ) strlen( label ) }, - { CKA_TOKEN, NULL /* &trueObject */, sizeof( CK_BBOOL ) }, - { CKA_SIGN, NULL /* &trueObject */, sizeof( CK_BBOOL ) }, - { CKA_MODULUS, rsaParams->modulus + 1, MODULUS_LENGTH }, - { CKA_PRIVATE_EXPONENT, rsaParams->d + 1, D_LENGTH }, - { CKA_PUBLIC_EXPONENT, rsaParams->e + 1, E_LENGTH }, - { CKA_PRIME_1, rsaParams->prime1 + 1, PRIME_1_LENGTH }, - { CKA_PRIME_2, rsaParams->prime2 + 1, PRIME_2_LENGTH }, - { CKA_EXPONENT_1, rsaParams->exponent1 + 1, EXPONENT_1_LENGTH }, - { CKA_EXPONENT_2, rsaParams->exponent2 + 1, EXPONENT_2_LENGTH }, - { CKA_COEFFICIENT, rsaParams->coefficient + 1, COEFFICIENT_LENGTH } - }; - - /* Aggregate initializers must not use the address of an automatic variable. */ - privateKeyTemplate[ 0 ].pValue = &privateKeyClass; - privateKeyTemplate[ 1 ].pValue = &privateKeyType; - privateKeyTemplate[ 3 ].pValue = &trueObject; - privateKeyTemplate[ 4 ].pValue = &trueObject; - - result = functionList->C_CreateObject( session, - ( CK_ATTRIBUTE_PTR ) &privateKeyTemplate, - sizeof( privateKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - &objectHandle ); - } - - if( NULL != rsaParams ) - { - free( rsaParams ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionPrivateKey( CK_SESSION_HANDLE session, - const char * privateKey, - size_t privateKeyLength, - const char * label ) -{ - CK_RV result = CKR_OK; - mbedtls_pk_type_t mbedKeyType = MBEDTLS_PK_NONE; - int mbedResult = 0; - mbedtls_pk_context mbedPkContext = { 0 }; - - mbedtls_pk_init( &mbedPkContext ); - mbedResult = mbedtls_pk_parse_key( &mbedPkContext, ( const uint8_t * ) privateKey, - privateKeyLength, NULL, 0 ); - - if( mbedResult != 0 ) - { - LogError( ( "Unable to parse private key." ) ); - result = CKR_ARGUMENTS_BAD; - } - - /* Determine whether the key to be imported is RSA or EC. */ - if( result == CKR_OK ) - { - mbedKeyType = mbedtls_pk_get_type( &mbedPkContext ); - - if( mbedKeyType == MBEDTLS_PK_RSA ) - { - result = provisionPrivateRSAKey( session, label, &mbedPkContext ); - } - else if( ( mbedKeyType == MBEDTLS_PK_ECDSA ) || - ( mbedKeyType == MBEDTLS_PK_ECKEY ) || - ( mbedKeyType == MBEDTLS_PK_ECKEY_DH ) ) - { - result = provisionPrivateECKey( session, label, &mbedPkContext ); - } - else - { - LogError( ( "Invalid private key type provided. Only RSA-2048 and " - "EC P-256 keys are supported." ) ); - result = CKR_ARGUMENTS_BAD; - } - } - - mbedtls_pk_free( &mbedPkContext ); - - return result; -} - -/*-----------------------------------------------------------*/ - -static CK_RV provisionCertificate( CK_SESSION_HANDLE session, - const char * certificate, - size_t certificateLength, - const char * label ) -{ - PKCS11_CertificateTemplate_t certificateTemplate; - CK_OBJECT_CLASS certificateClass = CKO_CERTIFICATE; - CK_CERTIFICATE_TYPE certificateType = CKC_X_509; - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_RV result = CKR_OK; - uint8_t * derObject = NULL; - int32_t conversion = 0; - size_t derLen = 0; - CK_BBOOL tokenStorage = CK_TRUE; - CK_BYTE subject[] = "TestSubject"; - CK_OBJECT_HANDLE objectHandle = CK_INVALID_HANDLE; - - /* Initialize the client certificate template. */ - certificateTemplate.xObjectClass.type = CKA_CLASS; - certificateTemplate.xObjectClass.pValue = &certificateClass; - certificateTemplate.xObjectClass.ulValueLen = sizeof( certificateClass ); - certificateTemplate.xSubject.type = CKA_SUBJECT; - certificateTemplate.xSubject.pValue = subject; - certificateTemplate.xSubject.ulValueLen = strlen( ( const char * ) subject ); - certificateTemplate.xValue.type = CKA_VALUE; - certificateTemplate.xValue.pValue = ( CK_VOID_PTR ) certificate; - certificateTemplate.xValue.ulValueLen = ( CK_ULONG ) certificateLength; - certificateTemplate.xLabel.type = CKA_LABEL; - certificateTemplate.xLabel.pValue = ( CK_VOID_PTR ) label; - certificateTemplate.xLabel.ulValueLen = strlen( label ); - certificateTemplate.xCertificateType.type = CKA_CERTIFICATE_TYPE; - certificateTemplate.xCertificateType.pValue = &certificateType; - certificateTemplate.xCertificateType.ulValueLen = sizeof( CK_CERTIFICATE_TYPE ); - certificateTemplate.xTokenObject.type = CKA_TOKEN; - certificateTemplate.xTokenObject.pValue = &tokenStorage; - certificateTemplate.xTokenObject.ulValueLen = sizeof( tokenStorage ); - - if( certificate == NULL ) - { - LogError( ( "Certificate cannot be null." ) ); - result = CKR_ATTRIBUTE_VALUE_INVALID; - } - - if( result == CKR_OK ) - { - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - } - - if( result == CKR_OK ) - { - /* Convert the certificate to DER format from PEM. The DER key should - * be about 3/4 the size of the PEM key, so mallocing the PEM key size - * is sufficient. */ - derObject = ( uint8_t * ) malloc( certificateTemplate.xValue.ulValueLen ); - derLen = certificateTemplate.xValue.ulValueLen; - - if( derObject != NULL ) - { - conversion = convert_pem_to_der( ( unsigned char * ) certificateTemplate.xValue.pValue, - certificateTemplate.xValue.ulValueLen, - derObject, &derLen ); - - if( 0 != conversion ) - { - LogError( ( "Failed to convert provided certificate." ) ); - result = CKR_ARGUMENTS_BAD; - } - } - else - { - LogError( ( "Failed to allocate buffer for converting certificate to DER." ) ); - result = CKR_HOST_MEMORY; - } - } - - if( result == CKR_OK ) - { - /* Set the template pointers to refer to the DER converted objects. */ - certificateTemplate.xValue.pValue = derObject; - certificateTemplate.xValue.ulValueLen = derLen; - - /* Best effort clean-up of the existing object, if it exists. */ - destroyProvidedObjects( session, ( CK_BYTE_PTR * ) &label, &certificateClass, 1 ); - - /* Create an object using the encoded client certificate. */ - LogInfo( ( "Writing certificate into label \"%s\".", label ) ); - - result = functionList->C_CreateObject( session, - ( CK_ATTRIBUTE_PTR ) &certificateTemplate, - sizeof( certificateTemplate ) / sizeof( CK_ATTRIBUTE ), - &objectHandle ); - } - - if( derObject != NULL ) - { - free( derObject ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -bool loadClaimCredentials( CK_SESSION_HANDLE p11Session, - const char * pClaimCertPath, - const char * pClaimCertLabel, - const char * pClaimPrivKeyPath, - const char * pClaimPrivKeyLabel ) -{ - bool status; - char claimCert[ CLAIM_CERT_BUFFER_LENGTH ] = { 0 }; - size_t claimCertLength = 0; - char claimPrivateKey[ CLAIM_PRIVATE_KEY_BUFFER_LENGTH ] = { 0 }; - size_t claimPrivateKeyLength = 0; - CK_RV ret; - - assert( pClaimCertPath != NULL ); - assert( pClaimCertLabel != NULL ); - assert( pClaimPrivKeyPath != NULL ); - assert( pClaimPrivKeyLabel != NULL ); - - status = readFile( pClaimCertPath, claimCert, CLAIM_CERT_BUFFER_LENGTH, - &claimCertLength ); - - if( status == true ) - { - status = readFile( pClaimPrivKeyPath, claimPrivateKey, - CLAIM_PRIVATE_KEY_BUFFER_LENGTH, &claimPrivateKeyLength ); - } - - if( status == true ) - { - ret = provisionPrivateKey( p11Session, claimPrivateKey, - claimPrivateKeyLength + 1, /* MbedTLS includes null character in length for PEM objects. */ - pClaimPrivKeyLabel ); - status = ( ret == CKR_OK ); - } - - if( status == true ) - { - ret = provisionCertificate( p11Session, claimCert, - claimCertLength + 1, /* MbedTLS includes null character in length for PEM objects. */ - pClaimCertLabel ); - status = ( ret == CKR_OK ); - } - - return status; -} - -/*-----------------------------------------------------------*/ - -static int extractEcPublicKey( CK_SESSION_HANDLE p11Session, - mbedtls_ecdsa_context * pEcdsaContext, - CK_OBJECT_HANDLE publicKey ) -{ - CK_ATTRIBUTE ecTemplate = { 0 }; - int mbedtlsRet = -1; - CK_RV pkcs11ret = CKR_OK; - CK_BYTE ecPoint[ 67 ] = { 0 }; - CK_FUNCTION_LIST_PTR pP11FunctionList; - - mbedtls_ecdsa_init( pEcdsaContext ); - mbedtls_ecp_group_init( &( pEcdsaContext->grp ) ); - - pkcs11ret = C_GetFunctionList( &pP11FunctionList ); - - if( pkcs11ret != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - ecTemplate.type = CKA_EC_POINT; - ecTemplate.pValue = ecPoint; - ecTemplate.ulValueLen = sizeof( ecPoint ); - pkcs11ret = pP11FunctionList->C_GetAttributeValue( p11Session, publicKey, &ecTemplate, 1 ); - - if( pkcs11ret != CKR_OK ) - { - LogError( ( "Failed to extract EC public key. Could not get attribute value. " - "C_GetAttributeValue failed with %lu.", pkcs11ret ) ); - } - } - - if( pkcs11ret == CKR_OK ) - { - mbedtlsRet = mbedtls_ecp_group_load( &( pEcdsaContext->grp ), MBEDTLS_ECP_DP_SECP256R1 ); - - if( mbedtlsRet != 0 ) - { - LogError( ( "Failed creating an EC key. " - "mbedtls_ecp_group_load failed: MbedTLS" - "error = %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsRet ), - mbedtlsLowLevelCodeOrDefault( mbedtlsRet ) ) ); - pkcs11ret = CKR_FUNCTION_FAILED; - } - else - { - mbedtlsRet = mbedtls_ecp_point_read_binary( &( pEcdsaContext->grp ), &( pEcdsaContext->Q ), &ecPoint[ 2 ], ecTemplate.ulValueLen - 2 ); - - if( mbedtlsRet != 0 ) - { - LogError( ( "Failed creating an EC key. " - "mbedtls_ecp_group_load failed: MbedTLS" - "error = %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsRet ), - mbedtlsLowLevelCodeOrDefault( mbedtlsRet ) ) ); - pkcs11ret = CKR_FUNCTION_FAILED; - } - } - } - - return mbedtlsRet; -} - -/*-----------------------------------------------------------*/ - -static int32_t privateKeySigningCallback( void * pContext, - mbedtls_md_type_t mdAlg, - const unsigned char * pHash, - size_t hashLen, - unsigned char * pSig, - size_t * pSigLen, - int ( * pRng )( void *, unsigned char *, size_t ), - void * pRngContext ) -{ - CK_RV ret = CKR_OK; - int32_t result = 0; - CK_MECHANISM mech = { 0 }; - CK_BYTE toBeSigned[ 256 ]; - CK_ULONG toBeSignedLen = sizeof( toBeSigned ); - CK_FUNCTION_LIST_PTR functionList = NULL; - - /* Unreferenced parameters. */ - ( void ) ( pContext ); - ( void ) ( pRng ); - ( void ) ( pRngContext ); - ( void ) ( mdAlg ); - - /* Sanity check buffer length. */ - if( hashLen > sizeof( toBeSigned ) ) - { - ret = CKR_ARGUMENTS_BAD; - } - - mech.mechanism = CKM_ECDSA; - memcpy( toBeSigned, pHash, hashLen ); - toBeSignedLen = hashLen; - - if( ret == CKR_OK ) - { - ret = C_GetFunctionList( &functionList ); - } - - if( ret == CKR_OK ) - { - ret = functionList->C_SignInit( signingContext.p11Session, &mech, - signingContext.p11PrivateKey ); - } - - if( ret == CKR_OK ) - { - *pSigLen = sizeof( toBeSigned ); - ret = functionList->C_Sign( signingContext.p11Session, toBeSigned, - toBeSignedLen, pSig, ( CK_ULONG_PTR ) pSigLen ); - } - - if( ret == CKR_OK ) - { - /* PKCS #11 for P256 returns a 64-byte signature with 32 bytes for R and 32 - * bytes for S. This must be converted to an ASN.1 encoded array. */ - if( *pSigLen != pkcs11ECDSA_P256_SIGNATURE_LENGTH ) - { - ret = CKR_FUNCTION_FAILED; - LogError( ( "Failed to sign message using PKCS #11. Expected signature " - "length of %lu, but received %lu.", - ( unsigned long ) pkcs11ECDSA_P256_SIGNATURE_LENGTH, - ( unsigned long ) *pSigLen ) ); - } - - if( ret == CKR_OK ) - { - PKI_pkcs11SignatureTombedTLSSignature( pSig, pSigLen ); - } - } - - if( ret != CKR_OK ) - { - LogError( ( "Failed to sign message using PKCS #11 with error code %lu.", ret ) ); - result = -1; - } - - return result; -} - -/*-----------------------------------------------------------*/ - -static int randomCallback( void * pCtx, - unsigned char * pRandom, - size_t randomLength ) -{ - CK_SESSION_HANDLE * p11Session = ( CK_SESSION_HANDLE * ) pCtx; - CK_RV res; - CK_FUNCTION_LIST_PTR pP11FunctionList; - - res = C_GetFunctionList( &pP11FunctionList ); - - if( res != CKR_OK ) - { - LogError( ( "Failed to generate a random number in RNG callback. Could not get a " - "PKCS #11 function pointer." ) ); - } - else - { - res = pP11FunctionList->C_GenerateRandom( *p11Session, pRandom, randomLength ); - - if( res != CKR_OK ) - { - LogError( ( "Failed to generate a random number in RNG callback. " - "C_GenerateRandom failed with %lu.", res ) ); - } - } - - return ( int ) res; -} - -/*-----------------------------------------------------------*/ - -static CK_RV generateKeyPairEC( CK_SESSION_HANDLE session, - const char * privateKeyLabel, - const char * publicKeyLabel, - CK_OBJECT_HANDLE_PTR privateKeyHandlePtr, - CK_OBJECT_HANDLE_PTR publicKeyHandlePtr ) -{ - CK_RV result; - CK_MECHANISM mechanism = { CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0 }; - CK_FUNCTION_LIST_PTR functionList; - CK_BYTE ecParams[] = pkcs11DER_ENCODED_OID_P256; /* prime256v1 */ - CK_KEY_TYPE keyType = CKK_EC; - - CK_BBOOL trueObject = CK_TRUE; - CK_ATTRIBUTE publicKeyTemplate[] = - { - { CKA_KEY_TYPE, NULL /* &keyType */, sizeof( keyType ) }, - { CKA_VERIFY, NULL /* &trueObject */, sizeof( trueObject ) }, - { CKA_EC_PARAMS, NULL /* ecParams */, sizeof( ecParams ) }, - { CKA_LABEL, ( void * ) publicKeyLabel, strlen( publicKeyLabel ) } - }; - - /* Aggregate initializers must not use the address of an automatic variable. */ - publicKeyTemplate[ 0 ].pValue = &keyType; - publicKeyTemplate[ 1 ].pValue = &trueObject; - publicKeyTemplate[ 2 ].pValue = &ecParams; - - CK_ATTRIBUTE privateKeyTemplate[] = - { - { CKA_KEY_TYPE, NULL /* &keyType */, sizeof( keyType ) }, - { CKA_TOKEN, NULL /* &trueObject */, sizeof( trueObject ) }, - { CKA_PRIVATE, NULL /* &trueObject */, sizeof( trueObject ) }, - { CKA_SIGN, NULL /* &trueObject */, sizeof( trueObject ) }, - { CKA_LABEL, ( void * ) privateKeyLabel, strlen( privateKeyLabel ) } - }; - - /* Aggregate initializers must not use the address of an automatic variable. */ - privateKeyTemplate[ 0 ].pValue = &keyType; - privateKeyTemplate[ 1 ].pValue = &trueObject; - privateKeyTemplate[ 2 ].pValue = &trueObject; - privateKeyTemplate[ 3 ].pValue = &trueObject; - - result = C_GetFunctionList( &functionList ); - - if( result != CKR_OK ) - { - LogError( ( "Could not get a PKCS #11 function pointer." ) ); - } - else - { - result = functionList->C_GenerateKeyPair( session, - &mechanism, - publicKeyTemplate, - sizeof( publicKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - privateKeyTemplate, sizeof( privateKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - publicKeyHandlePtr, - privateKeyHandlePtr ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -bool generateKeyAndCsr( CK_SESSION_HANDLE p11Session, - const char * pPrivKeyLabel, - const char * pPubKeyLabel, - char * pCsrBuffer, - size_t csrBufferLength, - size_t * pOutCsrLength ) -{ - CK_OBJECT_HANDLE privKeyHandle; - CK_OBJECT_HANDLE pubKeyHandle; - CK_RV pkcs11Ret = CKR_OK; - mbedtls_pk_context privKey; - mbedtls_pk_info_t privKeyInfo; - mbedtls_ecdsa_context xEcdsaContext; - mbedtls_x509write_csr req; - int32_t mbedtlsRet = -1; - const mbedtls_pk_info_t * header = mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ); - - assert( pPrivKeyLabel != NULL ); - assert( pPubKeyLabel != NULL ); - assert( pCsrBuffer != NULL ); - assert( pOutCsrLength != NULL ); - - pkcs11Ret = generateKeyPairEC( p11Session, - pPrivKeyLabel, - pPubKeyLabel, - &privKeyHandle, - &pubKeyHandle ); - - if( pkcs11Ret == CKR_OK ) - { - mbedtls_x509write_csr_init( &req ); - mbedtls_x509write_csr_set_md_alg( &req, MBEDTLS_MD_SHA256 ); - - mbedtlsRet = mbedtls_x509write_csr_set_key_usage( &req, MBEDTLS_X509_KU_DIGITAL_SIGNATURE ); - - if( mbedtlsRet == 0 ) - { - mbedtlsRet = mbedtls_x509write_csr_set_ns_cert_type( &req, MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT ); - } - - if( mbedtlsRet == 0 ) - { - mbedtlsRet = mbedtls_x509write_csr_set_subject_name( &req, CSR_SUBJECT_NAME ); - } - - if( mbedtlsRet == 0 ) - { - mbedtls_pk_init( &privKey ); - } - - if( mbedtlsRet == 0 ) - { - mbedtlsRet = extractEcPublicKey( p11Session, &xEcdsaContext, pubKeyHandle ); - } - - if( mbedtlsRet == 0 ) - { - signingContext.p11Session = p11Session; - signingContext.p11PrivateKey = privKeyHandle; - - memcpy( &privKeyInfo, header, sizeof( mbedtls_pk_info_t ) ); - - privKeyInfo.sign_func = privateKeySigningCallback; - privKey.pk_info = &privKeyInfo; - privKey.pk_ctx = &xEcdsaContext; - - mbedtls_x509write_csr_set_key( &req, &privKey ); - - mbedtlsRet = mbedtls_x509write_csr_pem( &req, ( unsigned char * ) pCsrBuffer, - csrBufferLength, &randomCallback, - &p11Session ); - } - - mbedtls_x509write_csr_free( &req ); - mbedtls_ecdsa_free( &xEcdsaContext ); - mbedtls_ecp_group_free( &( xEcdsaContext.grp ) ); - } - - *pOutCsrLength = strlen( pCsrBuffer ); - - return( mbedtlsRet == 0 ); -} - -/*-----------------------------------------------------------*/ - -bool loadCertificate( CK_SESSION_HANDLE p11Session, - const char * pCertificate, - const char * pLabel, - size_t certificateLength ) -{ - CK_RV ret; - - assert( pCertificate != NULL ); - assert( pLabel != NULL ); - - ret = provisionCertificate( p11Session, - pCertificate, - certificateLength + 1, /* MbedTLS includes null character in length for PEM objects. */ - pLabel ); - - return( ret == CKR_OK ); -} - -/*-----------------------------------------------------------*/ - -bool pkcs11CloseSession( CK_SESSION_HANDLE p11Session ) -{ - CK_RV result = CKR_OK; - CK_FUNCTION_LIST_PTR functionList = NULL; - - result = C_GetFunctionList( &functionList ); - - if( result == CKR_OK ) - { - result = functionList->C_CloseSession( p11Session ); - } - - if( result == CKR_OK ) - { - result = functionList->C_Finalize( NULL ); - } - - return( result == CKR_OK ); -} - -/*-----------------------------------------------------------*/ diff --git a/demos/fleet_provisioning/fleet_provisioning_with_csr/pkcs11_operations.h b/demos/fleet_provisioning/fleet_provisioning_with_csr/pkcs11_operations.h deleted file mode 100644 index 21b4528018..0000000000 --- a/demos/fleet_provisioning/fleet_provisioning_with_csr/pkcs11_operations.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef PKCS11_OPERATIONS_H_ -#define PKCS11_OPERATIONS_H_ - -/* Standard includes. */ -#include -#include - -/* corePKCS11 include. */ -#include "core_pkcs11.h" - -/** - * @brief Loads the claim credentials into the PKCS #11 module. Claim - * credentials are used in "Provisioning by Claim" workflow of Fleet - * Provisioning feature of AWS IoT Core. For more information, refer to the - * [AWS documentation](https://docs.aws.amazon.com/iot/latest/developerguide/provision-wo-cert.html#claim-based) - * - * Note: This function is for demonstration purposes, and the claim credentials - * should be securely stored in production devices. For example, the - * shared claim credentials could be loaded into a secure element on the devices - * in your fleet at the time of manufacturing. - * - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pClaimCertPath Path to the claim certificate. - * @param[in] pClaimCertLabel PKCS #11 label for the claim certificate. - * @param[in] pClaimPrivKeyPath Path to the claim private key. - * @param[in] pClaimPrivKeyLabel PKCS #11 label for the claim private key. - * - * @return True on success. - */ -bool loadClaimCredentials( CK_SESSION_HANDLE p11Session, - const char * pClaimCertPath, - const char * pClaimCertLabel, - const char * pClaimPrivKeyPath, - const char * pClaimPrivKeyLabel ); - -/** - * @brief Generate a new public-private key pair in the PKCS #11 module, and - * generate a certificate signing request (CSR) for them. - * - * This device-generated private key and CSR can be used with the - * CreateCertificateFromCsr API of the the Fleet Provisioning feature of AWS IoT - * Core in order to provision a unique client certificate. - * - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pPrivKeyLabel PKCS #11 label for the private key. - * @param[in] pPubKeyLabel PKCS #11 label for the public key. - * @param[out] pCsrBuffer The buffer to write the CSR to. - * @param[in] csrBufferLength Length of #pCsrBuffer. - * @param[out] pOutCsrLength The length of the written CSR. - * - * @return True on success. - */ -bool generateKeyAndCsr( CK_SESSION_HANDLE p11Session, - const char * pPrivKeyLabel, - const char * pPubKeyLabel, - char * pCsrBuffer, - size_t csrBufferLength, - size_t * pOutCsrLength ); - -/** - * @brief Save the device client certificate into the PKCS #11 module. - * - * @param[in] p11Session The PKCS #11 session to use. - * @param[in] pCertificate The certificate to save. - * @param[in] pLabel PKCS #11 label for the certificate. - * @param[in] certificateLength Length of #pCertificate. - * - * @return True on success. - */ -bool loadCertificate( CK_SESSION_HANDLE p11Session, - const char * pCertificate, - const char * pLabel, - size_t certificateLength ); - -/** - * @brief Close the PKCS #11 session. - * - * @param[in] p11Session The PKCS #11 session to use. - * - * @return True on success. - */ -bool pkcs11CloseSession( CK_SESSION_HANDLE p11Session ); - -#endif /* ifndef PKCS11_OPERATIONS_H_ */ diff --git a/demos/pkcs11/common/include/core_pkcs11_config.h b/demos/pkcs11/common/include/core_pkcs11_config.h deleted file mode 100644 index 4a18c29ce6..0000000000 --- a/demos/pkcs11/common/include/core_pkcs11_config.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * @file core_pkcs11_config.h - * @brief PCKS#11 config options. - */ -#ifndef _CORE_PKCS11_CONFIG_H_ -#define _CORE_PKCS11_CONFIG_H_ - -/**************************************************/ -/******* DO NOT CHANGE the following order ********/ -/**************************************************/ - -/* Include logging header files and define logging macros in the following order: - * 1. Include the header file "logging_levels.h". - * 2. Define the LIBRARY_LOG_NAME and LIBRARY_LOG_LEVEL macros depending on - * the logging configuration for PKCS #11. - * 3. Include the header file "logging_stack.h", if logging is enabled for PKCS #11. - */ - -#include "logging_levels.h" - -/* Logging configuration for the PKCS #11 library. */ -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "PKCS11" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/************ End of logging configuration ****************/ - -#include - -/** - * @brief Malloc API used by core_pkcs11.h - */ -#define pkcs11configPKCS11_MALLOC malloc - -/** - * @brief Free API used by core_pkcs11.h - */ -#define pkcs11configPKCS11_FREE free - -/** - * @brief PKCS #11 default user PIN. - * - * The PKCS #11 standard specifies the presence of a user PIN. That feature is - * sensible for applications that have an interactive user interface and memory - * protections. However, since typical microcontroller applications lack one or - * both of those, the user PIN is assumed to be used herein for interoperability - * purposes only, and not as a security feature. - * - * Note: Do not cast this to a pointer! The library calls sizeof to get the length - * of this string. - */ -#define pkcs11configPKCS11_DEFAULT_USER_PIN "0000" - -/** - * @brief Maximum length (in characters) for a PKCS #11 CKA_LABEL - * attribute. - */ -#define pkcs11configMAX_LABEL_LENGTH 32UL - -/** - * @brief Maximum number of token objects that can be stored - * by the PKCS #11 module. - */ -#define pkcs11configMAX_NUM_OBJECTS 6 - -/** - * @brief Maximum number of sessions that can be stored - * by the PKCS #11 module. - */ -#define pkcs11configMAX_SESSIONS 10 - -/** - * @brief Set to 1 if a PAL destroy object is implemented. - * - * If set to 0, no PAL destroy object is implemented, and this functionality - * is implemented in the common PKCS #11 layer. - */ -#define pkcs11configPAL_DESTROY_SUPPORTED 0 - -/** - * @brief Set to 1 if OTA image verification via PKCS #11 module is supported. - * - * If set to 0, OTA code signing certificate is built in via - * aws_ota_codesigner_certificate.h. - */ -#define pkcs11configOTA_SUPPORTED 0 - -/** - * @brief Set to 1 if PAL supports storage for JITP certificate, - * code verify certificate, and trusted server root certificate. - * - * If set to 0, PAL does not support storage mechanism for these, and - * they are accessed via headers compiled into the code. - */ -#define pkcs11configJITP_CODEVERIFY_ROOT_CERT_SUPPORTED 0 - -/** - * @brief The PKCS #11 label for device private key. - * - * Private key for connection to AWS IoT endpoint. The corresponding - * public key should be registered with the AWS IoT endpoint. - */ -#define pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS "Device Priv TLS Key" - -/** - * @brief The PKCS #11 label for device public key. - * - * The public key corresponding to pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS. - */ -#define pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS "Device Pub TLS Key" - -/** - * @brief The PKCS #11 label for the device certificate. - * - * Device certificate corresponding to pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS. - */ -#define pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS "Device Cert" - -/** - * @brief The PKCS #11 label for the object to be used for HMAC operations. - */ -#define pkcs11configLABEL_HMAC_KEY "HMAC Key" - -/** - * @brief The PKCS #11 label for the object to be used for CMAC operations. - */ -#define pkcs11configLABEL_CMAC_KEY "CMAC Key" - -/** - * @brief The PKCS #11 label for the object to be used for code verification. - * - * Used by over-the-air update code to verify an incoming signed image. - */ -#define pkcs11configLABEL_CODE_VERIFICATION_KEY "Code Verify Key" - -/** - * @brief The PKCS #11 label for the claim certificate for Fleet Provisioning. - */ -#define pkcs11configLABEL_CLAIM_CERTIFICATE "Claim Cert" - -/** - * @brief The PKCS #11 label for the claim private key for Fleet Provisioning. - */ -#define pkcs11configLABEL_CLAIM_PRIVATE_KEY "Claim Key" - -/** - * @brief The PKCS #11 label for Just-In-Time-Provisioning. - * - * The certificate corresponding to the issuer of the device certificate - * (pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS) when using the JITR or - * JITP flow. - */ -#define pkcs11configLABEL_JITP_CERTIFICATE "JITP Cert" - -/** - * @brief The PKCS #11 label for the AWS Trusted Root Certificate. - * - * @see aws_default_root_certificates.h - */ -#define pkcs11configLABEL_ROOT_CERTIFICATE "Root Cert" - -#endif /* _CORE_PKCS11_CONFIG_H_ */ diff --git a/demos/pkcs11/common/include/demo_helpers.h b/demos/pkcs11/common/include/demo_helpers.h deleted file mode 100644 index c6d892f5dc..0000000000 --- a/demos/pkcs11/common/include/demo_helpers.h +++ /dev/null @@ -1,116 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ -#ifndef _DEMO_HELPER_FUNCTIONS_ -#define _DEMO_HELPER_FUNCTIONS_ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -/** - * @file demo_helpers.h - * @brief Common functions used between the PKCS #11 demos. - */ - -/* PKCS #11 include. */ -#include "core_pkcs11.h" - -/* mbed TLS include. */ -#include "mbedtls/pk.h" - -/* - * @brief demo label for the device certificate. - */ -#define pkcs11demoCERT_LABEL "Device Cert" - -/* - * @brief demo label for the device private key. - */ -#define pkcs11demoPRIVATE_KEY_LABEL "Device Priv TLS Key" - -/* - * @brief demo label for the device public key. - */ -#define pkcs11demoPUBLIC_KEY_LABEL "Device Pub TLS Key" - - -/* - * @brief This function contains standard setup code for PKCS #11. See the - * "management_and_rng.c" file for the demo code explaining this section - * of cryptoki. - * - * @param[in] pxSession Pointer to an uninitialized PKCS #11 session handle. - * This will be initialized by start. - * @param[in] ppxSlotId Pointer to a CK_SLOT_ID pointer. - * A valid slot will be set by start. - * - */ -CK_RV start( CK_SESSION_HANDLE * sssion, - CK_SLOT_ID ** slotId ); -/*-----------------------------------------------------------*/ - -/* @brief This function contains standard tear down code for PKCS #11. See the - * "management_and_rng.c" file for the demo code explaining this section - * of cryptoki. - * - * @param[in] xSession PKCS #11 session handle to uninitialized. - * @param[in] ppxSlotId PKCS #11 slot to close. - */ -void end( CK_SESSION_HANDLE session, - CK_SLOT_ID * slotId ); -/*-----------------------------------------------------------*/ - -/* - * @brief This function is simply a helper function to print the raw hex values - * of an EC public key. Its explanation is not within the scope of the demos - * and is sparsely commented. - * - * @param[in] description Description message - * @param[in] data Hex contents to print (Public key) - * @param[in] dataLength Length of data - * - */ -void writeHexBytesToConsole( const char * description, - CK_BYTE * data, - CK_ULONG dataLength ); -/*-----------------------------------------------------------*/ - -/* - * @brief This function is simply a helper function to export the raw hex values - * of an EC public key into a buffer. It's explanation is not within the - * scope of the demos and is sparsely commented. - */ -CK_RV exportPublicKey( CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE publicKeyHandle, - CK_BYTE ** derPublicKey, - CK_ULONG * derPublicKeyLength ); -/*-----------------------------------------------------------*/ - -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -#endif /* _DEMO_HELPER_FUNCTIONS_ */ diff --git a/demos/pkcs11/common/src/demo_helpers.c b/demos/pkcs11/common/src/demo_helpers.c deleted file mode 100644 index 2285e63bb4..0000000000 --- a/demos/pkcs11/common/src/demo_helpers.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * @file demo_helpers.c - * @brief Common functions used between the PKCS #11 demos. - */ -/* Standard includes. */ -#include -#include - -/* Log includes. */ -#include "logging_levels.h" -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "PKCS11_DEMO_HELPERS" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/* PKCS #11 includes. */ -#include "core_pkcs11.h" -#include "pkcs11.h" - -/* mbed TLS includes. */ -#include "mbedtls/pk.h" -#include "mbedtls/oid.h" - -/* Helpers include. */ -#include "demo_helpers.h" - - -/* - * @brief macro to help print public key hex to serial. - */ -#define BYTES_TO_DISPLAY_PER_ROW 16 -/*-----------------------------------------------------------*/ - -CK_RV start( CK_SESSION_HANDLE * session, - CK_SLOT_ID ** slotId ) -{ - CK_RV result = CKR_OK; - - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_C_INITIALIZE_ARGS initArgs = { 0 }; - CK_SESSION_HANDLE tempSession = CK_INVALID_HANDLE; - CK_ULONG slotCount = 0; - CK_SLOT_ID * innerSlotId = NULL; - - result = C_GetFunctionList( &functionList ); - - if( result == CKR_OK ) - { - result = functionList->C_Initialize( &initArgs ); - } - - if( result == CKR_OK ) - { - result = functionList->C_GetSlotList( CK_TRUE, - NULL, - &slotCount ); - } - - innerSlotId = malloc( sizeof( CK_SLOT_ID ) * ( slotCount ) ); - - if( innerSlotId == NULL ) - { - result = CKR_HOST_MEMORY; - } - - if( result == CKR_OK ) - { - result = functionList->C_GetSlotList( CK_TRUE, - innerSlotId, - &slotCount ); - } - - if( result == CKR_OK ) - { - result = functionList->C_OpenSession( innerSlotId[ 0 ], - CKF_SERIAL_SESSION | CKF_RW_SESSION, - NULL, /* Application defined pointer. */ - NULL, /* Callback function. */ - &tempSession ); - } - - if( result == CKR_OK ) - { - result = functionList->C_Login( tempSession, - CKU_USER, - ( CK_UTF8CHAR_PTR ) "0000", - sizeof( "0000" ) - 1UL ); - } - - *slotId = innerSlotId; - *session = tempSession; - - return result; -} -/*-----------------------------------------------------------*/ - -void end( CK_SESSION_HANDLE session, - CK_SLOT_ID * slotId ) -{ - C_CloseSession( session ); - C_Finalize( NULL ); - free( slotId ); -} -/*-----------------------------------------------------------*/ - -void writeHexBytesToConsole( const char * description, - CK_BYTE * data, - CK_ULONG dataLength ) -{ - /* This function is simply a helper function to print the raw hex values - * of an EC public key. Its explanation is not within the scope of the demos - * and is sparsely commented. */ - char byteRow[ 1 + ( BYTES_TO_DISPLAY_PER_ROW * 2 ) + ( BYTES_TO_DISPLAY_PER_ROW / 2 ) ]; - char * nextChar = byteRow; - uint32_t index = 0; - uint8_t byteValue = 0; - - ( void ) description; - - /* Write help text to the console. */ - LogInfo( ( "%s, %lu bytes:", description, dataLength ) ); - - /* Iterate over the bytes of the encoded public key. */ - for( index = 0; index < dataLength; index++ ) - { - /* Convert one byte to ASCII hex. */ - byteValue = *( data + index ); - snprintf( nextChar, - sizeof( byteRow ) - ( nextChar - byteRow ), - "%02x", - byteValue ); - nextChar += 2; - - /* Check for the end of a two-byte display word. */ - if( 0 == ( ( index + 1 ) % sizeof( uint16_t ) ) ) - { - *nextChar = ' '; - nextChar++; - } - - /* Check for the end of a row. */ - if( 0 == ( ( index + 1 ) % BYTES_TO_DISPLAY_PER_ROW ) ) - { - *nextChar = '\0'; - LogInfo( ( "%s", byteRow ) ); - nextChar = byteRow; - } - } - - /* Check for a partial line to print. */ - if( nextChar > byteRow ) - { - *nextChar = '\0'; - LogInfo( ( "%s", byteRow ) ); - } -} -/*-----------------------------------------------------------*/ - -CK_RV exportPublicKey( CK_SESSION_HANDLE session, - CK_OBJECT_HANDLE publicKeyHandle, - CK_BYTE ** derPublicKey, - CK_ULONG * derPublicKeyLength ) -{ - /* This function is simply a helper function to export the raw hex values - * of an EC public key into a buffer. It's explanation is not within the - * scope of the demos and is sparsely commented. */ - CK_RV result; - CK_FUNCTION_LIST_PTR functionList; - CK_KEY_TYPE keyType = 0; - CK_ATTRIBUTE template = { 0 }; - uint8_t ecP256AsnOid[] = - { - 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 - }; - uint8_t unusedKeyTag[] = { 0x04, 0x41 }; - - /* This variable is used only for its size. This gets rid of compiler warnings. */ - ( void ) unusedKeyTag; - - result = C_GetFunctionList( &functionList ); - - /* Query the key type. */ - if( CKR_OK == result ) - { - template.type = CKA_KEY_TYPE; - template.pValue = &keyType; - template.ulValueLen = sizeof( keyType ); - result = functionList->C_GetAttributeValue( session, - publicKeyHandle, - &template, - 1 ); - } - - /* Scope to ECDSA keys only, since there's currently no use case for - * onboard keygen and certificate enrollment for RSA. */ - if( ( CKR_OK == result ) && ( CKK_ECDSA == keyType ) ) - { - /* Query the size of the public key. */ - template.type = CKA_EC_POINT; - template.pValue = NULL; - template.ulValueLen = 0; - result = functionList->C_GetAttributeValue( session, - publicKeyHandle, - &template, - 1 ); - - /* Allocate a buffer large enough for the full, encoded public key. */ - if( CKR_OK == result ) - { - /* Add space for the full DER header. */ - template.ulValueLen += sizeof( ecP256AsnOid ) - sizeof( unusedKeyTag ); - *derPublicKeyLength = template.ulValueLen; - - /* Get a heap buffer. */ - *derPublicKey = malloc( template.ulValueLen ); - - /* Check for resource exhaustion. */ - if( NULL == *derPublicKey ) - { - result = CKR_HOST_MEMORY; - } - } - - /* Export the public key. */ - if( CKR_OK == result ) - { - template.pValue = *derPublicKey + sizeof( ecP256AsnOid ) - sizeof( unusedKeyTag ); - template.ulValueLen -= ( sizeof( ecP256AsnOid ) - sizeof( unusedKeyTag ) ); - result = functionList->C_GetAttributeValue( session, - publicKeyHandle, - &template, - 1 ); - } - - /* Prepend the full DER header. */ - if( CKR_OK == result ) - { - memcpy( *derPublicKey, ecP256AsnOid, sizeof( ecP256AsnOid ) ); - } - } - - /* Free memory if there was an error after allocation. */ - if( ( NULL != *derPublicKey ) && ( CKR_OK != result ) ) - { - free( *derPublicKey ); - *derPublicKey = NULL; - } - - return result; -} -/*-----------------------------------------------------------*/ diff --git a/demos/pkcs11/pkcs11_demo_management_and_rng/CMakeLists.txt b/demos/pkcs11/pkcs11_demo_management_and_rng/CMakeLists.txt deleted file mode 100644 index 855ec83725..0000000000 --- a/demos/pkcs11/pkcs11_demo_management_and_rng/CMakeLists.txt +++ /dev/null @@ -1,40 +0,0 @@ -set( DEMO_NAME "pkcs11_demo_management_and_rng" ) - -# Set path to corePKCS11 and it's third party libraries. -set(COREPKCS11_LOCATION "${CMAKE_SOURCE_DIR}/libraries/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") - -# Include PKCS #11 library's source and header path variables. -include( ${COREPKCS11_LOCATION}/pkcsFilePaths.cmake ) - -list(APPEND PKCS_SOURCES - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c" -) - -file( GLOB DEMO_SRCS "*.c*" ) - -# Demo target. -add_executable( - ${DEMO_NAME} - ${DEMO_SRCS} - ${PKCS_SOURCES} - ${PKCS_PAL_POSIX_SOURCES} -) - -target_link_libraries( - ${DEMO_NAME} - PRIVATE - mbedtls -) - -target_include_directories( - ${DEMO_NAME} - PUBLIC - "${DEMOS_DIR}/pkcs11/common/include" - ${PKCS_INCLUDE_PUBLIC_DIRS} - ${PKCS_PAL_INCLUDE_PUBLIC_DIRS} - ${CMAKE_CURRENT_LIST_DIR} - ${LOGGING_INCLUDE_DIRS} - PRIVATE - ${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils -) diff --git a/demos/pkcs11/pkcs11_demo_management_and_rng/pkcs11_demo_management_and_rng.c b/demos/pkcs11/pkcs11_demo_management_and_rng/pkcs11_demo_management_and_rng.c deleted file mode 100644 index 5a01c9b05a..0000000000 --- a/demos/pkcs11/pkcs11_demo_management_and_rng/pkcs11_demo_management_and_rng.c +++ /dev/null @@ -1,245 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Standard includes. */ -#include -#include - -/* Logging configuration for the PKCS #11 library. */ -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "PKCS11_RNG_DEMO" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/* PKCS #11 includes. */ -#include "core_pkcs11.h" -#include "pkcs11.h" - -/** - * @brief This function details how to use the PKCS #11 "Management" functions to - * manage the internal state machine of the PKCS #11 implementation. These - * functions are all defined in - * https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html - * Please consult the standard for more information regarding these functions. - * - * The standard has grouped the functions presented in this demo as: - * General Purpose Functions - * Slot and Token Management Functions - * Session Management Functions - * Random Number Generation Functions - */ -CK_RV PKCS11ManagementAndRNGDemo( void ) -{ - /* We will use the terminology as defined in the standard, Cryptoki is in - * reference to the Cryptographic Token Interface defined in the PKCS #11 - * standard. An implementation of Cryptoki is referred to as a - * "Cryptoki library". */ - LogInfo( ( "Starting PKCS #11 Management and Random Number Generation" - " Demo." ) ); - - /* CK_RV is the return type for a Cryptoki function. Generally the underlying - * type is a CK_ULONG, it can also be a CKR_VENDOR_DEFINED type. */ - CK_RV result = CKR_OK; - - /* The CK_FUNCTION_LIST is a structure that contains the Cryptoki version - * and a function pointer to each function in the Cryptoki API. If the - * function pointer is NULL it is unimplemented. */ - CK_FUNCTION_LIST_PTR functionList = NULL; - - /* This Cryptoki library does not implement any initialization arguments. At the time of - * writing this demo, the purpose of these optional arguments is to provide - * function pointers for mutex operations. */ - CK_C_INITIALIZE_ARGS initArgs = { 0 }; - - /* A slot ID is an integer that defines a slot. The Cryptoki definition of - * a slot is "A logical reader that potentially contains a token." - * - * Essentially it is an abstraction for accessing the token. The reason for - * this is Some tokens are a physical "card' that needs to be inserted into - * a slot for the device to read. - * - * A concrete example of a slot could be a USB Hardware Security Module (HSM), - * which generally appears as a singular slot, and abstracts it's internal "token". - * - * Some implementations have multiple slots mapped to a single token, or maps - * a slot per token. */ - CK_SLOT_ID * slotId = NULL; - - /* A session is defined to be "The logical connection between an application - * and a token." - * - * The session can either be private or public, and differentiates - * your application from the other users of the token. */ - CK_SESSION_HANDLE session = CK_INVALID_HANDLE; - - /* Helper variables. */ - CK_BYTE randomData[ 10 ] = { 0 }; - uint32_t index = 0; - CK_ULONG slotCount = 0; - - /* We use the function list returned by C_GetFunctionList to see what functions - * the Cryptoki library supports. We use asserts to ensure that all the - * functionality needed in this demo is available. */ - result = C_GetFunctionList( &functionList ); - - if( result == CKR_OK ) - { - LogInfo( ( "Cryptoki Major Version: %u Minor Version: %u", - functionList->version.major, - functionList->version.minor ) ); - - /* C_Initialize will initialize the Cryptoki library and the hardware it - * abstracts. */ - result = functionList->C_Initialize( &initArgs ); - } - - /* C_GetSlotList will retrieve an array of CK_SLOT_IDs. - * This Cryptoki library does not implement slots, but it is important to - * highlight how Cryptoki can be used to interface with real hardware. - * - * By setting the first argument "tokenPresent" to true, we only retrieve - * slots that have a token. If the second argument "pSlotList" is NULL, the - * third argument "pulCount" will be modified to contain the total slots. */ - if( result == CKR_OK ) - { - result = functionList->C_GetSlotList( CK_TRUE, - NULL, - &slotCount ); - } - - /* Since C_GetSlotList does not allocate the memory itself for getting a list - * of CK_SLOT_ID, we allocate one for it to populate with the list of - * slot ids. */ - if( result == CKR_OK ) - { - slotId = ( CK_SLOT_ID * ) malloc( sizeof( CK_SLOT_ID ) * ( slotCount ) ); - - if( slotId == NULL ) - { - result = CKR_HOST_MEMORY; - } - } - - /* Now since pSlotList is not NULL, C_GetSlotList will populate it with the - * available slots. */ - if( result == CKR_OK ) - { - result = functionList->C_GetSlotList( CK_TRUE, - slotId, - &slotCount ); - } - - /* Since this Cryptoki library does not actually implement the concept of slots, - * but we will use the first available slot, so the demo code conforms to - * Cryptoki. - * - * C_OpenSession will establish a session between the application and - * the token and we can then use the returned CK_SESSION_HANDLE for - * cryptographic operations with the token. - * - * For legacy reasons, Cryptoki demands that the CKF_SERIAL_SESSION bit - * is always set. */ - if( result == CKR_OK ) - { - result = functionList->C_OpenSession( slotId[ 0 ], - CKF_SERIAL_SESSION | CKF_RW_SESSION, - NULL, /* Application defined pointer. */ - NULL, /* Callback function. */ - &session ); - } - - /* C_Login is called to log the user in to the token. The login status is - * shared between sessions, so logging in once is sufficient for all the sessions - * tied to the token. Most of the behavior for C_Login is defined by the token - * so it may be necessary to modify calls to C_Login when switching to a different - * Cryptoki library or token. - * - * This Cryptoki library does not implement C_Login, and only defines the function - * for compatibility reasons. - */ - if( result == CKR_OK ) - { - result = functionList->C_Login( session, - CKU_USER, - ( CK_UTF8CHAR_PTR ) "0000", - sizeof( "0000" ) - 1UL ); - } - - /* C_GenerateRandom generates random or pseudo random data. As arguments it - * takes the application session, and a pointer to a byte buffer, as well as - * the length of the byte buffer. Then it will fill this buffer with random - * bytes. */ - - if( result == CKR_OK ) - { - result = functionList->C_GenerateRandom( session, - randomData, - sizeof( randomData ) ); - - for( index = 0; index < sizeof( randomData ); index++ ) - { - LogInfo( ( "Generated random number: %x", randomData[ index ] ) ); - } - } - - /* C_CloseSession closes the session that was established between the - * application and the token. This will clean up the resources that maintained - * the link between the application and the token. If the application wishes - * to use the token again, it will need to open a new session. */ - if( result == CKR_OK ) - { - result = functionList->C_CloseSession( session ); - } - - /* C_Finalize signals to the Cryptoki library that the application is done - * using it. It should always be the last call to the Cryptoki library. - * NULL should always be passed as the argument, as the parameter is currently - * just reserved for future revisions. - * - * Calling this function in a multi threaded environment can lead to undefined - * behavior if other threads are accessing the Cryptoki library. */ - if( result == CKR_OK ) - { - result = functionList->C_Finalize( NULL ); - } - - LogInfo( ( "Finished PKCS #11 Management and Random Number Generation" - " Demo." ) ); - - free( slotId ); - return result; -} - -/** - * @brief Entry point of demo. - * - * The example shown above uses PKCS #11 APIs to manage state and generate random numbers. - */ -int main( void ) -{ - return PKCS11ManagementAndRNGDemo(); -} diff --git a/demos/pkcs11/pkcs11_demo_mechanisms_and_digests/CMakeLists.txt b/demos/pkcs11/pkcs11_demo_mechanisms_and_digests/CMakeLists.txt deleted file mode 100644 index f765f4f966..0000000000 --- a/demos/pkcs11/pkcs11_demo_mechanisms_and_digests/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -set( DEMO_NAME "pkcs11_demo_mechanisms_and_digests" ) - -# Set path to corePKCS11 and its third party libraries. -set(COREPKCS11_LOCATION "${CMAKE_SOURCE_DIR}/libraries/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") - -# Include PKCS #11 library's source and header path variables. -include( ${COREPKCS11_LOCATION}/pkcsFilePaths.cmake ) - -list(APPEND PKCS_SOURCES - "${DEMOS_DIR}/pkcs11/common/src/demo_helpers.c" - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c" - ) - -file( GLOB DEMO_SRCS "*.c*" ) - -# Demo target. -add_executable( - ${DEMO_NAME} - ${DEMO_SRCS} - ${PKCS_SOURCES} - ${PKCS_PAL_POSIX_SOURCES} -) - -target_link_libraries( - ${DEMO_NAME} - PRIVATE - mbedtls -) - -target_include_directories( - ${DEMO_NAME} - PUBLIC - "${DEMOS_DIR}/pkcs11/common/include" - ${PKCS_INCLUDE_PUBLIC_DIRS} - ${PKCS_PAL_INCLUDE_PUBLIC_DIRS} - ${CMAKE_CURRENT_LIST_DIR} - ${LOGGING_INCLUDE_DIRS} - PRIVATE - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils" -) diff --git a/demos/pkcs11/pkcs11_demo_mechanisms_and_digests/pkcs11_demo_mechanisms_and_digests.c b/demos/pkcs11/pkcs11_demo_mechanisms_and_digests/pkcs11_demo_mechanisms_and_digests.c deleted file mode 100644 index b97ffbb55e..0000000000 --- a/demos/pkcs11/pkcs11_demo_mechanisms_and_digests/pkcs11_demo_mechanisms_and_digests.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Standard includes. */ -#include -#include - -/* Logging configuration for the PKCS #11 Demo. */ -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "PKCS11_MECH_AND_DIGEST_DEMO" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/* PKCS #11 includes. */ -#include "core_pkcs11.h" -#include "pkcs11.h" - -/* Demo includes. */ -#include "demo_helpers.h" - -/** - * @brief This function details what Cryptoki mechanisms are, how to query a slot's - * support for them, and how to use those mechanisms to generate a hash of a buffer. - * This can then be used as a message digest. - * - * https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html - * please consult the standard for more information. - * - * The standard has grouped the functions presented in this demo as: - * Slot and token management functions. - * Message digesting functions. - * - */ -CK_RV PKCS11MechanismsAndDigestDemo( void ) -{ - /* - * This demo builds upon the demo found in "management_and_rng.c". It borrows - * code and terminology defined and explained, and it is recommended to complete - * the "management and rng" demo before this one. - */ - LogInfo( ( "Starting PKCS #11 Mechanisms and Digest Demo." ) ); - - CK_SESSION_HANDLE session = CK_INVALID_HANDLE; - CK_SLOT_ID * slotId = 0; - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_ULONG index = 0; - CK_RV result = CKR_OK; - CK_BYTE hashFormatBuffer[ pkcs11SHA256_DIGEST_LENGTH * 2 ] = { 0 }; - CK_BYTE_PTR formatPtr = NULL; - - /* The PKCS #11 standard defines a mechanism to be a "A process for - * implementing a cryptographic operation." For example the SHA-256 algorithm - * will be the mechanism used in this demo to perform a digest (hash operation). - * - * The mechanism types are defined in "pkcs11t.h", and are prefixed CKM_, to - * provide a portable way to identify mechanisms. - */ - CK_MECHANISM_TYPE xMechanismType = 0; - - /* This variable is not directly used, but is instantiated for demonstration - * purposes. - */ - ( void ) xMechanismType; - - /* The CK_MECHANISM_INFO allows the application to retrieve the minimum and - * maximum key sizes supported by the mechanism (could be in bits or bytes). - * The structure also has a flags field, that is populated with bit flags - * for what features the mechanism supports. - */ - CK_MECHANISM_INFO MechanismInfo = { 0 }; - - /* The CK_MECHANISM type contains the mechanism type, as well as a pointer - * for mechanism parameters and a CK_ULONG indicating the length of the - * parameters. - */ - CK_MECHANISM xDigestMechanism = { 0 }; - - /* The digest will return a hash of the known SHA-256 hash size, 32 bytes. - * Please see this page for further explanation of the SHA-256 hash. - * https://en.wikipedia.org/wiki/SHA-2 - */ - CK_BYTE digestResult[ pkcs11SHA256_DIGEST_LENGTH ] = { 0 }; - CK_ULONG digestLength = pkcs11SHA256_DIGEST_LENGTH; - - CK_BYTE knownMessage[] = "Hello world!"; - - start( &session, &slotId ); - result = C_GetFunctionList( &functionList ); - - /*************************** RSA Capabilities ***************************/ - if( result == CKR_OK ) - { - result = functionList->C_GetMechanismInfo( slotId[ 0 ], - CKM_RSA_PKCS, - &MechanismInfo ); - - /* Check to see if the slot supports signing. This capability is important - * because we want to use the Cryptoki API to sign messages, without directly - * accessing the private key. This concept will be explained further in the - * "sign_verify.c" demo, but for now we will just check that the slot has the - * capabilities we need. See https://en.wikipedia.org/wiki/Public-key_cryptography - * for more information regarding private keys and public keys. - */ - if( 0 != ( CKF_SIGN & MechanismInfo.flags ) ) - { - LogInfo( ( "This Cryptoki library supports signing messages with RSA" - " private keys." ) ); - } - else - { - LogInfo( ( "This Cryptoki library does not support signing messages" - " with RSA private keys." ) ); - } - } - - /* Check for pre-padded signature verification support, this feature will - * be used in the "sign_verify.c" demo. - */ - if( result == CKR_OK ) - { - result = functionList->C_GetMechanismInfo( slotId[ 0 ], - CKM_RSA_X_509, - &MechanismInfo ); - - /* If this fails, the slot is not able to verify the signature using - * a RSA public key. Please see https://en.wikipedia.org/wiki/Public_key_infrastructure - * for more information regarding PKI (Public Key Infrastructure). - */ - if( 0 != ( CKF_VERIFY & MechanismInfo.flags ) ) - { - LogInfo( ( "This Cryptoki library supports verifying messages with RSA" - " public keys." ) ); - } - else - { - LogInfo( ( "This Cryptoki library does not support verifying messages" - " with RSA public keys." ) ); - } - } - - /*************************** ECDSA Capabilities ***************************/ - if( result == CKR_OK ) - { - result = functionList->C_GetMechanismInfo( slotId[ 0 ], - CKM_ECDSA, - &MechanismInfo ); - - if( 0 != ( CKF_SIGN & MechanismInfo.flags ) ) - { - LogInfo( ( "This Cryptoki library supports signing messages with" - " ECDSA private keys." ) ); - } - else - { - LogInfo( ( "This Cryptoki library does not support signing messages" - " with ECDSA private keys." ) ); - } - - if( 0 != ( CKF_VERIFY & MechanismInfo.flags ) ) - { - LogInfo( ( "This Cryptoki library supports verifying messages with" - " ECDSA public keys." ) ); - } - else - { - LogInfo( ( "This Cryptoki library does not support verifying" - " messages with ECDSA public keys." ) ); - } - } - - /************************** Digest Capabilities **************************/ - if( result == CKR_OK ) - { - result = functionList->C_GetMechanismInfo( slotId[ 0 ], - CKM_SHA256, - &MechanismInfo ); - - if( 0 != ( CKF_DIGEST & MechanismInfo.flags ) ) - { - LogInfo( ( "The Cryptoki library supports the " - "SHA-256 algorithm." ) ); - } - else - { - LogInfo( ( "The Cryptoki library doesn't support the " - "SHA-256 algorithm." ) ); - } - } - - /***************************** Buffer Digest *****************************/ - /* Hash with SHA256 mechanism. */ - xDigestMechanism.mechanism = CKM_SHA256; - - /* Initializes the digest operation and sets what mechanism will be used - * for the digest. */ - if( result == CKR_OK ) - { - result = functionList->C_DigestInit( session, - &xDigestMechanism ); - } - - /* Pass a pointer to the buffer of bytes to be hashed, and it's size. */ - if( result == CKR_OK ) - { - result = functionList->C_DigestUpdate( session, - knownMessage, - /* Strip NULL Terminator. */ - sizeof( knownMessage ) - 1 ); - } - - /* Retrieve the digest buffer. Since the mechanism is a SHA-256 algorithm, - * the size will always be 32 bytes. If the size cannot be known ahead of time, - * a NULL value to the second parameter pDigest, will set the third parameter, - * pulDigestLen to the number of required bytes. */ - if( result == CKR_OK ) - { - result = functionList->C_DigestFinal( session, - digestResult, - &digestLength ); - } - - if( result == CKR_OK ) - { - /* This will now print out the digest of the known message. You can compare - * the hash generated by the Cryptoki library in a UNIX shell by using the - * command '$ echo -n "{knownMessage}" | shasum -a 256' - * this command should generate the same hash. */ - LogInfo( ( "Known message: %s", ( char * ) knownMessage ) ); - - formatPtr = &hashFormatBuffer[ 0 ]; - - for( index = 0; index < digestLength; index++ ) - { - formatPtr += sprintf( ( char * ) formatPtr, "%x", digestResult[ index ] ); - } - - LogInfo( ( "Hash of known message using SHA256: %s.", hashFormatBuffer ) ); - LogInfo( ( "Finished PKCS #11 Mechanisms and Digest Demo." ) ); - } - - end( session, slotId ); - return result; -} - -/** - * @brief Entry point of demo. - * - * The example shown above uses PKCS #11 APIs to specify mechanisms and how to create a digest. - */ -int main( void ) -{ - return PKCS11MechanismsAndDigestDemo(); -} diff --git a/demos/pkcs11/pkcs11_demo_objects/CMakeLists.txt b/demos/pkcs11/pkcs11_demo_objects/CMakeLists.txt deleted file mode 100644 index e03a311098..0000000000 --- a/demos/pkcs11/pkcs11_demo_objects/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -set( DEMO_NAME "pkcs11_demo_objects" ) - -# Set path to corePKCS11 and it's third party libraries. -set(COREPKCS11_LOCATION "${CMAKE_SOURCE_DIR}/libraries/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") - -# Include PKCS #11 library's source and header path variables. -include( ${COREPKCS11_LOCATION}/pkcsFilePaths.cmake ) - -list(APPEND PKCS_SOURCES - "../common/src/demo_helpers.c" - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c" - ) - -file( GLOB DEMO_SRCS "*.c*" ) - -# Demo target. -add_executable( - ${DEMO_NAME} - ${DEMO_SRCS} - ${PKCS_SOURCES} - ${PKCS_PAL_POSIX_SOURCES} -) - -target_link_libraries( - ${DEMO_NAME} - PRIVATE - mbedtls -) - -target_include_directories( - ${DEMO_NAME} - PUBLIC - "${DEMOS_DIR}/pkcs11/common/include" - ${PKCS_INCLUDE_PUBLIC_DIRS} - ${PKCS_PAL_INCLUDE_PUBLIC_DIRS} - ${CMAKE_CURRENT_LIST_DIR} - ${LOGGING_INCLUDE_DIRS} - PRIVATE - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils" -) - diff --git a/demos/pkcs11/pkcs11_demo_objects/pkcs11_demo_objects.c b/demos/pkcs11/pkcs11_demo_objects/pkcs11_demo_objects.c deleted file mode 100644 index 04b3d57b3b..0000000000 --- a/demos/pkcs11/pkcs11_demo_objects/pkcs11_demo_objects.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Standard include. */ -#include -#include -#include - -/* Logging configuration for the PKCS #11 Demo. */ -#include "logging_levels.h" -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "PKCS11_OBJECTS_DEMO" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/* PKCS #11 includes. */ -#include "core_pkcs11.h" -#include "pkcs11.h" - -/* mbed TLS includes. */ -#include "mbedtls/pk.h" - -/* Demo includes. */ -#include "demo_helpers.h" - -/* RSA certificate that has been generated off the device. - * This key will be used as an example for importing an object onto the device. - * This is useful when the device itself cannot create credentials or for storing - * a well known CA certificate. - */ -#define pkcs11demo_RSA_CERTIFICATE \ - "" \ - "-----BEGIN CERTIFICATE-----\n" \ - "MIIFgTCCA2mgAwIBAgIUPsOLvI1VI8EtdIZi1s2vp7sGhy8wDQYJKoZIhvcNAQEL\n" \ - "BQAwTzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAldBMRAwDgYDVQQHDAdTZWF0dGxl\n" \ - "MSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMjAwNzEzMTY0\n" \ - "MDUyWhgPMjEyMDA2MTkxNjQwNTJaME8xCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJX\n" \ - "QTEQMA4GA1UEBwwHU2VhdHRsZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQ\n" \ - "dHkgTHRkMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtSrIA3Esgjtf\n" \ - "5Ltk/zMaUIbdX8F3VJKyQ9L3Bu07BDNVYmSqPg7+TNvUSrVT7npYmF7TE+jKJXvW\n" \ - "Lf9UUQZUb5KFf6cKkUKoZlXY3Jn3oInD9md7Yyry1z7eTrBz20UnUaTx28lqq2T8\n" \ - "SzwAthMyjhHmXeFXTD+KKY7j9H73kgOH4EUme3Nrxp+z/yaSQN5Naeqp1/HBGayY\n" \ - "TqFOgDlv2NXdrvKPlvBeEpWa6WoRnq7iC3jCuafO4ZUueu4hdt9tfQLXtKixLKhu\n" \ - "Tjw1w7iKi88KjQhGz7gCDxCGQxWm22HgXdNEBHUctN+lUpYyMQy/dafHvUgug2YJ\n" \ - "aRwN+QBL7GH6N75Mfh9t3dFTERxa1tphNeiVeqlb5/D2yY0JaqqIBUxpSsgpn/a1\n" \ - "orR+XgAtMaHL0I+xwE1gdhYOWAhfcGo6vTD45b9fgERoeUC5KOUiZ2xABUV278lF\n" \ - "QJ7uPwwhV+fjpwwZcum3viFnk5SUBtENhm9QGoH0KW8K43doPc7yeeaY4gxXdV1g\n" \ - "im2uQ07Vk9bIm/HDYpW+tRQX7BM7o4BhqL7FbnKgfN2YcyMds+16YfugaaNJy53I\n" \ - "O4640KT9NrpmJ0el+rmwb+2Ut9Ie+V7ja40V0M0hBToDWXjoIY2i9nf6rIXws76J\n" \ - "A3jIMNTDLhoCT0cMcSs8zB9mqxNlbqkCAwEAAaNTMFEwHQYDVR0OBBYEFFPkZ81v\n" \ - "G9lKvZv9XvKOOF0nwu8fMB8GA1UdIwQYMBaAFFPkZ81vG9lKvZv9XvKOOF0nwu8f\n" \ - "MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBACjoiRIwP+mIggZ/\n" \ - "PEBGqR+siV4TDDTVgUBeanLilkfKYeNEo4tapRy1Jvm2Kd/T26O2X2fTCVGG5Hpf\n" \ - "KUYC9RLq7gPEytLUIlfwn0jp3uY3DotKQD03GWZ5nc0FJyhMoMH72MdoculbQ4UL\n" \ - "x4CCrCvnGodXm0oXa6cEl4Do8MadU7fgRF1Bj05FD7LfDUgBGJp8pZbKiPIKLzAx\n" \ - "UlMQen5PHJOke4+y2O/mL2iQshat7a5MOwJgPp1Wkn0q5kLO9AGVXbq3DD40jLrh\n" \ - "b9EDVsWTa1Xu3RQV4zqHFsm3OGliwJbtO1BA6P7QFBRGMMos4xZQWjxJXbr1m+uf\n" \ - "1y/X5icXdwWQ/f9h0ovjWeqOZBW8hfW6CRD1ehJpBB2YCwTjK7Fn5p4PH0PJUWf5\n" \ - "rPuShvCAUy73QC/Iud4xwNQf6D9MWzOcDWvh7NPGhCHFmz4swKlN8oglMD1JaE4U\n" \ - "97LLfATEYy5ajjlWoJ8qF/in8jzsYxq9OZ2/ObchZsU9ybzLRuE1Cv7v4Mx1sgH3\n" \ - "EoWYZK1j3WytKmbaWYDR6INYklT/d+14OyIflUfBGiSXNKMITWVRZYjTHKUeAPdb\n" \ - "1bsyMu+g4y1PVOrp/d9AyZTZrDW81zuYpO5Ah0DgF4EYiz2fWnz2ITVUmq35znIQ\n" \ - "xg07nhvDeydwB48xXrPQ1KutrRyh\n" \ - "-----END CERTIFICATE-----" - -/* Add C++ guards for C linkage in case this file is being compiled as C++ - * for a CI check. */ -/* *INDENT-OFF* */ -#ifdef __cplusplus - extern "C" { -#endif -/* *INDENT-ON* */ - -/* This function can be found in - * corePKCS11/source/dependency/3rdparty/mbedtls_utils/mbedtls_utils.c. - * It will be used to convert the RSA certificate from PEM format - * to DER format. */ -extern int convert_pem_to_der( const unsigned char * pucInput, - size_t xLen, - unsigned char * pucOutput, - size_t * pxOlen ); -/* *INDENT-OFF* */ -#ifdef __cplusplus - } -#endif -/* *INDENT-ON* */ - -/*-----------------------------------------------------------*/ - - -/** - * @brief objectImporting covers how to import a RSA certificate that was - * not generated by the Cryptoki library. - * - */ -static CK_RV objectImporting( void ); - -/** - * @brief objectGeneration covers how to create a public key and private key pair - * with Cryptoki defined attributes using C_GenerateKeyPair. - * - * @note The "sign-verify.c" demo has a dependency on the objects created - * in this function, and will not work without first running this function. - */ -static CK_RV objectGeneration( void ); - - -/** - * This function details how to use the PKCS #11 "Object" functions to - * manage the objects abstracted by cryptoki. - * - * https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html - * please consult the standard for more information. - * - * The standard has grouped the functions presented in this demo as: - * Object Management Functions. - * - */ -CK_RV PKCS11ObjectDemo( void ) -{ - CK_RV result = CKR_OK; - - LogInfo( ( "Starting PKCS #11 Objects Demo." ) ); - - /* PKCS #11 defines objects as "An item that is stored on a token. May be - * data, a certificate, or a key." This demo will show how to create objects - * that are managed by Cryptoki. */ - result = objectImporting(); - - if( result == CKR_OK ) - { - result = objectGeneration(); - } - - LogInfo( ( "Finished PKCS #11 Objects Demo." ) ); - - return result; -} - -static CK_RV objectImporting( void ) -{ - LogInfo( ( "---------Importing Objects---------" ) ); - LogInfo( ( "Importing RSA Certificate..." ) ); - - /* Helper variables and variables that have been covered. */ - CK_RV result = CKR_OK; - CK_SESSION_HANDLE session = CK_INVALID_HANDLE; - CK_SLOT_ID * slotId = 0; - CK_FUNCTION_LIST_PTR functionList = NULL; - uint8_t * derObject = NULL; - size_t derLen = 0; - CK_BBOOL tokenStorage = CK_TRUE; - CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE; - CK_BYTE subject[] = "TestSubject"; - - - /* The PKCS11_CertificateTemplate_t is a custom struct defined in "core_pkcs11.h" - * in order to make it easier to import a certificate. This struct will be - * populated with the parameters necessary to import the certificate into the - * Cryptoki library. - */ - PKCS11_CertificateTemplate_t certificateTemplate; - - /* The object class is specified as a certificate to help the Cryptoki library - * parse the arguments. - */ - CK_OBJECT_CLASS xCertificateClass = CKO_CERTIFICATE; - - /* The certificate type is an x509 certificate, which is the only type - * supported by this stack. To read more about x509 certificates one can - * read the following: - * - * https://en.wikipedia.org/wiki/X.509 - * https://www.ssl.com/faqs/what-is-an-x-509-certificate/ - * - */ - CK_CERTIFICATE_TYPE xCertificateType = CKC_X_509; - - /* The label will help the application identify which object it would like - * to access. - */ - CK_BYTE label[] = pkcs11demoCERT_LABEL; - - /* Specify certificate class. */ - certificateTemplate.xObjectClass.type = CKA_CLASS; - certificateTemplate.xObjectClass.pValue = &xCertificateClass; - certificateTemplate.xObjectClass.ulValueLen = sizeof( xCertificateClass ); - - /* Specify certificate subject. */ - certificateTemplate.xSubject.type = CKA_SUBJECT; - certificateTemplate.xSubject.pValue = subject; - certificateTemplate.xSubject.ulValueLen = strlen( ( const char * ) subject ); - - /* Point to contents of certificate. */ - certificateTemplate.xValue.type = CKA_VALUE; - certificateTemplate.xValue.pValue = ( CK_VOID_PTR ) pkcs11demo_RSA_CERTIFICATE; - certificateTemplate.xValue.ulValueLen = ( CK_ULONG ) sizeof( pkcs11demo_RSA_CERTIFICATE ); - - /* Specify certificate label. */ - certificateTemplate.xLabel.type = CKA_LABEL; - certificateTemplate.xLabel.pValue = ( CK_VOID_PTR ) label; - certificateTemplate.xLabel.ulValueLen = strlen( ( const char * ) label ); - - /* Specify certificate type as x509. */ - certificateTemplate.xCertificateType.type = CKA_CERTIFICATE_TYPE; - certificateTemplate.xCertificateType.pValue = &xCertificateType; - certificateTemplate.xCertificateType.ulValueLen = sizeof( CK_CERTIFICATE_TYPE ); - - /* Specify that the certificate should be on a token. */ - certificateTemplate.xTokenObject.type = CKA_TOKEN; - certificateTemplate.xTokenObject.pValue = &tokenStorage; - certificateTemplate.xTokenObject.ulValueLen = sizeof( tokenStorage ); - - result = start( &session, &slotId ); - - /* Ensure the Cryptoki library has the necessary functions implemented. */ - if( result == CKR_OK ) - { - result = C_GetFunctionList( &functionList ); - } - - /* Convert the certificate to DER format if it was in PEM. The DER key - * should be about 3/4 the size of the PEM key, so mallocing the PEM key - * size is sufficient. */ - derObject = ( uint8_t * ) malloc( certificateTemplate.xValue.ulValueLen ); - - if( derObject == NULL ) - { - result = CKR_HOST_MEMORY; - } - - if( result == CKR_OK ) - { - derLen = certificateTemplate.xValue.ulValueLen; - ( void ) convert_pem_to_der( ( unsigned char * ) certificateTemplate.xValue.pValue, - certificateTemplate.xValue.ulValueLen, - derObject, - &derLen ); - } - - /* Set the template pointers to refer to the DER converted objects. */ - certificateTemplate.xValue.pValue = derObject; - certificateTemplate.xValue.ulValueLen = derLen; - - /* Create an object using the encoded client certificate. */ - LogInfo( ( "Creating x509 certificate with label: %s ", - pkcs11demoCERT_LABEL ) ); - - /* Once the Cryptoki library has finished importing the new x509 certificate - * a CK_OBJECT_HANDLE is associated with it. The application can now use this - * to refer to the object in following operations. - * - * certHandle in the below example will have it's value modified to - * be the CK_OBJECT_HANDLE. - * - * Compare the hard coded x509, in PEM format, with the DER formatted - * x509 certificate that is created by the Cryptoki library, with the following - * OpenSSL command: - * "$ openssl x509 -in FreeRTOS_P11_Certificate.dat -inform der -text" - * - * See this explanation for the difference between the PEM format and the - * DER format: - * https://stackoverflow.com/questions/22743415/what-are-the-differences-between-pem-cer-and-der/22743616 - * - */ - if( result == CKR_OK ) - { - result = functionList->C_CreateObject( session, - ( CK_ATTRIBUTE_PTR ) &certificateTemplate, - sizeof( certificateTemplate ) / sizeof( CK_ATTRIBUTE ), - &certHandle ); - } - - LogInfo( ( "FreeRTOS_P11_Certificate.dat has been created in the current " - " directory" ) ); - - free( derObject ); - end( session, slotId ); - LogInfo( ( "Finished Importing RSA Certificate." ) ); - LogInfo( ( "---------Finished Importing Objects---------" ) ); - - return result; -} - -static CK_RV objectGeneration( void ) -{ - LogInfo( ( "---------Generating Objects---------" ) ); - - /* Helper variables. */ - CK_RV result = CKR_OK; - CK_SESSION_HANDLE session = CK_INVALID_HANDLE; - CK_SLOT_ID * slotId = 0; - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_BYTE * derPublicKey = NULL; - CK_ULONG derPublicKeyLength = 0; - CK_BBOOL trueVar = CK_TRUE; - - /* Specify the mechanism to use in the key pair generation. Mechanisms are - * previously explained in the "mechanims_and_digests.c" demo. */ - CK_MECHANISM mechanism = - { - CKM_EC_KEY_PAIR_GEN, NULL_PTR, 0 - }; - - /* The EC curve used in this demo will be the named EC curve prime256v1. - * For further explanations of EC Cryptography please see the following: - * https://en.wikipedia.org/wiki/Elliptic-curve_cryptography - * https://wiki.openssl.org/index.php/Elliptic_Curve_Cryptography - */ - CK_BYTE ecParams[] = pkcs11DER_ENCODED_OID_P256; - - /* Specify the key type to be EC. */ - CK_KEY_TYPE keyType = CKK_EC; - - /* Object handles are a token specific identifier for an object. They are - * used so the application's sessions can specify which object to interact - * with. Non-zero values are valid, 0 is always invalid, and is defined as - * CK_INVALID_HANDLE - * - * The lifetime of the handle is not necessarily the same as the lifetime of - * the object. - */ - CK_OBJECT_HANDLE privateKeyHandle = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE publicKeyHandle = CK_INVALID_HANDLE; - - - /* Labels are application defined strings that are used to identify an - * object. It should not be NULL terminated. */ - CK_BYTE publicKeyLabel[] = { pkcs11demoPUBLIC_KEY_LABEL }; - CK_BYTE privateKeyLabel[] = { pkcs11demoPRIVATE_KEY_LABEL }; - - /* CK_ATTTRIBUTE's contain an attribute type, a value, and the length of - * the value. An array of CK_ATTRIBUTEs is called a template. They are used - * for creating, searching, and manipulating for objects. The order of the - * template does not matter. - * - * In the below template we are creating a public key: - * Specify the key type as EC. - * The key will be able to verify a message. - * Specify the EC Curve. - * Assign a label to the object that will be created. - */ - CK_ATTRIBUTE publicKeyTemplate[] = - { - { CKA_KEY_TYPE, &keyType, sizeof( keyType ) }, - { CKA_VERIFY, &trueVar, sizeof( trueVar ) }, - { CKA_EC_PARAMS, ecParams, sizeof( ecParams ) }, - { CKA_LABEL, publicKeyLabel, sizeof( publicKeyLabel ) - 1 } - }; - - /* In the below template we are creating a private key: - * The key type is EC. - * The key is a token object. - * The key will be a private key. - * The key will be able to sign messages. - * Assign a label to the object that will be created. - */ - CK_ATTRIBUTE privateKeyTemplate[] = - { - { CKA_KEY_TYPE, &keyType, sizeof( keyType ) }, - { CKA_TOKEN, &trueVar, sizeof( trueVar ) }, - { CKA_PRIVATE, &trueVar, sizeof( trueVar ) }, - { CKA_SIGN, &trueVar, sizeof( trueVar ) }, - { CKA_LABEL, privateKeyLabel, sizeof( privateKeyLabel ) - 1 } - }; - - if( result == CKR_OK ) - { - start( &session, &slotId ); - } - - result = C_GetFunctionList( &functionList ); - - LogInfo( ( "Creating private key with label: %s ", - pkcs11demoPRIVATE_KEY_LABEL ) ); - LogInfo( ( "Creating public key with label: %s ", - pkcs11demoPUBLIC_KEY_LABEL ) ); - - /* This function will generate a new EC private and public key pair. You can - * use " $openssl ec -inform der -in FreeRTOS_P11_Key.dat -text " to see - * the structure of the keys that were generated. - */ - if( result == CKR_OK ) - { - result = functionList->C_GenerateKeyPair( session, - &mechanism, - publicKeyTemplate, - sizeof( publicKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - privateKeyTemplate, - sizeof( privateKeyTemplate ) / sizeof( CK_ATTRIBUTE ), - &publicKeyHandle, - &privateKeyHandle ); - } - - LogInfo( ( "FreeRTOS_P11_Key.dat has been created in the " - "current directory" ) ); - LogInfo( ( "Extracting public key bytes..." ) ); - - /* Export public key as hex bytes and print the hex representation of the - * public key. */ - exportPublicKey( session, - publicKeyHandle, - &derPublicKey, - &derPublicKeyLength ); - writeHexBytesToConsole( "Public Key in Hex Format", - derPublicKey, - derPublicKeyLength ); - - /* exportPublicKey allocates memory which must be freed. */ - if( derPublicKey != NULL ) - { - free( derPublicKey ); - } - - LogInfo( ( "---------Finished Generating Objects---------" ) ); - end( session, slotId ); - - return result; -} - -/** - * @brief Entry point of demo. - * - * The example shown above uses PKCS #11 APIs to interact with objects. - */ -int main( void ) -{ - return PKCS11ObjectDemo(); -} diff --git a/demos/pkcs11/pkcs11_demo_sign_and_verify/CMakeLists.txt b/demos/pkcs11/pkcs11_demo_sign_and_verify/CMakeLists.txt deleted file mode 100644 index f8498ef0a1..0000000000 --- a/demos/pkcs11/pkcs11_demo_sign_and_verify/CMakeLists.txt +++ /dev/null @@ -1,41 +0,0 @@ -set( DEMO_NAME "pkcs11_demo_sign_and_verify" ) - -# Set path to corePKCS11 and it's third party libraries. -set(COREPKCS11_LOCATION "${CMAKE_SOURCE_DIR}/libraries/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") - -# Include PKCS #11 library's source and header path variables. -include( ${COREPKCS11_LOCATION}/pkcsFilePaths.cmake ) - -list(APPEND PKCS_SOURCES - "${DEMOS_DIR}/pkcs11/common/src/demo_helpers.c" - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c" - ) - -file( GLOB DEMO_SRCS "*.c*" ) - -# Demo target. -add_executable( - ${DEMO_NAME} - ${DEMO_SRCS} - ${PKCS_SOURCES} - ${PKCS_PAL_POSIX_SOURCES} -) - -target_link_libraries( - ${DEMO_NAME} - PRIVATE - mbedtls -) - -target_include_directories( - ${DEMO_NAME} - PUBLIC - "${DEMOS_DIR}/pkcs11/common/include" - ${PKCS_INCLUDE_PUBLIC_DIRS} - ${PKCS_PAL_INCLUDE_PUBLIC_DIRS} - ${CMAKE_CURRENT_LIST_DIR} - ${LOGGING_INCLUDE_DIRS} - PRIVATE - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils" -) diff --git a/demos/pkcs11/pkcs11_demo_sign_and_verify/pkcs11_demo_sign_and_verify.c b/demos/pkcs11/pkcs11_demo_sign_and_verify/pkcs11_demo_sign_and_verify.c deleted file mode 100644 index 89224710b7..0000000000 --- a/demos/pkcs11/pkcs11_demo_sign_and_verify/pkcs11_demo_sign_and_verify.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Standard include. */ -#include -#include - -/* Logging stack includes. */ -#include "logging_levels.h" - -#ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "PKCS11_SIGN_VERIFY_DEMO" -#endif - -#ifndef LIBRARY_LOG_LEVEL - #define LIBRARY_LOG_LEVEL LOG_INFO -#endif - -#include "logging_stack.h" - -/* PKCS #11 includes. */ -#include "core_pkcs11.h" -#include "pkcs11.h" -#include "core_pki_utils.h" - -/* Demo includes. */ -#include "demo_helpers.h" - -/** - * @brief This function details how to use the PKCS #11 "Sign and Verify" functions to - * create and interact with digital signatures. - * The functions described are all defined in - * https://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html - * Please consult the standard for more information regarding these functions. - * - * The standard has grouped the functions presented in this demo as: - * Object Management Functions - * Signing and MACing Functions - */ -CK_RV PKCS11SignVerifyDemo( void ) -{ - /* This demo will use the generated private and public key from the - * "objects.c" demo and use them to sign and verify the integrity of a - * message digest. This demo will use concepts from all the other demos, - * and is recommended be done last. - * - * The intention of this demo is how to use PKCS #11's Crypotki API to do - * these signature operations, not to explain when and why they should be - * used. For a deeper understanding of that please read: - * https://en.wikipedia.org/wiki/Public_key_infrastructure - * https://en.wikipedia.org/wiki/Transport_Layer_Security - * https://en.wikipedia.org/wiki/Digital_signature - */ - LogInfo( ( "Starting PKCS #11 Sign and Verify Demo." ) ); - - /* Helper / previously explained variables. */ - CK_RV result = CKR_OK; - CK_SESSION_HANDLE session = CK_INVALID_HANDLE; - CK_ULONG index = 0; - CK_OBJECT_HANDLE privateKeyHandle = CK_INVALID_HANDLE; - CK_OBJECT_HANDLE publicKeyHandle = CK_INVALID_HANDLE; - CK_FUNCTION_LIST_PTR functionList = NULL; - CK_BYTE * derPublicKey = NULL; - CK_ULONG derPublicKeyLength = 0; - CK_BYTE signatureFormatBuffer[ pkcs11SHA256_DIGEST_LENGTH * 2 ] = { 0 }; - CK_BYTE_PTR formatPtr = NULL; - - /* Digest variables. See "mechanisms_and_digests" for an explanation. */ - CK_BYTE knownMessage[] = { "Hello world" }; - CK_BYTE digestResult[ pkcs11SHA256_DIGEST_LENGTH ] = { 0 }; - CK_ULONG digestLength = pkcs11SHA256_DIGEST_LENGTH; - CK_MECHANISM xDigestMechanism = { 0 }; - - /* Signing variables. */ - /* The ECDSA mechanism will be used to sign the message digest. */ - CK_MECHANISM mechanism = { CKM_ECDSA, NULL, 0 }; - - /* This signature buffer will be used to store the signature created by the - * private key. (64 bytes). We pad it with an extra 8 bytes so it can be - * converted to an ASN.1 encoding. */ - CK_BYTE signature[ pkcs11ECDSA_P256_SIGNATURE_LENGTH + 8 ] = { 0 }; - CK_ULONG signatureLength = sizeof( signature ); - - /* Ensure the Cryptoki library has the necessary functions implemented. */ - result = C_GetFunctionList( &functionList ); - - /* Instead of using the start helper, we will use the "core_pkcs11.h" - * functions that help wrap around some common PKCS #11 use cases. - * - * This function will: - * Initialize the PKCS #11 module if it is not already. - * Initialize a PKCS #11 session. - */ - if( result == CKR_OK ) - { - result = xInitializePkcs11Session( &session ); - } - - /* This function will: - * Initialize the PKCS #11 module if it is not already. - * Initialize the token to be used. - * - * Note: By default this function will always initialize the token in the - * first slot in the slot list. If it desired to use a different slot, it - * is necessary to modify the implementation of this function to use a - * different slot. */ - if( result == CKR_OK ) - { - result = xInitializePkcs11Token(); - } - - /***************************** Find Objects *****************************/ - - /* This function will: - * Find an object, given it's label. - * - * This is done using the FindObjects group of functions defined as - * "Object Management Functions" in PKCS #11. - * - * This will acquire the object handle for the private key created in the - * "objects.c" demo. - */ - if( result == CKR_OK ) - { - result = xFindObjectWithLabelAndClass( session, - pkcs11demoPRIVATE_KEY_LABEL, - sizeof( pkcs11demoPRIVATE_KEY_LABEL ) - 1, - CKO_PRIVATE_KEY, - &privateKeyHandle ); - } - - /* Acquire the object handle for the public key created in the "objects.c" - * demo. */ - if( result == CKR_OK ) - { - result = xFindObjectWithLabelAndClass( session, - pkcs11demoPUBLIC_KEY_LABEL, - sizeof( pkcs11demoPUBLIC_KEY_LABEL ) - 1, - CKO_PUBLIC_KEY, - &publicKeyHandle ); - } - - if( ( privateKeyHandle == CK_INVALID_HANDLE ) || ( publicKeyHandle == CK_INVALID_HANDLE ) ) - { - LogError( ( "IMPORTANT: The demo could not find the key and certificate" - " generated by the pkcs11_demo_objects demo. It is" - " necessary to FIRST run the objects demo, to create a key" - " and certificate. Once this is done make sure to run the" - " sign_and_verify demo from a folder containing those files" - ", so it can access the key and certificate in the file" - " system." ) ); - result = CKR_OBJECT_HANDLE_INVALID; - } - - /***************************** Buffer Digest *****************************/ - xDigestMechanism.mechanism = CKM_SHA256; - - /* Initializes the digest operation and sets what mechanism will be used - * for the digest. */ - if( result == CKR_OK ) - { - result = functionList->C_DigestInit( session, - &xDigestMechanism ); - } - - /* Pass a pointer to the buffer of bytes to be hashed, and it's size. */ - if( result == CKR_OK ) - { - result = functionList->C_DigestUpdate( session, - knownMessage, - /* Strip NULL Terminator. */ - sizeof( knownMessage ) - 1 ); - } - - /* Retrieve the digest buffer length. When passing in a NULL pointer as the - * second argument, instead of a point to a buffer, this will signal the - * Cryptoki library to fill the third parameter with the required amount of - * bytes to store the resulting digest. - */ - if( result == CKR_OK ) - { - result = functionList->C_DigestFinal( session, - NULL, - &digestLength ); - } - - /* Now that digestLength contains the required byte length, retrieve the - * digest buffer. - */ - if( result == CKR_OK ) - { - result = functionList->C_DigestFinal( session, - digestResult, - &digestLength ); - } - - /********************************* Sign **********************************/ - - /* Initializes the sign operation and sets what mechanism will be used - * for signing the message digest. Specify what object handle to use for this - * operation, in this case the private key object handle. */ - if( result == CKR_OK ) - { - LogInfo( ( "Signing known message: %s", - ( char * ) knownMessage ) ); - - result = functionList->C_SignInit( session, - &mechanism, - privateKeyHandle ); - } - - /* Sign the message digest that was created with the C_Digest series of - * functions. A signature will be created using the private key specified in - * C_SignInit and put in the byte buffer signature. */ - if( result == CKR_OK ) - { - result = functionList->C_Sign( session, - digestResult, - pkcs11SHA256_DIGEST_LENGTH, - signature, - &signatureLength ); - } - - /********************************* Verify **********************************/ - - /* Verify the signature created by C_Sign. First we will verify that the - * same Cryptoki library was able to trust itself. - * - * C_VerifyInit will begin the verify operation, by specifying what mechanism - * to use (CKM_ECDSA, the same as the sign operation) and then specifying - * which public key handle to use. - */ - if( result == CKR_OK ) - { - result = functionList->C_VerifyInit( session, - &mechanism, - publicKeyHandle ); - } - - /* Given the signature and it's length, the Cryptoki will use the public key - * to verify that the signature was created by the corresponding private key. - * If C_Verify returns CKR_OK, it means that the sender of the message has - * the same private key as the private key that was used to generate the - * public key, and we can trust that the message we received was from that - * sender. - * - * Note that we are not using the actual message, but the digest that we - * created earlier of the message, for the verification. - */ - if( result == CKR_OK ) - { - result = functionList->C_Verify( session, - digestResult, - pkcs11SHA256_DIGEST_LENGTH, - signature, - signatureLength ); - - if( result == CKR_OK ) - { - LogInfo( ( "The signature of the digest was verified with the" - " public key and can be trusted." ) ); - } - else - { - LogInfo( ( "Unable to verify the signature with the given public" - " key, the message cannot be trusted." ) ); - } - } - - /* Export public key as hex bytes and print the hex representation of the - * public key. - * - * We need to export the public key so that it can be used by a different - * device to verify messages signed by the private key of the device that - * generated the key pair. - * - * To do this, we will output the hex representation of the public key. - * Then create an empty text file called "DevicePublicKeyAsciiHex.txt". - * - * Copy and paste the hex value of the public key into this text file. - * - * Then we will need to convert the text file to binary using the xxd tool. - * - * xxd will take a text file that contains hex data and output a binary of - * the hex in the file. See "$ man xxd" for more information about xxd. - * - * Copy the below command into the terminal. - * "$ xxd -r -ps DevicePublicKeyAsciiHex.txt DevicePublicKeyDer.bin" - * - * Now that we have the binary encoding of the public key, we will convert - * it to PEM using OpenSSL. - * - * The following command will create a PEM file of the public key called - * "public_key.pem" - * - * "$ openssl ec -inform der -in DevicePublicKeyDer.bin -pubin -pubout -outform pem -out public_key.pem" - * - * Now we can use the extracted public key to verify the signature of the - * device's private key. - * - * WARNING: Running the object generation demo will create a new key pair, - * and make it necessary to redo these steps! - * - */ - if( result == CKR_OK ) - { - LogInfo( ( "Verifying with public key." ) ); - exportPublicKey( session, - publicKeyHandle, - &derPublicKey, - &derPublicKeyLength ); - writeHexBytesToConsole( "Public Key in Hex Format", - derPublicKey, - derPublicKeyLength ); - - /* exportPublicKey allocates memory which needs to be freed. */ - if( derPublicKey != NULL ) - { - free( derPublicKey ); - } - } - - /* This utility function converts the PKCS #11 signature into an ASN.1 - * encoded binary der signature. This is necessary so we can export the - * signature and verify it with OpenSSL, otherwise OpenSSL will not be able - * to parse the buffer. - * - * See https://en.wikipedia.org/wiki/ASN.1 for more information about the - * ASN.1 encoding format. - */ - if( result == CKR_OK ) - { - PKI_pkcs11SignatureTombedTLSSignature( signature, ( size_t * ) &signatureLength ); - - /* The following loop will output the signature in hex. - * - * In order to get the signature exported in binary form copy the output - * of the loop, and paste it to an empty text file. - * - * Then we will need to convert the text file to binary using the xxd tool. - * - * The following commands outline this process. - * Write buffer to signature.txt - * xxd will take a text file that contains hex data and output a binary of - * the hex in the file. See "$ man xxd" for more information about xxd. - * - * Copy the below command into the terminal. - * "$ xxd -r -ps signature.txt signature.bin" - * - * Next, we need to copy the original message that the Cryptoki library - * signed, the following shell command will create the message without any - * newlines, so the messages are similar. - * - * The contents of the echo command can be replaced with whatever data was - * in the known message, but the example uses "Hello world" to make it easier - * for copy and pasting. - * - * "$ echo -n "Hello world" > msg.txt" - * - * Now we will use OpenSSL to verify that the signature we created can be - * trusted by another device using the public key we created and then - * extracted earlier. - * - * "$ openssl dgst -sha256 -verify public_key.pem -signature signature.bin msg.txt" - * This command should output "Verified OK" and we then know we can trust - * the sender of the message! - */ - formatPtr = &signatureFormatBuffer[ 0 ]; - - for( index = 0; index < digestLength; index++ ) - { - formatPtr += sprintf( ( char * ) formatPtr, "%x", signature[ index ] ); - } - - LogInfo( ( "Created signature: %s", signatureFormatBuffer ) ); - LogInfo( ( "Finished PKCS #11 Sign and Verify Demo." ) ); - } - - return result; -} - -/** - * @brief Entry point of demo. - * - * The example shown above uses PKCS #11 APIs to demonstrate how to sign and verify a message - */ -int main( void ) -{ - return PKCS11SignVerifyDemo(); -} diff --git a/libraries/3rdparty/mbedtls b/libraries/3rdparty/mbedtls index 8b3f26a5ac..2ca6c285a0 160000 --- a/libraries/3rdparty/mbedtls +++ b/libraries/3rdparty/mbedtls @@ -1 +1 @@ -Subproject commit 8b3f26a5ac38d4fdccbc5c5366229f3e01dafcc0 +Subproject commit 2ca6c285a0dd3f33982dd57299012dacab1ff206 diff --git a/libraries/CMakeLists.txt b/libraries/CMakeLists.txt index 05a9ffdf93..063d501953 100644 --- a/libraries/CMakeLists.txt +++ b/libraries/CMakeLists.txt @@ -15,7 +15,6 @@ endmacro() # Clone the submodules only if this is a Git repo. if( EXISTS ${ROOT_DIR}/.git ) clone_path( ${MODULES_DIR} ) - clone_path( ${MODULES_DIR}/standard/corePKCS11 "--checkout" ) endif() # Add build configuration for all 3rd party modules. diff --git a/libraries/standard/corePKCS11 b/libraries/standard/corePKCS11 deleted file mode 160000 index c671c11f2d..0000000000 --- a/libraries/standard/corePKCS11 +++ /dev/null @@ -1 +0,0 @@ -Subproject commit c671c11f2de13c31e8eb9563858fb513b4c5b678 diff --git a/manifest.yml b/manifest.yml index 005ca373b6..1f1bd57725 100644 --- a/manifest.yml +++ b/manifest.yml @@ -55,12 +55,6 @@ dependencies: type: "git" url: "https://github.com/FreeRTOS/backoffAlgorithm" path: "libraries/standard/backoffAlgorithm" - - name: "corePKCS11" - version: "c671c11f2de13c31e8eb9563858fb513b4c5b678" - repository: - type: "git" - url: "https://github.com/FreeRTOS/corePKCS11" - path: "libraries/standard/corePKCS11" - name: "Fleet-Provisioning-for-AWS-IoT-embedded-sdk" version: "8ce2b28325efb917c2e357aed2361e3fa6162ecf" repository: diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt index 6f1e95faf9..5847dfb06c 100644 --- a/platform/CMakeLists.txt +++ b/platform/CMakeLists.txt @@ -1,7 +1,7 @@ # For static library builds, link against static library of OpenSSL -if(NOT BUILD_SHARED_LIBS) - set( OPENSSL_USE_STATIC_LIBS TRUE ) -endif() +# if(NOT BUILD_SHARED_LIBS) +# set( OPENSSL_USE_STATIC_LIBS TRUE ) +# endif() find_package(OpenSSL) # Verify the minimum OpenSSL version required if( ${OPENSSL_FOUND} AND ( OPENSSL_VERSION MATCHES "0.9$" OR OPENSSL_VERSION MATCHES "1.0$" ) ) diff --git a/platform/posix/include/mbedtls_config.h b/platform/posix/include/mbedtls_config.h index 9d2047ab28..5d946d0b25 100644 --- a/platform/posix/include/mbedtls_config.h +++ b/platform/posix/include/mbedtls_config.h @@ -1,119 +1,4213 @@ +/** + * \file mbedtls_config.h + * + * \brief Configuration options (set of defines) + * + * This set of compile-time options may be used to enable + * or disable features selectively, and reduce the global + * memory footprint. + */ /* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * Copyright The Mbed TLS Contributors + * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later + */ + +#include + +/** + * This is an optional version symbol that enables compatibility handling of + * config files. + * + * It is equal to the #MBEDTLS_VERSION_NUMBER of the Mbed TLS version that + * introduced the config format we want to be compatible with. + */ +//#define MBEDTLS_CONFIG_VERSION 0x03000000 + +/** + * \name SECTION: System support + * + * This section sets system specific settings. + * \{ + */ + +/** + * \def MBEDTLS_HAVE_ASM + * + * The compiler has support for asm(). + * + * Requires support for asm() in compiler. + * + * Used in: + * library/aesni.h + * library/aria.c + * library/bn_mul.h + * library/constant_time.c + * library/padlock.h + * + * Required by: + * MBEDTLS_AESCE_C + * MBEDTLS_AESNI_C (on some platforms) + * MBEDTLS_PADLOCK_C + * + * Comment to disable the use of assembly code. + */ +#define MBEDTLS_HAVE_ASM + +/** + * \def MBEDTLS_NO_UDBL_DIVISION + * + * The platform lacks support for double-width integer division (64-bit + * division on a 32-bit platform, 128-bit division on a 64-bit platform). + * + * Used in: + * include/mbedtls/bignum.h + * library/bignum.c + * + * The bignum code uses double-width division to speed up some operations. + * Double-width division is often implemented in software that needs to + * be linked with the program. The presence of a double-width integer + * type is usually detected automatically through preprocessor macros, + * but the automatic detection cannot know whether the code needs to + * and can be linked with an implementation of division for that type. + * By default division is assumed to be usable if the type is present. + * Uncomment this option to prevent the use of double-width division. + * + * Note that division for the native integer type is always required. + * Furthermore, a 64-bit type is always required even on a 32-bit + * platform, but it need not support multiplication or division. In some + * cases it is also desirable to disable some double-width operations. For + * example, if double-width division is implemented in software, disabling + * it can reduce code size in some embedded targets. + */ +//#define MBEDTLS_NO_UDBL_DIVISION + +/** + * \def MBEDTLS_NO_64BIT_MULTIPLICATION + * + * The platform lacks support for 32x32 -> 64-bit multiplication. + * + * Used in: + * library/poly1305.c + * + * Some parts of the library may use multiplication of two unsigned 32-bit + * operands with a 64-bit result in order to speed up computations. On some + * platforms, this is not available in hardware and has to be implemented in + * software, usually in a library provided by the toolchain. + * + * Sometimes it is not desirable to have to link to that library. This option + * removes the dependency of that library on platforms that lack a hardware + * 64-bit multiplier by embedding a software implementation in Mbed TLS. + * + * Note that depending on the compiler, this may decrease performance compared + * to using the library function provided by the toolchain. + */ +//#define MBEDTLS_NO_64BIT_MULTIPLICATION + +/** + * \def MBEDTLS_HAVE_SSE2 + * + * CPU supports SSE2 instruction set. + * + * Uncomment if the CPU supports SSE2 (IA-32 specific). + */ +//#define MBEDTLS_HAVE_SSE2 + +/** + * \def MBEDTLS_HAVE_TIME + * + * System has time.h and time(). + * The time does not need to be correct, only time differences are used, + * by contrast with MBEDTLS_HAVE_TIME_DATE + * + * Defining MBEDTLS_HAVE_TIME allows you to specify MBEDTLS_PLATFORM_TIME_ALT, + * MBEDTLS_PLATFORM_TIME_MACRO, MBEDTLS_PLATFORM_TIME_TYPE_MACRO and + * MBEDTLS_PLATFORM_STD_TIME. + * + * Comment if your system does not support time functions. + * + * \note If MBEDTLS_TIMING_C is set - to enable the semi-portable timing + * interface - timing.c will include time.h on suitable platforms + * regardless of the setting of MBEDTLS_HAVE_TIME, unless + * MBEDTLS_TIMING_ALT is used. See timing.c for more information. + */ +#define MBEDTLS_HAVE_TIME + +/** + * \def MBEDTLS_HAVE_TIME_DATE + * + * System has time.h, time(), and an implementation for + * mbedtls_platform_gmtime_r() (see below). + * The time needs to be correct (not necessarily very accurate, but at least + * the date should be correct). This is used to verify the validity period of + * X.509 certificates. + * + * Comment if your system does not have a correct clock. + * + * \note mbedtls_platform_gmtime_r() is an abstraction in platform_util.h that + * behaves similarly to the gmtime_r() function from the C standard. Refer to + * the documentation for mbedtls_platform_gmtime_r() for more information. + * + * \note It is possible to configure an implementation for + * mbedtls_platform_gmtime_r() at compile-time by using the macro + * MBEDTLS_PLATFORM_GMTIME_R_ALT. + */ +#define MBEDTLS_HAVE_TIME_DATE + +/** + * \def MBEDTLS_PLATFORM_MEMORY + * + * Enable the memory allocation layer. + * + * By default Mbed TLS uses the system-provided calloc() and free(). + * This allows different allocators (self-implemented or provided) to be + * provided to the platform abstraction layer. + * + * Enabling #MBEDTLS_PLATFORM_MEMORY without the + * MBEDTLS_PLATFORM_{FREE,CALLOC}_MACROs will provide + * "mbedtls_platform_set_calloc_free()" allowing you to set an alternative calloc() and + * free() function pointer at runtime. + * + * Enabling #MBEDTLS_PLATFORM_MEMORY and specifying + * MBEDTLS_PLATFORM_{CALLOC,FREE}_MACROs will allow you to specify the + * alternate function at compile time. + * + * An overview of how the value of mbedtls_calloc is determined: + * + * - if !MBEDTLS_PLATFORM_MEMORY + * - mbedtls_calloc = calloc + * - if MBEDTLS_PLATFORM_MEMORY + * - if (MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): + * - mbedtls_calloc = MBEDTLS_PLATFORM_CALLOC_MACRO + * - if !(MBEDTLS_PLATFORM_CALLOC_MACRO && MBEDTLS_PLATFORM_FREE_MACRO): + * - Dynamic setup via mbedtls_platform_set_calloc_free is now possible with a default value MBEDTLS_PLATFORM_STD_CALLOC. + * - How is MBEDTLS_PLATFORM_STD_CALLOC handled? + * - if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: + * - MBEDTLS_PLATFORM_STD_CALLOC is not set to anything; + * - MBEDTLS_PLATFORM_STD_MEM_HDR can be included if present; + * - if !MBEDTLS_PLATFORM_NO_STD_FUNCTIONS: + * - if MBEDTLS_PLATFORM_STD_CALLOC is present: + * - User-defined MBEDTLS_PLATFORM_STD_CALLOC is respected; + * - if !MBEDTLS_PLATFORM_STD_CALLOC: + * - MBEDTLS_PLATFORM_STD_CALLOC = calloc + * + * - At this point the presence of MBEDTLS_PLATFORM_STD_CALLOC is checked. + * - if !MBEDTLS_PLATFORM_STD_CALLOC + * - MBEDTLS_PLATFORM_STD_CALLOC = uninitialized_calloc + * + * - mbedtls_calloc = MBEDTLS_PLATFORM_STD_CALLOC. + * + * Defining MBEDTLS_PLATFORM_CALLOC_MACRO and #MBEDTLS_PLATFORM_STD_CALLOC at the same time is not possible. + * MBEDTLS_PLATFORM_CALLOC_MACRO and MBEDTLS_PLATFORM_FREE_MACRO must both be defined or undefined at the same time. + * #MBEDTLS_PLATFORM_STD_CALLOC and #MBEDTLS_PLATFORM_STD_FREE do not have to be defined at the same time, as, if they are used, + * dynamic setup of these functions is possible. See the tree above to see how are they handled in all cases. + * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. + * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. + * + * Requires: MBEDTLS_PLATFORM_C + * + * Enable this layer to allow use of alternative memory allocators. + */ +//#define MBEDTLS_PLATFORM_MEMORY + +/** + * \def MBEDTLS_PLATFORM_NO_STD_FUNCTIONS + * + * Do not assign standard functions in the platform layer (e.g. calloc() to + * MBEDTLS_PLATFORM_STD_CALLOC and printf() to MBEDTLS_PLATFORM_STD_PRINTF) * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: + * This makes sure there are no linking errors on platforms that do not support + * these functions. You will HAVE to provide alternatives, either at runtime + * via the platform_set_xxx() functions or at compile time by setting + * the MBEDTLS_PLATFORM_STD_XXX defines, or enabling a + * MBEDTLS_PLATFORM_XXX_MACRO. * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. + * Requires: MBEDTLS_PLATFORM_C * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Uncomment to prevent default assignment of standard functions in the + * platform layer. */ +//#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS -/* This file configures MbedTLS for the CSDK transport interface and demos. */ +/** + * \def MBEDTLS_PLATFORM_EXIT_ALT + * + * MBEDTLS_PLATFORM_XXX_ALT: Uncomment a macro to let Mbed TLS support the + * function in the platform abstraction layer. + * + * Example: In case you uncomment MBEDTLS_PLATFORM_PRINTF_ALT, Mbed TLS will + * provide a function "mbedtls_platform_set_printf()" that allows you to set an + * alternative printf function pointer. + * + * All these define require MBEDTLS_PLATFORM_C to be defined! + * + * \note MBEDTLS_PLATFORM_SNPRINTF_ALT is required on Windows; + * it will be enabled automatically by check_config.h + * + * \warning MBEDTLS_PLATFORM_XXX_ALT cannot be defined at the same time as + * MBEDTLS_PLATFORM_XXX_MACRO! + * + * Requires: MBEDTLS_PLATFORM_TIME_ALT requires MBEDTLS_HAVE_TIME + * + * Uncomment a macro to enable alternate implementation of specific base + * platform function + */ +//#define MBEDTLS_PLATFORM_SETBUF_ALT +//#define MBEDTLS_PLATFORM_EXIT_ALT +//#define MBEDTLS_PLATFORM_TIME_ALT +//#define MBEDTLS_PLATFORM_FPRINTF_ALT +//#define MBEDTLS_PLATFORM_PRINTF_ALT +//#define MBEDTLS_PLATFORM_SNPRINTF_ALT +//#define MBEDTLS_PLATFORM_VSNPRINTF_ALT +//#define MBEDTLS_PLATFORM_NV_SEED_ALT +//#define MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT +//#define MBEDTLS_PLATFORM_MS_TIME_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_gmtime_r(). This replaces the default implementation in + * platform_util.c. + * + * gmtime() is not a thread-safe function as defined in the C standard. The + * library will try to use safer implementations of this function, such as + * gmtime_r() when available. However, if Mbed TLS cannot identify the target + * system, the implementation of mbedtls_platform_gmtime_r() will default to + * using the standard gmtime(). In this case, calls from the library to + * gmtime() will be guarded by the global mutex mbedtls_threading_gmtime_mutex + * if MBEDTLS_THREADING_C is enabled. We recommend that calls from outside the + * library are also guarded with this mutex to avoid race conditions. However, + * if the macro MBEDTLS_PLATFORM_GMTIME_R_ALT is defined, Mbed TLS will + * unconditionally use the implementation for mbedtls_platform_gmtime_r() + * supplied at compile time. + */ +//#define MBEDTLS_PLATFORM_GMTIME_R_ALT + +/** + * Uncomment the macro to let Mbed TLS use your alternate implementation of + * mbedtls_platform_zeroize(), to wipe sensitive data in memory. This replaces + * the default implementation in platform_util.c. + * + * By default, the library uses a system function such as memset_s() + * (optional feature of C11), explicit_bzero() (BSD and compatible), or + * SecureZeroMemory (Windows). If no such function is detected, the library + * falls back to a plain C implementation. Compilers are technically + * permitted to optimize this implementation out, meaning that the memory is + * not actually wiped. The library tries to prevent that, but the C language + * makes it impossible to guarantee that the memory will always be wiped. + * + * If your platform provides a guaranteed method to wipe memory which + * `platform_util.c` does not detect, define this macro to the name of + * a function that takes two arguments, a `void *` pointer and a length, + * and wipes that many bytes starting at the specified address. For example, + * if your platform has explicit_bzero() but `platform_util.c` does not + * detect its presence, define `MBEDTLS_PLATFORM_ZEROIZE_ALT` to be + * `explicit_bzero` to use that function as mbedtls_platform_zeroize(). + */ +//#define MBEDTLS_PLATFORM_ZEROIZE_ALT + +/** + * \def MBEDTLS_DEPRECATED_WARNING + * + * Mark deprecated functions and features so that they generate a warning if + * used. Functionality deprecated in one version will usually be removed in the + * next version. You can enable this to help you prepare the transition to a + * new major version by making sure your code is not using this functionality. + * + * This only works with GCC and Clang. With other compilers, you may want to + * use MBEDTLS_DEPRECATED_REMOVED + * + * Uncomment to get warnings on using deprecated functions and features. + */ +//#define MBEDTLS_DEPRECATED_WARNING + +/** + * \def MBEDTLS_DEPRECATED_REMOVED + * + * Remove deprecated functions and features so that they generate an error if + * used. Functionality deprecated in one version will usually be removed in the + * next version. You can enable this to help you prepare the transition to a + * new major version by making sure your code is not using this functionality. + * + * Uncomment to get errors on using deprecated functions and features. + */ +//#define MBEDTLS_DEPRECATED_REMOVED + +/** \} name SECTION: System support */ + +/** + * \name SECTION: Mbed TLS feature support + * + * This section sets support for features that are or are not needed + * within the modules that are enabled. + * \{ + */ + +/** + * \def MBEDTLS_TIMING_ALT + * + * Uncomment to provide your own alternate implementation for + * mbedtls_timing_get_timer(), mbedtls_set_alarm(), mbedtls_set/get_delay() + * + * Only works if you have MBEDTLS_TIMING_C enabled. + * + * You will need to provide a header "timing_alt.h" and an implementation at + * compile time. + */ +//#define MBEDTLS_TIMING_ALT + +/** + * \def MBEDTLS_AES_ALT + * + * MBEDTLS__MODULE_NAME__ALT: Uncomment a macro to let Mbed TLS use your + * alternate core implementation of a symmetric crypto, an arithmetic or hash + * module (e.g. platform specific assembly optimized implementations). Keep + * in mind that the function prototypes should remain the same. + * + * This replaces the whole module. If you only want to replace one of the + * functions, use one of the MBEDTLS__FUNCTION_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_AES_ALT, Mbed TLS will no longer + * provide the "struct mbedtls_aes_context" definition and omit the base + * function declarations and implementations. "aes_alt.h" will be included from + * "aes.h" to include the new function definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * module. + * + * \warning MD5, DES and SHA-1 are considered weak and their + * use constitutes a security risk. If possible, we recommend + * avoiding dependencies on them, and considering stronger message + * digests and ciphers instead. + * + */ +//#define MBEDTLS_AES_ALT +//#define MBEDTLS_ARIA_ALT +//#define MBEDTLS_CAMELLIA_ALT +//#define MBEDTLS_CCM_ALT +//#define MBEDTLS_CHACHA20_ALT +//#define MBEDTLS_CHACHAPOLY_ALT +//#define MBEDTLS_CMAC_ALT +//#define MBEDTLS_DES_ALT +//#define MBEDTLS_DHM_ALT +//#define MBEDTLS_ECJPAKE_ALT +//#define MBEDTLS_GCM_ALT +//#define MBEDTLS_NIST_KW_ALT +//#define MBEDTLS_MD5_ALT +//#define MBEDTLS_POLY1305_ALT +//#define MBEDTLS_RIPEMD160_ALT +//#define MBEDTLS_RSA_ALT +//#define MBEDTLS_SHA1_ALT +//#define MBEDTLS_SHA256_ALT +//#define MBEDTLS_SHA512_ALT + +/* + * When replacing the elliptic curve module, please consider, that it is + * implemented with two .c files: + * - ecp.c + * - ecp_curves.c + * You can replace them very much like all the other MBEDTLS__MODULE_NAME__ALT + * macros as described above. The only difference is that you have to make sure + * that you provide functionality for both .c files. + */ +//#define MBEDTLS_ECP_ALT -#ifndef MBEDTLS_CONFIG_H_ -#define MBEDTLS_CONFIG_H_ +/** + * \def MBEDTLS_SHA256_PROCESS_ALT + * + * MBEDTLS__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use you + * alternate core implementation of symmetric crypto or hash function. Keep in + * mind that function prototypes should remain the same. + * + * This replaces only one function. The header file from Mbed TLS is still + * used, in contrast to the MBEDTLS__MODULE_NAME__ALT flags. + * + * Example: In case you uncomment MBEDTLS_SHA256_PROCESS_ALT, Mbed TLS will + * no longer provide the mbedtls_sha1_process() function, but it will still provide + * the other function (using your mbedtls_sha1_process() function) and the definition + * of mbedtls_sha1_context, so your implementation of mbedtls_sha1_process must be compatible + * with this definition. + * + * \note If you use the AES_xxx_ALT macros, then it is recommended to also set + * MBEDTLS_AES_ROM_TABLES in order to help the linker garbage-collect the AES + * tables. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + * + * \warning MD5, DES and SHA-1 are considered weak and their use + * constitutes a security risk. If possible, we recommend avoiding + * dependencies on them, and considering stronger message digests + * and ciphers instead. + * + * \warning If both MBEDTLS_ECDSA_SIGN_ALT and MBEDTLS_ECDSA_DETERMINISTIC are + * enabled, then the deterministic ECDH signature functions pass the + * the static HMAC-DRBG as RNG to mbedtls_ecdsa_sign(). Therefore + * alternative implementations should use the RNG only for generating + * the ephemeral key and nothing else. If this is not possible, then + * MBEDTLS_ECDSA_DETERMINISTIC should be disabled and an alternative + * implementation should be provided for mbedtls_ecdsa_sign_det_ext(). + * + */ +//#define MBEDTLS_MD5_PROCESS_ALT +//#define MBEDTLS_RIPEMD160_PROCESS_ALT +//#define MBEDTLS_SHA1_PROCESS_ALT +//#define MBEDTLS_SHA256_PROCESS_ALT +//#define MBEDTLS_SHA512_PROCESS_ALT +//#define MBEDTLS_DES_SETKEY_ALT +//#define MBEDTLS_DES_CRYPT_ECB_ALT +//#define MBEDTLS_DES3_CRYPT_ECB_ALT +//#define MBEDTLS_AES_SETKEY_ENC_ALT +//#define MBEDTLS_AES_SETKEY_DEC_ALT +//#define MBEDTLS_AES_ENCRYPT_ALT +//#define MBEDTLS_AES_DECRYPT_ALT +//#define MBEDTLS_ECDH_GEN_PUBLIC_ALT +//#define MBEDTLS_ECDH_COMPUTE_SHARED_ALT +//#define MBEDTLS_ECDSA_VERIFY_ALT +//#define MBEDTLS_ECDSA_SIGN_ALT +//#define MBEDTLS_ECDSA_GENKEY_ALT -#include +/** + * \def MBEDTLS_ECP_INTERNAL_ALT + * + * Expose a part of the internal interface of the Elliptic Curve Point module. + * + * MBEDTLS_ECP__FUNCTION_NAME__ALT: Uncomment a macro to let Mbed TLS use your + * alternative core implementation of elliptic curve arithmetic. Keep in mind + * that function prototypes should remain the same. + * + * This partially replaces one function. The header file from Mbed TLS is still + * used, in contrast to the MBEDTLS_ECP_ALT flag. The original implementation + * is still present and it is used for group structures not supported by the + * alternative. + * + * The original implementation can in addition be removed by setting the + * MBEDTLS_ECP_NO_FALLBACK option, in which case any function for which the + * corresponding MBEDTLS_ECP__FUNCTION_NAME__ALT macro is defined will not be + * able to fallback to curves not supported by the alternative implementation. + * + * Any of these options become available by defining MBEDTLS_ECP_INTERNAL_ALT + * and implementing the following functions: + * unsigned char mbedtls_internal_ecp_grp_capable( + * const mbedtls_ecp_group *grp ) + * int mbedtls_internal_ecp_init( const mbedtls_ecp_group *grp ) + * void mbedtls_internal_ecp_free( const mbedtls_ecp_group *grp ) + * The mbedtls_internal_ecp_grp_capable function should return 1 if the + * replacement functions implement arithmetic for the given group and 0 + * otherwise. + * The functions mbedtls_internal_ecp_init and mbedtls_internal_ecp_free are + * called before and after each point operation and provide an opportunity to + * implement optimized set up and tear down instructions. + * + * Example: In case you set MBEDTLS_ECP_INTERNAL_ALT and + * MBEDTLS_ECP_DOUBLE_JAC_ALT, Mbed TLS will still provide the ecp_double_jac() + * function, but will use your mbedtls_internal_ecp_double_jac() if the group + * for the operation is supported by your implementation (i.e. your + * mbedtls_internal_ecp_grp_capable() function returns 1 for this group). If the + * group is not supported by your implementation, then the original Mbed TLS + * implementation of ecp_double_jac() is used instead, unless this fallback + * behaviour is disabled by setting MBEDTLS_ECP_NO_FALLBACK (in which case + * ecp_double_jac() will return MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE). + * + * The function prototypes and the definition of mbedtls_ecp_group and + * mbedtls_ecp_point will not change based on MBEDTLS_ECP_INTERNAL_ALT, so your + * implementation of mbedtls_internal_ecp__function_name__ must be compatible + * with their definitions. + * + * Uncomment a macro to enable alternate implementation of the corresponding + * function. + */ +/* Required for all the functions in this section */ +//#define MBEDTLS_ECP_INTERNAL_ALT +/* Turn off software fallback for curves not supported in hardware */ +//#define MBEDTLS_ECP_NO_FALLBACK +/* Support for Weierstrass curves with Jacobi representation */ +//#define MBEDTLS_ECP_RANDOMIZE_JAC_ALT +//#define MBEDTLS_ECP_ADD_MIXED_ALT +//#define MBEDTLS_ECP_DOUBLE_JAC_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_MANY_ALT +//#define MBEDTLS_ECP_NORMALIZE_JAC_ALT +/* Support for curves with Montgomery arithmetic */ +//#define MBEDTLS_ECP_DOUBLE_ADD_MXZ_ALT +//#define MBEDTLS_ECP_RANDOMIZE_MXZ_ALT +//#define MBEDTLS_ECP_NORMALIZE_MXZ_ALT -/* Generate errors if deprecated functions are used. */ -#define MBEDTLS_DEPRECATED_REMOVED +/** + * \def MBEDTLS_ENTROPY_HARDWARE_ALT + * + * Uncomment this macro to let Mbed TLS use your own implementation of a + * hardware entropy collector. + * + * Your function must be called \c mbedtls_hardware_poll(), have the same + * prototype as declared in library/entropy_poll.h, and accept NULL as first + * argument. + * + * Uncomment to use your own hardware entropy collector. + */ +//#define MBEDTLS_ENTROPY_HARDWARE_ALT -/* Place AES tables in ROM. */ +/** + * \def MBEDTLS_AES_ROM_TABLES + * + * Use precomputed AES tables stored in ROM. + * + * Uncomment this macro to use precomputed AES tables stored in ROM. + * Comment this macro to generate AES tables in RAM at runtime. + * + * Tradeoff: Using precomputed ROM tables reduces RAM usage by ~8kb + * (or ~2kb if \c MBEDTLS_AES_FEWER_TABLES is used) and reduces the + * initialization time before the first AES operation can be performed. + * It comes at the cost of additional ~8kb ROM use (resp. ~2kb if \c + * MBEDTLS_AES_FEWER_TABLES below is used), and potentially degraded + * performance if ROM access is slower than RAM access. + * + * This option is independent of \c MBEDTLS_AES_FEWER_TABLES. + */ #define MBEDTLS_AES_ROM_TABLES -/* Enable the following cipher modes. */ +/** + * \def MBEDTLS_AES_FEWER_TABLES + * + * Use less ROM/RAM for AES tables. + * + * Uncommenting this macro omits 75% of the AES tables from + * ROM / RAM (depending on the value of \c MBEDTLS_AES_ROM_TABLES) + * by computing their values on the fly during operations + * (the tables are entry-wise rotations of one another). + * + * Tradeoff: Uncommenting this reduces the RAM / ROM footprint + * by ~6kb but at the cost of more arithmetic operations during + * runtime. Specifically, one has to compare 4 accesses within + * different tables to 4 accesses with additional arithmetic + * operations within the same table. The performance gain/loss + * depends on the system and memory details. + * + * This option is independent of \c MBEDTLS_AES_ROM_TABLES. + */ +//#define MBEDTLS_AES_FEWER_TABLES + +/** + * \def MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH + * + * Use only 128-bit keys in AES operations to save ROM. + * + * Uncomment this macro to remove support for AES operations that use 192- + * or 256-bit keys. + * + * Uncommenting this macro reduces the size of AES code by ~300 bytes + * on v8-M/Thumb2. + * + * Module: library/aes.c + * + * Requires: MBEDTLS_AES_C + */ +//#define MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH + +/* + * Disable plain C implementation for AES. + * + * When the plain C implementation is enabled, and an implementation using a + * special CPU feature (such as MBEDTLS_AESCE_C) is also enabled, runtime + * detection will be used to select between them. + * + * If only one implementation is present, runtime detection will not be used. + * This configuration will crash at runtime if running on a CPU without the + * necessary features. It will not build unless at least one of MBEDTLS_AESCE_C + * and/or MBEDTLS_AESNI_C is enabled & present in the build. + */ +//#define MBEDTLS_AES_USE_HARDWARE_ONLY + +/** + * \def MBEDTLS_CAMELLIA_SMALL_MEMORY + * + * Use less ROM for the Camellia implementation (saves about 768 bytes). + * + * Uncomment this macro to use less memory for Camellia. + */ +//#define MBEDTLS_CAMELLIA_SMALL_MEMORY + +/** + * \def MBEDTLS_CHECK_RETURN_WARNING + * + * If this macro is defined, emit a compile-time warning if application code + * calls a function without checking its return value, but the return value + * should generally be checked in portable applications. + * + * This is only supported on platforms where #MBEDTLS_CHECK_RETURN is + * implemented. Otherwise this option has no effect. + * + * Uncomment to get warnings on using fallible functions without checking + * their return value. + * + * \note This feature is a work in progress. + * Warnings will be added to more functions in the future. + * + * \note A few functions are considered critical, and ignoring the return + * value of these functions will trigger a warning even if this + * macro is not defined. To completely disable return value check + * warnings, define #MBEDTLS_CHECK_RETURN with an empty expansion. + */ +//#define MBEDTLS_CHECK_RETURN_WARNING + +/** + * \def MBEDTLS_CIPHER_MODE_CBC + * + * Enable Cipher Block Chaining mode (CBC) for symmetric ciphers. + */ #define MBEDTLS_CIPHER_MODE_CBC + +/** + * \def MBEDTLS_CIPHER_MODE_CFB + * + * Enable Cipher Feedback mode (CFB) for symmetric ciphers. + */ #define MBEDTLS_CIPHER_MODE_CFB + +/** + * \def MBEDTLS_CIPHER_MODE_CTR + * + * Enable Counter Block Cipher mode (CTR) for symmetric ciphers. + */ #define MBEDTLS_CIPHER_MODE_CTR -/* Enable the following cipher padding modes. */ +/** + * \def MBEDTLS_CIPHER_MODE_OFB + * + * Enable Output Feedback mode (OFB) for symmetric ciphers. + */ +#define MBEDTLS_CIPHER_MODE_OFB + +/** + * \def MBEDTLS_CIPHER_MODE_XTS + * + * Enable Xor-encrypt-xor with ciphertext stealing mode (XTS) for AES. + */ +#define MBEDTLS_CIPHER_MODE_XTS + +/** + * \def MBEDTLS_CIPHER_NULL_CIPHER + * + * Enable NULL cipher. + * Warning: Only do so when you know what you are doing. This allows for + * encryption or channels without any security! + * + * To enable the following ciphersuites: + * MBEDTLS_TLS_ECDH_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_WITH_NULL_SHA + * MBEDTLS_TLS_RSA_WITH_NULL_MD5 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_NULL_SHA + * MBEDTLS_TLS_PSK_WITH_NULL_SHA384 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA256 + * MBEDTLS_TLS_PSK_WITH_NULL_SHA + * + * Uncomment this macro to enable the NULL cipher and ciphersuites + */ +//#define MBEDTLS_CIPHER_NULL_CIPHER + +/** + * \def MBEDTLS_CIPHER_PADDING_PKCS7 + * + * MBEDTLS_CIPHER_PADDING_XXX: Uncomment or comment macros to add support for + * specific padding modes in the cipher layer with cipher modes that support + * padding (e.g. CBC) + * + * If you disable all padding modes, only full blocks can be used with CBC. + * + * Enable padding modes in the cipher layer. + */ #define MBEDTLS_CIPHER_PADDING_PKCS7 #define MBEDTLS_CIPHER_PADDING_ONE_AND_ZEROS #define MBEDTLS_CIPHER_PADDING_ZEROS_AND_LEN #define MBEDTLS_CIPHER_PADDING_ZEROS -/* Cipher suite configuration. */ -#define MBEDTLS_REMOVE_ARC4_CIPHERSUITES +/** \def MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + * + * Uncomment this macro to use a 128-bit key in the CTR_DRBG module. + * Without this, CTR_DRBG uses a 256-bit key + * unless \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set. + */ +//#define MBEDTLS_CTR_DRBG_USE_128_BIT_KEY + +/** + * Enable the verified implementations of ECDH primitives from Project Everest + * (currently only Curve25519). This feature changes the layout of ECDH + * contexts and therefore is a compatibility break for applications that access + * fields of a mbedtls_ecdh_context structure directly. See also + * MBEDTLS_ECDH_LEGACY_CONTEXT in include/mbedtls/ecdh.h. + * + * The Everest code is provided under the Apache 2.0 license only; therefore enabling this + * option is not compatible with taking the library under the GPL v2.0-or-later license. + */ +//#define MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED + +/** + * \def MBEDTLS_ECP_DP_SECP192R1_ENABLED + * + * MBEDTLS_ECP_XXXX_ENABLED: Enables specific curves within the Elliptic Curve + * module. By default all supported curves are enabled. + * + * Comment macros to disable the curve and functions for it + */ +/* Short Weierstrass curves (supporting ECP, ECDH, ECDSA) */ +#define MBEDTLS_ECP_DP_SECP192R1_ENABLED +#define MBEDTLS_ECP_DP_SECP224R1_ENABLED #define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_DP_SECP384R1_ENABLED +#define MBEDTLS_ECP_DP_SECP521R1_ENABLED +#define MBEDTLS_ECP_DP_SECP192K1_ENABLED +#define MBEDTLS_ECP_DP_SECP224K1_ENABLED +#define MBEDTLS_ECP_DP_SECP256K1_ENABLED +#define MBEDTLS_ECP_DP_BP256R1_ENABLED +#define MBEDTLS_ECP_DP_BP384R1_ENABLED +#define MBEDTLS_ECP_DP_BP512R1_ENABLED +/* Montgomery curves (supporting ECP) */ +#define MBEDTLS_ECP_DP_CURVE25519_ENABLED +#define MBEDTLS_ECP_DP_CURVE448_ENABLED + +/** + * \def MBEDTLS_ECP_NIST_OPTIM + * + * Enable specific 'modulo p' routines for each NIST prime. + * Depending on the prime and architecture, makes operations 4 to 8 times + * faster on the corresponding curve. + * + * Comment this macro to disable NIST curves optimisation. + */ #define MBEDTLS_ECP_NIST_OPTIM -#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED -#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED -/* Enable all SSL alert messages. */ -#define MBEDTLS_SSL_ALL_ALERT_MESSAGES +/** + * \def MBEDTLS_ECP_RESTARTABLE + * + * Enable "non-blocking" ECC operations that can return early and be resumed. + * + * This allows various functions to pause by returning + * #MBEDTLS_ERR_ECP_IN_PROGRESS (or, for functions in the SSL module, + * #MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS) and then be called later again in + * order to further progress and eventually complete their operation. This is + * controlled through mbedtls_ecp_set_max_ops() which limits the maximum + * number of ECC operations a function may perform before pausing; see + * mbedtls_ecp_set_max_ops() for more information. + * + * This is useful in non-threaded environments if you want to avoid blocking + * for too long on ECC (and, hence, X.509 or SSL/TLS) operations. + * + * This option: + * - Adds xxx_restartable() variants of existing operations in the + * following modules, with corresponding restart context types: + * - ECP (for Short Weierstrass curves only): scalar multiplication (mul), + * linear combination (muladd); + * - ECDSA: signature generation & verification; + * - PK: signature generation & verification; + * - X509: certificate chain verification. + * - Adds mbedtls_ecdh_enable_restart() in the ECDH module. + * - Changes the behaviour of TLS 1.2 clients (not servers) when using the + * ECDHE-ECDSA key exchange (not other key exchanges) to make all ECC + * computations restartable: + * - ECDH operations from the key exchange, only for Short Weierstrass + * curves, only when MBEDTLS_USE_PSA_CRYPTO is not enabled. + * - verification of the server's key exchange signature; + * - verification of the server's certificate chain; + * - generation of the client's signature if client authentication is used, + * with an ECC key/certificate. + * + * \note In the cases above, the usual SSL/TLS functions, such as + * mbedtls_ssl_handshake(), can now return + * MBEDTLS_ERR_SSL_CRYPTO_IN_PROGRESS. + * + * \note When this option and MBEDTLS_USE_PSA_CRYPTO are both enabled, + * restartable operations in PK, X.509 and TLS (see above) are not + * using PSA. On the other hand, ECDH computations in TLS are using + * PSA, and are not restartable. These are temporary limitations that + * should be lifted in the future. + * + * \note This option only works with the default software implementation of + * elliptic curve functionality. It is incompatible with + * MBEDTLS_ECP_ALT, MBEDTLS_ECDH_XXX_ALT, MBEDTLS_ECDSA_XXX_ALT. + * + * Requires: MBEDTLS_ECP_C + * + * Uncomment this macro to enable restartable ECC computations. + */ +#define MBEDTLS_ECP_RESTARTABLE -/* Enable the following SSL features. */ -#define MBEDTLS_SSL_ENCRYPT_THEN_MAC -#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET -#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH -#define MBEDTLS_SSL_PROTO_TLS1_2 -#define MBEDTLS_SSL_ALPN -#define MBEDTLS_SSL_SERVER_NAME_INDICATION +/** + * Uncomment to enable using new bignum code in the ECC modules. + * + * \warning This is currently experimental, incomplete and therefore should not + * be used in production. + */ +//#define MBEDTLS_ECP_WITH_MPI_UINT -/* Check certificate key usage. */ -#define MBEDTLS_X509_CHECK_KEY_USAGE -#define MBEDTLS_X509_CHECK_EXTENDED_KEY_USAGE +/** + * \def MBEDTLS_ECDSA_DETERMINISTIC + * + * Enable deterministic ECDSA (RFC 6979). + * Standard ECDSA is "fragile" in the sense that lack of entropy when signing + * may result in a compromise of the long-term signing key. This is avoided by + * the deterministic variant. + * + * Requires: MBEDTLS_HMAC_DRBG_C, MBEDTLS_ECDSA_C + * + * Comment this macro to disable deterministic ECDSA. + */ +#define MBEDTLS_ECDSA_DETERMINISTIC -/* Enable PKCS11 features */ -#define MBEDTLS_PK_RSA_ALT_SUPPORT -#define MBEDTLS_GENPRIME +/** + * \def MBEDTLS_KEY_EXCHANGE_PSK_ENABLED + * + * Enable the PSK based ciphersuite modes in SSL / TLS. + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED -/* Enable the following MbedTLS features. */ -#define MBEDTLS_AES_C -#define MBEDTLS_ASN1_PARSE_C -#define MBEDTLS_ASN1_WRITE_C -#define MBEDTLS_BASE64_C -#define MBEDTLS_BIGNUM_C -#define MBEDTLS_CIPHER_C -#define MBEDTLS_CMAC_C -#define MBEDTLS_CTR_DRBG_C -#define MBEDTLS_DEBUG_C -#define MBEDTLS_ECDH_C -#define MBEDTLS_ECDSA_C -#define MBEDTLS_ECP_C -#define MBEDTLS_ENTROPY_C -#define MBEDTLS_ERROR_C -#define MBEDTLS_GCM_C -#define MBEDTLS_MD_C -#define MBEDTLS_OID_C -#define MBEDTLS_PEM_PARSE_C -#define MBEDTLS_PEM_WRITE_C -#define MBEDTLS_PK_C -#define MBEDTLS_PK_PARSE_C -#define MBEDTLS_PK_WRITE_C -#define MBEDTLS_PKCS1_V15 -#define MBEDTLS_PLATFORM_C -#define MBEDTLS_RSA_C -#define MBEDTLS_SHA1_C -#define MBEDTLS_SHA256_C +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + * + * Enable the DHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +#define MBEDTLS_KEY_EXCHANGE_DHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + * + * Enable the ECDHE-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + * + * Enable the RSA-PSK based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + * + * Enable the RSA-only based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + */ +#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + * + * Enable the DHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_DHM_C, MBEDTLS_RSA_C, MBEDTLS_PKCS1_V15, + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +#define MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + * + * Enable the ECDHE-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_RSA_C + * MBEDTLS_PKCS1_V15 + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + * + * Enable the ECDHE-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + */ +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + * + * Enable the ECDH-ECDSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + * + * Enable the ECDH-RSA based ciphersuite modes in SSL / TLS. + * + * Requires: MBEDTLS_ECDH_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDH) + * MBEDTLS_RSA_C + * MBEDTLS_X509_CRT_PARSE_C + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + */ +#define MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED + +/** + * \def MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + * + * Enable the ECJPAKE based ciphersuite modes in SSL / TLS. + * + * \warning This is currently experimental. EC J-PAKE support is based on the + * Thread v1.0.0 specification; incompatible changes to the specification + * might still happen. For this reason, this is disabled by default. + * + * Requires: MBEDTLS_ECJPAKE_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_JPAKE) + * SHA-256 (via MBEDTLS_SHA256_C or a PSA driver) + * MBEDTLS_ECP_DP_SECP256R1_ENABLED + * + * \warning If SHA-256 is provided only by a PSA driver, you must call + * psa_crypto_init() before the first hanshake (even if + * MBEDTLS_USE_PSA_CRYPTO is disabled). + * + * This enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + */ +//#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED + +/** + * \def MBEDTLS_PK_PARSE_EC_EXTENDED + * + * Enhance support for reading EC keys using variants of SEC1 not allowed by + * RFC 5915 and RFC 5480. + * + * Currently this means parsing the SpecifiedECDomain choice of EC + * parameters (only known groups are supported, not arbitrary domains, to + * avoid validation issues). + * + * Disable if you only need to support RFC 5915 + 5480 key formats. + */ +#define MBEDTLS_PK_PARSE_EC_EXTENDED + +/** + * \def MBEDTLS_PK_PARSE_EC_COMPRESSED + * + * Enable the support for parsing public keys of type Short Weierstrass + * (MBEDTLS_ECP_DP_SECP_XXX and MBEDTLS_ECP_DP_BP_XXX) which are using the + * compressed point format. This parsing is done through ECP module's functions. + * + * \note As explained in the description of MBEDTLS_ECP_PF_COMPRESSED (in ecp.h) + * the only unsupported curves are MBEDTLS_ECP_DP_SECP224R1 and + * MBEDTLS_ECP_DP_SECP224K1. + */ +#define MBEDTLS_PK_PARSE_EC_COMPRESSED + +/** + * \def MBEDTLS_ERROR_STRERROR_DUMMY + * + * Enable a dummy error function to make use of mbedtls_strerror() in + * third party libraries easier when MBEDTLS_ERROR_C is disabled + * (no effect when MBEDTLS_ERROR_C is enabled). + * + * You can safely disable this if MBEDTLS_ERROR_C is enabled, or if you're + * not using mbedtls_strerror() or error_strerror() in your application. + * + * Disable if you run into name conflicts and want to really remove the + * mbedtls_strerror() + */ +#define MBEDTLS_ERROR_STRERROR_DUMMY + +/** + * \def MBEDTLS_GENPRIME + * + * Enable the prime-number generation code. + * + * Requires: MBEDTLS_BIGNUM_C + */ +#define MBEDTLS_GENPRIME + +/** + * \def MBEDTLS_FS_IO + * + * Enable functions that use the filesystem. + */ +#define MBEDTLS_FS_IO + +/** + * \def MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + * + * Do not add default entropy sources in mbedtls_entropy_init(). + * + * This is useful to have more control over the added entropy sources in an + * application. + * + * Uncomment this macro to prevent loading of default entropy functions. + */ +//#define MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES + +/** + * \def MBEDTLS_NO_PLATFORM_ENTROPY + * + * Do not use built-in platform entropy functions. + * This is useful if your platform does not support + * standards like the /dev/urandom or Windows CryptoAPI. + * + * Uncomment this macro to disable the built-in platform entropy functions. + */ +//#define MBEDTLS_NO_PLATFORM_ENTROPY + +/** + * \def MBEDTLS_ENTROPY_FORCE_SHA256 + * + * Force the entropy accumulator to use a SHA-256 accumulator instead of the + * default SHA-512 based one (if both are available). + * + * Requires: MBEDTLS_SHA256_C + * + * On 32-bit systems SHA-256 can be much faster than SHA-512. Use this option + * if you have performance concerns. + * + * This option is only useful if both MBEDTLS_SHA256_C and + * MBEDTLS_SHA512_C are defined. Otherwise the available hash module is used. + */ +//#define MBEDTLS_ENTROPY_FORCE_SHA256 + +/** + * \def MBEDTLS_ENTROPY_NV_SEED + * + * Enable the non-volatile (NV) seed file-based entropy source. + * (Also enables the NV seed read/write functions in the platform layer) + * + * This is crucial (if not required) on systems that do not have a + * cryptographic entropy source (in hardware or kernel) available. + * + * Requires: MBEDTLS_ENTROPY_C, MBEDTLS_PLATFORM_C + * + * \note The read/write functions that are used by the entropy source are + * determined in the platform layer, and can be modified at runtime and/or + * compile-time depending on the flags (MBEDTLS_PLATFORM_NV_SEED_*) used. + * + * \note If you use the default implementation functions that read a seedfile + * with regular fopen(), please make sure you make a seedfile with the + * proper name (defined in MBEDTLS_PLATFORM_STD_NV_SEED_FILE) and at + * least MBEDTLS_ENTROPY_BLOCK_SIZE bytes in size that can be read from + * and written to or you will get an entropy source error! The default + * implementation will only use the first MBEDTLS_ENTROPY_BLOCK_SIZE + * bytes from the file. + * + * \note The entropy collector will write to the seed file before entropy is + * given to an external source, to update it. + */ +//#define MBEDTLS_ENTROPY_NV_SEED + +/* MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + * + * Enable key identifiers that encode a key owner identifier. + * + * The owner of a key is identified by a value of type ::mbedtls_key_owner_id_t + * which is currently hard-coded to be int32_t. + * + * Note that this option is meant for internal use only and may be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER + +/** + * \def MBEDTLS_MEMORY_DEBUG + * + * Enable debugging of buffer allocator memory issues. Automatically prints + * (to stderr) all (fatal) messages on memory allocation issues. Enables + * function for 'debug output' of allocated memory. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Uncomment this macro to let the buffer allocator print out error messages. + */ +//#define MBEDTLS_MEMORY_DEBUG + +/** + * \def MBEDTLS_MEMORY_BACKTRACE + * + * Include backtrace information with each allocated block. + * + * Requires: MBEDTLS_MEMORY_BUFFER_ALLOC_C + * GLIBC-compatible backtrace() and backtrace_symbols() support + * + * Uncomment this macro to include backtrace information + */ +//#define MBEDTLS_MEMORY_BACKTRACE + +/** + * \def MBEDTLS_PK_RSA_ALT_SUPPORT + * + * Support external private RSA keys (eg from a HSM) in the PK layer. + * + * Comment this macro to disable support for external private RSA keys. + */ +// #define MBEDTLS_PK_RSA_ALT_SUPPORT + +/** + * \def MBEDTLS_PKCS1_V15 + * + * Enable support for PKCS#1 v1.5 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * This enables support for PKCS#1 v1.5 operations. + */ +#define MBEDTLS_PKCS1_V15 + +/** + * \def MBEDTLS_PKCS1_V21 + * + * Enable support for PKCS#1 v2.1 encoding. + * + * Requires: MBEDTLS_RSA_C + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any PKCS#1 v2.1 operation. + * + * This enables support for RSAES-OAEP and RSASSA-PSS operations. + */ +#define MBEDTLS_PKCS1_V21 + +/** \def MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + * + * Enable support for platform built-in keys. If you enable this feature, + * you must implement the function mbedtls_psa_platform_get_builtin_key(). + * See the documentation of that function for more information. + * + * Built-in keys are typically derived from a hardware unique key or + * stored in a secure element. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_BUILTIN_KEYS + +/** \def MBEDTLS_PSA_CRYPTO_CLIENT + * + * Enable support for PSA crypto client. + * + * \note This option allows to include the code necessary for a PSA + * crypto client when the PSA crypto implementation is not included in + * the library (MBEDTLS_PSA_CRYPTO_C disabled). The code included is the + * code to set and get PSA key attributes. + * The development of PSA drivers partially relying on the library to + * fulfill the hardware gaps is another possible usage of this option. + * + * \warning This interface is experimental and may change or be removed + * without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_CLIENT + +/** \def MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + * + * Make the PSA Crypto module use an external random generator provided + * by a driver, instead of Mbed TLS's entropy and DRBG modules. + * + * \note This random generator must deliver random numbers with cryptographic + * quality and high performance. It must supply unpredictable numbers + * with a uniform distribution. The implementation of this function + * is responsible for ensuring that the random generator is seeded + * with sufficient entropy. If you have a hardware TRNG which is slow + * or delivers non-uniform output, declare it as an entropy source + * with mbedtls_entropy_add_source() instead of enabling this option. + * + * If you enable this option, you must configure the type + * ::mbedtls_psa_external_random_context_t in psa/crypto_platform.h + * and define a function called mbedtls_psa_external_get_random() + * with the following prototype: + * ``` + * psa_status_t mbedtls_psa_external_get_random( + * mbedtls_psa_external_random_context_t *context, + * uint8_t *output, size_t output_size, size_t *output_length); + * ); + * ``` + * The \c context value is initialized to 0 before the first call. + * The function must fill the \c output buffer with \c output_size bytes + * of random data and set \c *output_length to \c output_size. + * + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * \warning If you enable this option, code that uses the PSA cryptography + * interface will not use any of the entropy sources set up for + * the entropy module, nor the NV seed that MBEDTLS_ENTROPY_NV_SEED + * enables. + * + * \note This option is experimental and may be removed without notice. + */ +//#define MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG + +/** + * \def MBEDTLS_PSA_CRYPTO_SPM + * + * When MBEDTLS_PSA_CRYPTO_SPM is defined, the code is built for SPM (Secure + * Partition Manager) integration which separates the code into two parts: a + * NSPE (Non-Secure Process Environment) and an SPE (Secure Process + * Environment). + * + * If you enable this option, your build environment must include a header + * file `"crypto_spe.h"` (either in the `psa` subdirectory of the Mbed TLS + * header files, or in another directory on the compiler's include search + * path). Alternatively, your platform may customize the header + * `psa/crypto_platform.h`, in which case it can skip or replace the + * inclusion of `"crypto_spe.h"`. + * + * Module: library/psa_crypto.c + * Requires: MBEDTLS_PSA_CRYPTO_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SPM + +/** + * Uncomment to enable p256-m. This is an alternative implementation of + * key generation, ECDH and (randomized) ECDSA on the curve SECP256R1. + * Compared to the default implementation: + * + * - p256-m has a much smaller code size and RAM footprint. + * - p256-m is only available via the PSA API. This includes the pk module + * when #MBEDTLS_USE_PSA_CRYPTO is enabled. + * - p256-m does not support deterministic ECDSA, EC-JPAKE, custom protocols + * over the core arithmetic, or deterministic derivation of keys. + * + * We recommend enabling this option if your application uses the PSA API + * and the only elliptic curve support it needs is ECDH and ECDSA over + * SECP256R1. + * + * If you enable this option, you do not need to enable any ECC-related + * MBEDTLS_xxx option. You do need to separately request support for the + * cryptographic mechanisms through the PSA API: + * - #MBEDTLS_PSA_CRYPTO_C and #MBEDTLS_PSA_CRYPTO_CONFIG for PSA-based + * configuration; + * - #MBEDTLS_USE_PSA_CRYPTO if you want to use p256-m from PK, X.509 or TLS; + * - #PSA_WANT_ECC_SECP_R1_256; + * - #PSA_WANT_ALG_ECDH and/or #PSA_WANT_ALG_ECDSA as needed; + * - #PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY, #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_BASIC, + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT, + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT and/or + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE as needed. + * + * \note To benefit from the smaller code size of p256-m, make sure that you + * do not enable any ECC-related option not supported by p256-m: this + * would cause the built-in ECC implementation to be built as well, in + * order to provide the required option. + * Make sure #PSA_WANT_ALG_DETERMINISTIC_ECDSA, #PSA_WANT_ALG_JPAKE and + * #PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_DERIVE, and curves other than + * SECP256R1 are disabled as they are not supported by this driver. + * Also, avoid defining #MBEDTLS_PK_PARSE_EC_COMPRESSED or + * #MBEDTLS_PK_PARSE_EC_EXTENDED as those currently require a subset of + * the built-in ECC implementation, see docs/driver-only-builds.md. + */ +//#define MBEDTLS_PSA_P256M_DRIVER_ENABLED + +/** + * \def MBEDTLS_PSA_INJECT_ENTROPY + * + * Enable support for entropy injection at first boot. This feature is + * required on systems that do not have a built-in entropy source (TRNG). + * This feature is currently not supported on systems that have a built-in + * entropy source. + * + * Requires: MBEDTLS_PSA_CRYPTO_STORAGE_C, MBEDTLS_ENTROPY_NV_SEED + * + */ +//#define MBEDTLS_PSA_INJECT_ENTROPY + +/** + * \def MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS + * + * Assume all buffers passed to PSA functions are owned exclusively by the + * PSA function and are not stored in shared memory. + * + * This option may be enabled if all buffers passed to any PSA function reside + * in memory that is accessible only to the PSA function during its execution. + * + * This option MUST be disabled whenever buffer arguments are in memory shared + * with an untrusted party, for example where arguments to PSA calls are passed + * across a trust boundary. + * + * \note Enabling this option reduces memory usage and code size. + * + * \note Enabling this option causes overlap of input and output buffers + * not to be supported by PSA functions. + */ +//#define MBEDTLS_PSA_ASSUME_EXCLUSIVE_BUFFERS + +/** + * \def MBEDTLS_RSA_NO_CRT + * + * Do not use the Chinese Remainder Theorem + * for the RSA private operation. + * + * Uncomment this macro to disable the use of CRT in RSA. + * + */ +//#define MBEDTLS_RSA_NO_CRT + +/** + * \def MBEDTLS_SELF_TEST + * + * Enable the checkup functions (*_self_test). + */ +#define MBEDTLS_SELF_TEST + +/** + * \def MBEDTLS_SHA256_SMALLER + * + * Enable an implementation of SHA-256 that has lower ROM footprint but also + * lower performance. + * + * The default implementation is meant to be a reasonable compromise between + * performance and size. This version optimizes more aggressively for size at + * the expense of performance. Eg on Cortex-M4 it reduces the size of + * mbedtls_sha256_process() from ~2KB to ~0.5KB for a performance hit of about + * 30%. + * + * Uncomment to enable the smaller implementation of SHA256. + */ +//#define MBEDTLS_SHA256_SMALLER + +/** + * \def MBEDTLS_SHA512_SMALLER + * + * Enable an implementation of SHA-512 that has lower ROM footprint but also + * lower performance. + * + * Uncomment to enable the smaller implementation of SHA512. + */ +//#define MBEDTLS_SHA512_SMALLER + +/** + * \def MBEDTLS_SSL_ALL_ALERT_MESSAGES + * + * Enable sending of alert messages in case of encountered errors as per RFC. + * If you choose not to send the alert messages, Mbed TLS can still communicate + * with other servers, only debugging of failures is harder. + * + * The advantage of not sending alert messages, is that no information is given + * about reasons for failures thus preventing adversaries of gaining intel. + * + * Enable sending of all alert messages + */ +#define MBEDTLS_SSL_ALL_ALERT_MESSAGES + +/** + * \def MBEDTLS_SSL_DTLS_CONNECTION_ID + * + * Enable support for the DTLS Connection ID (CID) extension, + * which allows to identify DTLS connections across changes + * in the underlying transport. The CID functionality is described + * in RFC 9146. + * + * Setting this option enables the SSL APIs `mbedtls_ssl_set_cid()`, + * mbedtls_ssl_get_own_cid()`, `mbedtls_ssl_get_peer_cid()` and + * `mbedtls_ssl_conf_cid()`. See the corresponding documentation for + * more information. + * + * The maximum lengths of outgoing and incoming CIDs can be configured + * through the options + * - MBEDTLS_SSL_CID_OUT_LEN_MAX + * - MBEDTLS_SSL_CID_IN_LEN_MAX. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment to enable the Connection ID extension. + */ +#define MBEDTLS_SSL_DTLS_CONNECTION_ID + + +/** + * \def MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT + * + * Defines whether RFC 9146 (default) or the legacy version + * (version draft-ietf-tls-dtls-connection-id-05, + * https://tools.ietf.org/html/draft-ietf-tls-dtls-connection-id-05) + * is used. + * + * Set the value to 0 for the standard version, and + * 1 for the legacy draft version. + * + * \deprecated Support for the legacy version of the DTLS + * Connection ID feature is deprecated. Please + * switch to the standardized version defined + * in RFC 9146 enabled by utilizing + * MBEDTLS_SSL_DTLS_CONNECTION_ID without use + * of MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT. + * + * Requires: MBEDTLS_SSL_DTLS_CONNECTION_ID + */ +#define MBEDTLS_SSL_DTLS_CONNECTION_ID_COMPAT 0 + +/** + * \def MBEDTLS_SSL_ASYNC_PRIVATE + * + * Enable asynchronous external private key operations in SSL. This allows + * you to configure an SSL connection to call an external cryptographic + * module to perform private key operations instead of performing the + * operation inside the library. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + */ +//#define MBEDTLS_SSL_ASYNC_PRIVATE + +/** + * \def MBEDTLS_SSL_CONTEXT_SERIALIZATION + * + * Enable serialization of the TLS context structures, through use of the + * functions mbedtls_ssl_context_save() and mbedtls_ssl_context_load(). + * + * This pair of functions allows one side of a connection to serialize the + * context associated with the connection, then free or re-use that context + * while the serialized state is persisted elsewhere, and finally deserialize + * that state to a live context for resuming read/write operations on the + * connection. From a protocol perspective, the state of the connection is + * unaffected, in particular this is entirely transparent to the peer. + * + * Note: this is distinct from TLS session resumption, which is part of the + * protocol and fully visible by the peer. TLS session resumption enables + * establishing new connections associated to a saved session with shorter, + * lighter handshakes, while context serialization is a local optimization in + * handling a single, potentially long-lived connection. + * + * Enabling these APIs makes some SSL structures larger, as 64 extra bytes are + * saved after the handshake to allow for more efficient serialization, so if + * you don't need this feature you'll save RAM by disabling it. + * + * Requires: MBEDTLS_GCM_C or MBEDTLS_CCM_C or MBEDTLS_CHACHAPOLY_C + * + * Comment to disable the context serialization APIs. + */ +#define MBEDTLS_SSL_CONTEXT_SERIALIZATION + +/** + * \def MBEDTLS_SSL_DEBUG_ALL + * + * Enable the debug messages in SSL module for all issues. + * Debug messages have been disabled in some places to prevent timing + * attacks due to (unbalanced) debugging function calls. + * + * If you need all error reporting you should enable this during debugging, + * but remove this for production servers that should log as well. + * + * Uncomment this macro to report all debug messages on errors introducing + * a timing side-channel. + * + */ +//#define MBEDTLS_SSL_DEBUG_ALL + +/** \def MBEDTLS_SSL_ENCRYPT_THEN_MAC + * + * Enable support for Encrypt-then-MAC, RFC 7366. + * + * This allows peers that both support it to use a more robust protection for + * ciphersuites using CBC, providing deep resistance against timing attacks + * on the padding or underlying cipher. + * + * This only affects CBC ciphersuites, and is useless if none is defined. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Encrypt-then-MAC + */ +#define MBEDTLS_SSL_ENCRYPT_THEN_MAC + +/** \def MBEDTLS_SSL_EXTENDED_MASTER_SECRET + * + * Enable support for RFC 7627: Session Hash and Extended Master Secret + * Extension. + * + * This was introduced as "the proper fix" to the Triple Handshake family of + * attacks, but it is recommended to always use it (even if you disable + * renegotiation), since it actually fixes a more fundamental issue in the + * original SSL/TLS design, and has implications beyond Triple Handshake. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for Extended Master Secret. + */ +#define MBEDTLS_SSL_EXTENDED_MASTER_SECRET + +/** + * \def MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * + * This option controls the availability of the API mbedtls_ssl_get_peer_cert() + * giving access to the peer's certificate after completion of the handshake. + * + * Unless you need mbedtls_ssl_peer_cert() in your application, it is + * recommended to disable this option for reduced RAM usage. + * + * \note If this option is disabled, mbedtls_ssl_get_peer_cert() is still + * defined, but always returns \c NULL. + * + * \note This option has no influence on the protection against the + * triple handshake attack. Even if it is disabled, Mbed TLS will + * still ensure that certificates do not change during renegotiation, + * for example by keeping a hash of the peer's certificate. + * + * \note This option is required if MBEDTLS_SSL_PROTO_TLS1_3 is set. + * + * Comment this macro to disable storing the peer's certificate + * after the handshake. + */ +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + +/** + * \def MBEDTLS_SSL_RENEGOTIATION + * + * Enable support for TLS renegotiation. + * + * The two main uses of renegotiation are (1) refresh keys on long-lived + * connections and (2) client authentication after the initial handshake. + * If you don't need renegotiation, it's probably better to disable it, since + * it has been associated with security issues in the past and is easy to + * misuse/misunderstand. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this to disable support for renegotiation. + * + * \note Even if this option is disabled, both client and server are aware + * of the Renegotiation Indication Extension (RFC 5746) used to + * prevent the SSL renegotiation attack (see RFC 5746 Sect. 1). + * (See \c mbedtls_ssl_conf_legacy_renegotiation for the + * configuration of this extension). + * + */ +#define MBEDTLS_SSL_RENEGOTIATION + +/** + * \def MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + * + * Enable support for RFC 6066 max_fragment_length extension in SSL. + * + * Comment this macro to disable support for the max_fragment_length extension + */ +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + +/** + * \def MBEDTLS_SSL_RECORD_SIZE_LIMIT + * + * Enable support for RFC 8449 record_size_limit extension in SSL (TLS 1.3 only). + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_3 + * + * Uncomment this macro to enable support for the record_size_limit extension + */ +#define MBEDTLS_SSL_RECORD_SIZE_LIMIT + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_2 + * + * Enable support for TLS 1.2 (and DTLS 1.2 if DTLS is enabled). + * + * Requires: Without MBEDTLS_USE_PSA_CRYPTO: MBEDTLS_MD_C and + * (MBEDTLS_SHA256_C or MBEDTLS_SHA384_C or + * SHA-256 or SHA-512 provided by a PSA driver) + * With MBEDTLS_USE_PSA_CRYPTO: + * PSA_WANT_ALG_SHA_256 or PSA_WANT_ALG_SHA_384 + * + * \warning If building with MBEDTLS_USE_PSA_CRYPTO, or if the hash(es) used + * are only provided by PSA drivers, you must call psa_crypto_init() before + * doing any TLS operations. + * + * Comment this macro to disable support for TLS 1.2 / DTLS 1.2 + */ +#define MBEDTLS_SSL_PROTO_TLS1_2 + +/** + * \def MBEDTLS_SSL_PROTO_TLS1_3 + * + * Enable support for TLS 1.3. + * + * \note See docs/architecture/tls13-support.md for a description of the TLS + * 1.3 support that this option enables. + * + * Requires: MBEDTLS_SSL_KEEP_PEER_CERTIFICATE + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * \note TLS 1.3 uses PSA crypto for cryptographic operations that are + * directly performed by TLS 1.3 code. As a consequence, you must + * call psa_crypto_init() before the first TLS 1.3 handshake. + * + * \note Cryptographic operations performed indirectly via another module + * (X.509, PK) or by code shared with TLS 1.2 (record protection, + * running handshake hash) only use PSA crypto if + * #MBEDTLS_USE_PSA_CRYPTO is enabled. + * + * Uncomment this macro to enable the support for TLS 1.3. + */ +#define MBEDTLS_SSL_PROTO_TLS1_3 + +/** + * \def MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE + * + * Enable TLS 1.3 middlebox compatibility mode. + * + * As specified in Section D.4 of RFC 8446, TLS 1.3 offers a compatibility + * mode to make a TLS 1.3 connection more likely to pass through middle boxes + * expecting TLS 1.2 traffic. + * + * Turning on the compatibility mode comes at the cost of a few added bytes + * on the wire, but it doesn't affect compatibility with TLS 1.3 implementations + * that don't use it. Therefore, unless transmission bandwidth is critical and + * you know that middlebox compatibility issues won't occur, it is therefore + * recommended to set this option. + * + * Comment to disable compatibility mode for TLS 1.3. If + * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any + * effect on the build. + * + */ +#define MBEDTLS_SSL_TLS1_3_COMPATIBILITY_MODE + +/** + * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED + * + * Enable TLS 1.3 PSK key exchange mode. + * + * Comment to disable support for the PSK key exchange mode in TLS 1.3. If + * MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any + * effect on the build. + * + */ +#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED + +/** + * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED + * + * Enable TLS 1.3 ephemeral key exchange mode. + * + * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH + * MBEDTLS_X509_CRT_PARSE_C + * and at least one of: + * MBEDTLS_ECDSA_C or (MBEDTLS_USE_PSA_CRYPTO and PSA_WANT_ALG_ECDSA) + * MBEDTLS_PKCS1_V21 + * + * Comment to disable support for the ephemeral key exchange mode in TLS 1.3. + * If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not have any + * effect on the build. + * + */ +#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_EPHEMERAL_ENABLED + +/** + * \def MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED + * + * Enable TLS 1.3 PSK ephemeral key exchange mode. + * + * Requires: PSA_WANT_ALG_ECDH or PSA_WANT_ALG_FFDH + * + * Comment to disable support for the PSK ephemeral key exchange mode in + * TLS 1.3. If MBEDTLS_SSL_PROTO_TLS1_3 is not enabled, this option does not + * have any effect on the build. + * + */ +#define MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED + +/** + * \def MBEDTLS_SSL_EARLY_DATA + * + * Enable support for RFC 8446 TLS 1.3 early data. + * + * Requires: MBEDTLS_SSL_SESSION_TICKETS and either + * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_ENABLED or + * MBEDTLS_SSL_TLS1_3_KEY_EXCHANGE_MODE_PSK_EPHEMERAL_ENABLED + * + * Comment this to disable support for early data. If MBEDTLS_SSL_PROTO_TLS1_3 + * is not enabled, this option does not have any effect on the build. + * + * \note The maximum amount of early data can be set with + * MBEDTLS_SSL_MAX_EARLY_DATA_SIZE. + * + */ +//#define MBEDTLS_SSL_EARLY_DATA + +/** + * \def MBEDTLS_SSL_PROTO_DTLS + * + * Enable support for DTLS (all available versions). + * + * Enable this and MBEDTLS_SSL_PROTO_TLS1_2 to enable DTLS 1.2. + * + * Requires: MBEDTLS_SSL_PROTO_TLS1_2 + * + * Comment this macro to disable support for DTLS + */ +#define MBEDTLS_SSL_PROTO_DTLS + +/** + * \def MBEDTLS_SSL_ALPN + * + * Enable support for RFC 7301 Application Layer Protocol Negotiation. + * + * Comment this macro to disable support for ALPN. + */ +#define MBEDTLS_SSL_ALPN + +/** + * \def MBEDTLS_SSL_DTLS_ANTI_REPLAY + * + * Enable support for the anti-replay mechanism in DTLS. + * + * Requires: MBEDTLS_SSL_TLS_C + * MBEDTLS_SSL_PROTO_DTLS + * + * \warning Disabling this is often a security risk! + * See mbedtls_ssl_conf_dtls_anti_replay() for details. + * + * Comment this to disable anti-replay in DTLS. + */ +#define MBEDTLS_SSL_DTLS_ANTI_REPLAY + +/** + * \def MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Enable support for HelloVerifyRequest on DTLS servers. + * + * This feature is highly recommended to prevent DTLS servers being used as + * amplifiers in DoS attacks against other hosts. It should always be enabled + * unless you know for sure amplification cannot be a problem in the + * environment in which your server operates. + * + * \warning Disabling this can be a security risk! (see above) + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Comment this to disable support for HelloVerifyRequest. + */ +#define MBEDTLS_SSL_DTLS_HELLO_VERIFY + +/** + * \def MBEDTLS_SSL_DTLS_SRTP + * + * Enable support for negotiation of DTLS-SRTP (RFC 5764) + * through the use_srtp extension. + * + * \note This feature provides the minimum functionality required + * to negotiate the use of DTLS-SRTP and to allow the derivation of + * the associated SRTP packet protection key material. + * In particular, the SRTP packet protection itself, as well as the + * demultiplexing of RTP and DTLS packets at the datagram layer + * (see Section 5 of RFC 5764), are not handled by this feature. + * Instead, after successful completion of a handshake negotiating + * the use of DTLS-SRTP, the extended key exporter API + * mbedtls_ssl_conf_export_keys_cb() should be used to implement + * the key exporter described in Section 4.2 of RFC 5764 and RFC 5705 + * (this is implemented in the SSL example programs). + * The resulting key should then be passed to an SRTP stack. + * + * Setting this option enables the runtime API + * mbedtls_ssl_conf_dtls_srtp_protection_profiles() + * through which the supported DTLS-SRTP protection + * profiles can be configured. You must call this API at + * runtime if you wish to negotiate the use of DTLS-SRTP. + * + * Requires: MBEDTLS_SSL_PROTO_DTLS + * + * Uncomment this to enable support for use_srtp extension. + */ +//#define MBEDTLS_SSL_DTLS_SRTP + +/** + * \def MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + * + * Enable server-side support for clients that reconnect from the same port. + * + * Some clients unexpectedly close the connection and try to reconnect using the + * same source port. This needs special support from the server to handle the + * new connection securely, as described in section 4.2.8 of RFC 6347. This + * flag enables that support. + * + * Requires: MBEDTLS_SSL_DTLS_HELLO_VERIFY + * + * Comment this to disable support for clients reusing the source port. + */ +#define MBEDTLS_SSL_DTLS_CLIENT_PORT_REUSE + +/** + * \def MBEDTLS_SSL_SESSION_TICKETS + * + * Enable support for RFC 5077 session tickets in SSL. + * Client-side, provides full support for session tickets (maintenance of a + * session store remains the responsibility of the application, though). + * Server-side, you also need to provide callbacks for writing and parsing + * tickets, including authenticated encryption and key management. Example + * callbacks are provided by MBEDTLS_SSL_TICKET_C. + * + * Comment this macro to disable support for SSL session tickets + */ +#define MBEDTLS_SSL_SESSION_TICKETS + +/** + * \def MBEDTLS_SSL_SERVER_NAME_INDICATION + * + * Enable support for RFC 6066 server name indication (SNI) in SSL. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Comment this macro to disable support for server name indication in SSL + */ +#define MBEDTLS_SSL_SERVER_NAME_INDICATION + +/** + * \def MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + * + * When this option is enabled, the SSL buffer will be resized automatically + * based on the negotiated maximum fragment length in each direction. + * + * Requires: MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + */ +//#define MBEDTLS_SSL_VARIABLE_BUFFER_LENGTH + +/** + * \def MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + * + * Enable testing of the constant-flow nature of some sensitive functions with + * clang's MemorySanitizer. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires compiling with clang -fsanitize=memory. The test + * suites can then be run normally. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN + +/** + * \def MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + * + * Enable testing of the constant-flow nature of some sensitive functions with + * valgrind's memcheck tool. This causes some existing tests to also test + * this non-functional property of the code under test. + * + * This setting requires valgrind headers for building, and is only useful for + * testing if the tests suites are run with valgrind's memcheck. This can be + * done for an individual test suite with 'valgrind ./test_suite_xxx', or when + * using CMake, this can be done for all test suites with 'make memcheck'. + * + * \warning This macro is only used for extended testing; it is not considered + * part of the library's API, so it may change or disappear at any time. + * + * Uncomment to enable testing of the constant-flow nature of selected code. + */ +//#define MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND + +/** + * \def MBEDTLS_TEST_HOOKS + * + * Enable features for invasive testing such as introspection functions and + * hooks for fault injection. This enables additional unit tests. + * + * Merely enabling this feature should not change the behavior of the product. + * It only adds new code, and new branching points where the default behavior + * is the same as when this feature is disabled. + * However, this feature increases the attack surface: there is an added + * risk of vulnerabilities, and more gadgets that can make exploits easier. + * Therefore this feature must never be enabled in production. + * + * See `docs/architecture/testing/mbed-crypto-invasive-testing.md` for more + * information. + * + * Uncomment to enable invasive tests. + */ +//#define MBEDTLS_TEST_HOOKS + +/** + * \def MBEDTLS_THREADING_ALT + * + * Provide your own alternate threading implementation. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to allow your own alternate threading implementation. + */ +//#define MBEDTLS_THREADING_ALT + +/** + * \def MBEDTLS_THREADING_PTHREAD + * + * Enable the pthread wrapper layer for the threading layer. + * + * Requires: MBEDTLS_THREADING_C + * + * Uncomment this to enable pthread mutexes. + */ +#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_USE_PSA_CRYPTO + * + * Make the X.509 and TLS libraries use PSA for cryptographic operations as + * much as possible, and enable new APIs for using keys handled by PSA Crypto. + * + * \note Development of this option is currently in progress, and parts of Mbed + * TLS's X.509 and TLS modules are not ported to PSA yet. However, these parts + * will still continue to work as usual, so enabling this option should not + * break backwards compatibility. + * + * \warning If you enable this option, you need to call `psa_crypto_init()` + * before calling any function from the SSL/TLS, X.509 or PK modules, except + * for the various mbedtls_xxx_init() functions which can be called at any time. + * + * \note An important and desirable effect of this option is that it allows + * PK, X.509 and TLS to take advantage of PSA drivers. For example, enabling + * this option is what allows use of drivers for ECDSA, ECDH and EC J-PAKE in + * those modules. However, note that even with this option disabled, some code + * in PK, X.509, TLS or the crypto library might still use PSA drivers, if it + * can determine it's safe to do so; currently that's the case for hashes. + * + * \note See docs/use-psa-crypto.md for a complete description this option. + * + * Requires: MBEDTLS_PSA_CRYPTO_C. + * + * Uncomment this to enable internal use of PSA Crypto and new associated APIs. + */ +#define MBEDTLS_USE_PSA_CRYPTO + +/** + * \def MBEDTLS_PSA_CRYPTO_CONFIG + * + * This setting allows support for cryptographic mechanisms through the PSA + * API to be configured separately from support through the mbedtls API. + * + * When this option is disabled, the PSA API exposes the cryptographic + * mechanisms that can be implemented on top of the `mbedtls_xxx` API + * configured with `MBEDTLS_XXX` symbols. + * + * When this option is enabled, the PSA API exposes the cryptographic + * mechanisms requested by the `PSA_WANT_XXX` symbols defined in + * include/psa/crypto_config.h. The corresponding `MBEDTLS_XXX` settings are + * automatically enabled if required (i.e. if no PSA driver provides the + * mechanism). You may still freely enable additional `MBEDTLS_XXX` symbols + * in mbedtls_config.h. + * + * If the symbol #MBEDTLS_PSA_CRYPTO_CONFIG_FILE is defined, it specifies + * an alternative header to include instead of include/psa/crypto_config.h. + * + * \warning This option is experimental, in that the set of `PSA_WANT_XXX` + * symbols is not completely finalized yet, and the configuration + * tooling is not ideally adapted to having two separate configuration + * files. + * Future minor releases of Mbed TLS may make minor changes to those + * symbols, but we will endeavor to provide a transition path. + * Nonetheless, this option is considered mature enough to use in + * production, as long as you accept that you may need to make + * minor changes to psa/crypto_config.h when upgrading Mbed TLS. + */ +//#define MBEDTLS_PSA_CRYPTO_CONFIG + +/** + * \def MBEDTLS_VERSION_FEATURES + * + * Allow run-time checking of compile-time enabled features. Thus allowing users + * to check at run-time if the library is for instance compiled with threading + * support via mbedtls_version_check_feature(). + * + * Requires: MBEDTLS_VERSION_C + * + * Comment this to disable run-time checking and save ROM space + */ +#define MBEDTLS_VERSION_FEATURES + +/** + * \def MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK + * + * If set, this enables the X.509 API `mbedtls_x509_crt_verify_with_ca_cb()` + * and the SSL API `mbedtls_ssl_conf_ca_cb()` which allow users to configure + * the set of trusted certificates through a callback instead of a linked + * list. + * + * This is useful for example in environments where a large number of trusted + * certificates is present and storing them in a linked list isn't efficient + * enough, or when the set of trusted certificates changes frequently. + * + * See the documentation of `mbedtls_x509_crt_verify_with_ca_cb()` and + * `mbedtls_ssl_conf_ca_cb()` for more information. + * + * Requires: MBEDTLS_X509_CRT_PARSE_C + * + * Uncomment to enable trusted certificate callbacks. + */ +//#define MBEDTLS_X509_TRUSTED_CERTIFICATE_CALLBACK + +/** + * \def MBEDTLS_X509_REMOVE_INFO + * + * Disable mbedtls_x509_*_info() and related APIs. + * + * Uncomment to omit mbedtls_x509_*_info(), as well as mbedtls_debug_print_crt() + * and other functions/constants only used by these functions, thus reducing + * the code footprint by several KB. + */ +//#define MBEDTLS_X509_REMOVE_INFO + +/** + * \def MBEDTLS_X509_RSASSA_PSS_SUPPORT + * + * Enable parsing and verification of X.509 certificates, CRLs and CSRS + * signed with RSASSA-PSS (aka PKCS#1 v2.1). + * + * Requires: MBEDTLS_PKCS1_V21 + * + * Comment this macro to disallow using RSASSA-PSS in certificates. + */ +#define MBEDTLS_X509_RSASSA_PSS_SUPPORT +/** \} name SECTION: Mbed TLS feature support */ + +/** + * \name SECTION: Mbed TLS modules + * + * This section enables or disables entire modules in Mbed TLS + * \{ + */ + +/** + * \def MBEDTLS_AESNI_C + * + * Enable AES-NI support on x86-64 or x86-32. + * + * \note AESNI is only supported with certain compilers and target options: + * - Visual Studio: supported + * - GCC, x86-64, target not explicitly supporting AESNI: + * requires MBEDTLS_HAVE_ASM. + * - GCC, x86-32, target not explicitly supporting AESNI: + * not supported. + * - GCC, x86-64 or x86-32, target supporting AESNI: supported. + * For this assembly-less implementation, you must currently compile + * `library/aesni.c` and `library/aes.c` with machine options to enable + * SSE2 and AESNI instructions: `gcc -msse2 -maes -mpclmul` or + * `clang -maes -mpclmul`. + * - Non-x86 targets: this option is silently ignored. + * - Other compilers: this option is silently ignored. + * + * \note + * Above, "GCC" includes compatible compilers such as Clang. + * The limitations on target support are likely to be relaxed in the future. + * + * Module: library/aesni.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM (on some platforms, see note) + * + * This modules adds support for the AES-NI instructions on x86. + */ +// #define MBEDTLS_AESNI_C + +/** + * \def MBEDTLS_AESCE_C + * + * Enable AES cryptographic extension support on Armv8. + * + * Module: library/aesce.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_AES_C + * + * \warning Runtime detection only works on Linux. For non-Linux operating + * system, Armv8-A Cryptographic Extensions must be supported by + * the CPU when this option is enabled. + * + * \note Minimum compiler versions for this feature when targeting aarch64 + * are Clang 4.0; armclang 6.6; GCC 6.0; or MSVC 2019 version 16.11.2. + * Minimum compiler versions for this feature when targeting 32-bit + * Arm or Thumb are Clang 11.0; armclang 6.20; or GCC 6.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for + * armclang <= 6.9 + * + * This module adds support for the AES Armv8-A Cryptographic Extensions on Armv8 systems. + */ +#define MBEDTLS_AESCE_C + +/** + * \def MBEDTLS_AES_C + * + * Enable the AES block cipher. + * + * Module: library/aes.c + * Caller: library/cipher.c + * library/pem.c + * library/ctr_drbg.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_AES_128_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_AES_256_CBC_SHA + * MBEDTLS_TLS_PSK_WITH_AES_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA + * + * PEM_PARSE uses AES for decrypting encrypted keys. + */ +#define MBEDTLS_AES_C + +/** + * \def MBEDTLS_ASN1_PARSE_C + * + * Enable the generic ASN1 parser. + * + * Module: library/asn1.c + * Caller: library/x509.c + * library/dhm.c + * library/pkcs12.c + * library/pkcs5.c + * library/pkparse.c + */ +#define MBEDTLS_ASN1_PARSE_C + +/** + * \def MBEDTLS_ASN1_WRITE_C + * + * Enable the generic ASN1 writer. + * + * Module: library/asn1write.c + * Caller: library/ecdsa.c + * library/pkwrite.c + * library/x509_create.c + * library/x509write_crt.c + * library/x509write_csr.c + */ +#define MBEDTLS_ASN1_WRITE_C + +/** + * \def MBEDTLS_BASE64_C + * + * Enable the Base64 module. + * + * Module: library/base64.c + * Caller: library/pem.c + * + * This module is required for PEM support (required by X.509). + */ +#define MBEDTLS_BASE64_C + +/** + * \def MBEDTLS_BLOCK_CIPHER_NO_DECRYPT + * + * Remove decryption operation for AES, ARIA and Camellia block cipher. + * + * \note This feature is incompatible with insecure block cipher, + * MBEDTLS_DES_C, and cipher modes which always require decryption + * operation, MBEDTLS_CIPHER_MODE_CBC, MBEDTLS_CIPHER_MODE_XTS and + * MBEDTLS_NIST_KW_C. When #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, + * this feature is incompatible with following supported PSA equivalence, + * PSA_WANT_ALG_ECB_NO_PADDING, PSA_WANT_ALG_CBC_NO_PADDING, + * PSA_WANT_ALG_CBC_PKCS7 and PSA_WANT_KEY_TYPE_DES. + * + * Module: library/aes.c + * library/aesce.c + * library/aesni.c + * library/aria.c + * library/camellia.c + * library/cipher.c + */ +//#define MBEDTLS_BLOCK_CIPHER_NO_DECRYPT + +/** + * \def MBEDTLS_BIGNUM_C + * + * Enable the multi-precision integer library. + * + * Module: library/bignum.c + * library/bignum_core.c + * library/bignum_mod.c + * library/bignum_mod_raw.c + * Caller: library/dhm.c + * library/ecp.c + * library/ecdsa.c + * library/rsa.c + * library/rsa_alt_helpers.c + * library/ssl_tls.c + * + * This module is required for RSA, DHM and ECC (ECDH, ECDSA) support. + */ +#define MBEDTLS_BIGNUM_C + +/** + * \def MBEDTLS_CAMELLIA_C + * + * Enable the Camellia block cipher. + * + * Module: library/camellia.c + * Caller: library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_256_CBC_SHA + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_CAMELLIA_128_CBC_SHA + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 + */ +// #define MBEDTLS_CAMELLIA_C + +/** + * \def MBEDTLS_ARIA_C + * + * Enable the ARIA block cipher. + * + * Module: library/aria.c + * Caller: library/cipher.c + * + * This module enables the following ciphersuites (if other requisites are + * enabled as well): + * + * MBEDTLS_TLS_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 + * MBEDTLS_TLS_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 + * MBEDTLS_TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 + * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 + * MBEDTLS_TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 + */ +// #define MBEDTLS_ARIA_C + +/** + * \def MBEDTLS_CCM_C + * + * Enable the Counter with CBC-MAC (CCM) mode for 128-bit block cipher. + * + * Module: library/ccm.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * MBEDTLS_ARIA_C + * + * This module enables the AES-CCM ciphersuites, if other requisites are + * enabled as well. + */ +#define MBEDTLS_CCM_C + +/** + * \def MBEDTLS_CHACHA20_C + * + * Enable the ChaCha20 stream cipher. + * + * Module: library/chacha20.c + */ +#define MBEDTLS_CHACHA20_C + +/** + * \def MBEDTLS_CHACHAPOLY_C + * + * Enable the ChaCha20-Poly1305 AEAD algorithm. + * + * Module: library/chachapoly.c + * + * This module requires: MBEDTLS_CHACHA20_C, MBEDTLS_POLY1305_C + */ +#define MBEDTLS_CHACHAPOLY_C + +/** + * \def MBEDTLS_CIPHER_C + * + * Enable the generic cipher layer. + * + * Module: library/cipher.c + * Caller: library/ccm.c + * library/cmac.c + * library/gcm.c + * library/nist_kw.c + * library/pkcs12.c + * library/pkcs5.c + * library/psa_crypto_aead.c + * library/psa_crypto_mac.c + * library/ssl_ciphersuites.c + * library/ssl_msg.c + * library/ssl_ticket.c (unless MBEDTLS_USE_PSA_CRYPTO is enabled) + * Auto-enabled by: MBEDTLS_PSA_CRYPTO_C depending on which ciphers are enabled + * (see the documentation of that option for details). + * + * Uncomment to enable generic cipher wrappers. + */ +#define MBEDTLS_CIPHER_C + +/** + * \def MBEDTLS_CMAC_C + * + * Enable the CMAC (Cipher-based Message Authentication Code) mode for block + * ciphers. + * + * \note When #MBEDTLS_CMAC_ALT is active, meaning that the underlying + * implementation of the CMAC algorithm is provided by an alternate + * implementation, that alternate implementation may opt to not support + * AES-192 or 3DES as underlying block ciphers for the CMAC operation. + * + * Module: library/cmac.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_DES_C + * + */ +#define MBEDTLS_CMAC_C + +/** + * \def MBEDTLS_CTR_DRBG_C + * + * Enable the CTR_DRBG AES-based random generator. + * The CTR_DRBG generator uses AES-256 by default. + * To use AES-128 instead, enable \c MBEDTLS_CTR_DRBG_USE_128_BIT_KEY above. + * + * AES support can either be achived through builtin (MBEDTLS_AES_C) or PSA. + * Builtin is the default option when MBEDTLS_AES_C is defined otherwise PSA + * is used. + * + * \warning When using PSA, the user should call `psa_crypto_init()` before + * using any CTR_DRBG operation (except `mbedtls_ctr_drbg_init()`). + * + * \note AES-128 will be used if \c MBEDTLS_AES_ONLY_128_BIT_KEY_LENGTH is set. + * + * \note To achieve a 256-bit security strength with CTR_DRBG, + * you must use AES-256 *and* use sufficient entropy. + * See ctr_drbg.h for more details. + * + * Module: library/ctr_drbg.c + * Caller: + * + * Requires: MBEDTLS_AES_C or + * (PSA_WANT_KEY_TYPE_AES and PSA_WANT_ALG_ECB_NO_PADDING and + * MBEDTLS_PSA_CRYPTO_C) + * + * This module provides the CTR_DRBG AES random number generator. + */ +#define MBEDTLS_CTR_DRBG_C + +/** + * \def MBEDTLS_DEBUG_C + * + * Enable the debug functions. + * + * Module: library/debug.c + * Caller: library/ssl_msg.c + * library/ssl_tls.c + * library/ssl_tls12_*.c + * library/ssl_tls13_*.c + * + * This module provides debugging functions. + */ +#define MBEDTLS_DEBUG_C + +/** + * \def MBEDTLS_DES_C + * + * Enable the DES block cipher. + * + * Module: library/des.c + * Caller: library/pem.c + * library/cipher.c + * + * PEM_PARSE uses DES/3DES for decrypting encrypted keys. + * + * \warning DES/3DES are considered weak ciphers and their use constitutes a + * security risk. We recommend considering stronger ciphers instead. + */ +// #define MBEDTLS_DES_C + +/** + * \def MBEDTLS_DHM_C + * + * Enable the Diffie-Hellman-Merkle module. + * + * Module: library/dhm.c + * Caller: library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module is used by the following key exchanges: + * DHE-RSA, DHE-PSK + * + * \warning Using DHE constitutes a security risk as it + * is not possible to validate custom DH parameters. + * If possible, it is recommended users should consider + * preferring other methods of key exchange. + * See dhm.h for more details. + * + */ +// #define MBEDTLS_DHM_C + +/** + * \def MBEDTLS_ECDH_C + * + * Enable the elliptic curve Diffie-Hellman library. + * + * Module: library/ecdh.c + * Caller: library/psa_crypto.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA, ECDHE-RSA, DHE-PSK + * + * Requires: MBEDTLS_ECP_C + */ +#define MBEDTLS_ECDH_C + +/** + * \def MBEDTLS_ECDSA_C + * + * Enable the elliptic curve DSA library. + * + * Module: library/ecdsa.c + * Caller: + * + * This module is used by the following key exchanges: + * ECDHE-ECDSA + * + * Requires: MBEDTLS_ECP_C, MBEDTLS_ASN1_WRITE_C, MBEDTLS_ASN1_PARSE_C, + * and at least one MBEDTLS_ECP_DP_XXX_ENABLED for a + * short Weierstrass curve. + */ +#define MBEDTLS_ECDSA_C + +/** + * \def MBEDTLS_ECJPAKE_C + * + * Enable the elliptic curve J-PAKE library. + * + * \note EC J-PAKE support is based on the Thread v1.0.0 specification. + * It has not been reviewed for compliance with newer standards such as + * Thread v1.1 or RFC 8236. + * + * Module: library/ecjpake.c + * Caller: + * + * This module is used by the following key exchanges: + * ECJPAKE + * + * Requires: MBEDTLS_ECP_C and either MBEDTLS_MD_C or MBEDTLS_PSA_CRYPTO_C + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any EC J-PAKE operations. + */ +// #define MBEDTLS_ECJPAKE_C + +/** + * \def MBEDTLS_ECP_C + * + * Enable the elliptic curve over GF(p) library. + * + * Module: library/ecp.c + * Caller: library/ecdh.c + * library/ecdsa.c + * library/ecjpake.c + * + * Requires: MBEDTLS_BIGNUM_C and at least one MBEDTLS_ECP_DP_XXX_ENABLED + */ +#define MBEDTLS_ECP_C + +/** + * \def MBEDTLS_ENTROPY_C + * + * Enable the platform-specific entropy code. + * + * Module: library/entropy.c + * Caller: + * + * Requires: MBEDTLS_SHA512_C or MBEDTLS_SHA256_C + * + * This module provides a generic entropy pool + */ +#define MBEDTLS_ENTROPY_C + +/** + * \def MBEDTLS_ERROR_C + * + * Enable error code to error string conversion. + * + * Module: library/error.c + * Caller: + * + * This module enables mbedtls_strerror(). + */ +#define MBEDTLS_ERROR_C + +/** + * \def MBEDTLS_GCM_C + * + * Enable the Galois/Counter Mode (GCM). + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_AES_C or MBEDTLS_CAMELLIA_C or + * MBEDTLS_ARIA_C + * + * This module enables the AES-GCM and CAMELLIA-GCM ciphersuites, if other + * requisites are enabled as well. + */ +#define MBEDTLS_GCM_C + +/** + * \def MBEDTLS_GCM_LARGE_TABLE + * + * Enable large pre-computed tables for Galois/Counter Mode (GCM). + * Can significantly increase throughput on systems without GCM hardware + * acceleration (e.g., AESNI, AESCE). + * + * The mbedtls_gcm_context size will increase by 3840 bytes. + * The code size will increase by roughly 344 bytes. + * + * Module: library/gcm.c + * + * Requires: MBEDTLS_GCM_C + */ +//#define MBEDTLS_GCM_LARGE_TABLE + +/** + * \def MBEDTLS_HKDF_C + * + * Enable the HKDF algorithm (RFC 5869). + * + * Module: library/hkdf.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * This module adds support for the Hashed Message Authentication Code + * (HMAC)-based key derivation function (HKDF). + */ +#define MBEDTLS_HKDF_C + +/** + * \def MBEDTLS_HMAC_DRBG_C + * + * Enable the HMAC_DRBG random generator. + * + * Module: library/hmac_drbg.c + * Caller: + * + * Requires: MBEDTLS_MD_C + * + * Uncomment to enable the HMAC_DRBG random number generator. + */ +#define MBEDTLS_HMAC_DRBG_C + +/** + * \def MBEDTLS_LMS_C + * + * Enable the LMS stateful-hash asymmetric signature algorithm. + * + * Module: library/lms.c + * Caller: + * + * Requires: MBEDTLS_PSA_CRYPTO_C + * + * Uncomment to enable the LMS verification algorithm and public key operations. + */ +#define MBEDTLS_LMS_C + +/** + * \def MBEDTLS_LMS_PRIVATE + * + * Enable LMS private-key operations and signing code. Functions enabled by this + * option are experimental, and should not be used in production. + * + * Requires: MBEDTLS_LMS_C + * + * Uncomment to enable the LMS signature algorithm and private key operations. + */ +//#define MBEDTLS_LMS_PRIVATE + +/** + * \def MBEDTLS_NIST_KW_C + * + * Enable the Key Wrapping mode for 128-bit block ciphers, + * as defined in NIST SP 800-38F. Only KW and KWP modes + * are supported. At the moment, only AES is approved by NIST. + * + * Module: library/nist_kw.c + * + * Requires: MBEDTLS_AES_C and MBEDTLS_CIPHER_C + */ +#define MBEDTLS_NIST_KW_C + +/** + * \def MBEDTLS_MD_C + * + * Enable the generic layer for message digest (hashing) and HMAC. + * + * Requires: one of: MBEDTLS_MD5_C, MBEDTLS_RIPEMD160_C, MBEDTLS_SHA1_C, + * MBEDTLS_SHA224_C, MBEDTLS_SHA256_C, MBEDTLS_SHA384_C, + * MBEDTLS_SHA512_C, or MBEDTLS_PSA_CRYPTO_C with at least + * one hash. + * Module: library/md.c + * Caller: library/constant_time.c + * library/ecdsa.c + * library/ecjpake.c + * library/hkdf.c + * library/hmac_drbg.c + * library/pk.c + * library/pkcs5.c + * library/pkcs12.c + * library/psa_crypto_ecp.c + * library/psa_crypto_rsa.c + * library/rsa.c + * library/ssl_cookie.c + * library/ssl_msg.c + * library/ssl_tls.c + * library/x509.c + * library/x509_crt.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Uncomment to enable generic message digest wrappers. + */ +#define MBEDTLS_MD_C + +/** + * \def MBEDTLS_MD5_C + * + * Enable the MD5 hash algorithm. + * + * Module: library/md5.c + * Caller: library/md.c + * library/pem.c + * library/ssl_tls.c + * + * This module is required for TLS 1.2 depending on the handshake parameters. + * Further, it is used for checking MD5-signed certificates, and for PBKDF1 + * when decrypting PEM-encoded encrypted keys. + * + * \warning MD5 is considered a weak message digest and its use constitutes a + * security risk. If possible, we recommend avoiding dependencies on + * it, and considering stronger message digests instead. + * + */ +#define MBEDTLS_MD5_C + +/** + * \def MBEDTLS_MEMORY_BUFFER_ALLOC_C + * + * Enable the buffer allocator implementation that makes use of a (stack) + * based buffer to 'allocate' dynamic memory. (replaces calloc() and free() + * calls) + * + * Module: library/memory_buffer_alloc.c + * + * Requires: MBEDTLS_PLATFORM_C + * MBEDTLS_PLATFORM_MEMORY (to use it within Mbed TLS) + * + * Enable this module to enable the buffer memory allocator. + */ +//#define MBEDTLS_MEMORY_BUFFER_ALLOC_C + +/** + * \def MBEDTLS_NET_C + * + * Enable the TCP and UDP over IPv6/IPv4 networking routines. + * + * \note This module only works on POSIX/Unix (including Linux, BSD and OS X) + * and Windows. For other platforms, you'll want to disable it, and write your + * own networking callbacks to be passed to \c mbedtls_ssl_set_bio(). + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/net_sockets.c + * + * This module provides networking routines. + */ +#define MBEDTLS_NET_C + +/** + * \def MBEDTLS_OID_C + * + * Enable the OID database. + * + * Module: library/oid.c + * Caller: library/asn1write.c + * library/pkcs5.c + * library/pkparse.c + * library/pkwrite.c + * library/rsa.c + * library/x509.c + * library/x509_create.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * This modules translates between OIDs and internal values. + */ +#define MBEDTLS_OID_C + +/** + * \def MBEDTLS_PADLOCK_C + * + * Enable VIA Padlock support on x86. + * + * Module: library/padlock.c + * Caller: library/aes.c + * + * Requires: MBEDTLS_HAVE_ASM + * + * This modules adds support for the VIA PadLock on x86. + */ +// #define MBEDTLS_PADLOCK_C + +/** + * \def MBEDTLS_PEM_PARSE_C + * + * Enable PEM decoding / parsing. + * + * Module: library/pem.c + * Caller: library/dhm.c + * library/pkparse.c + * library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_BASE64_C + * optionally MBEDTLS_MD5_C, or PSA Crypto with MD5 (see below) + * + * \warning When parsing password-protected files, if MD5 is provided only by + * a PSA driver, you must call psa_crypto_init() before the first file. + * + * This modules adds support for decoding / parsing PEM files. + */ +#define MBEDTLS_PEM_PARSE_C + +/** + * \def MBEDTLS_PEM_WRITE_C + * + * Enable PEM encoding / writing. + * + * Module: library/pem.c + * Caller: library/pkwrite.c + * library/x509write_crt.c + * library/x509write_csr.c + * + * Requires: MBEDTLS_BASE64_C + * + * This modules adds support for encoding / writing PEM files. + */ +#define MBEDTLS_PEM_WRITE_C + +/** + * \def MBEDTLS_PK_C + * + * Enable the generic public (asymmetric) key layer. + * + * Module: library/pk.c + * Caller: library/psa_crypto_rsa.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * library/x509.c + * + * Requires: MBEDTLS_MD_C, MBEDTLS_RSA_C or MBEDTLS_ECP_C + * + * Uncomment to enable generic public key wrappers. + */ +#define MBEDTLS_PK_C + +/** + * \def MBEDTLS_PK_PARSE_C + * + * Enable the generic public (asymmetric) key parser. + * + * Module: library/pkparse.c + * Caller: library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_C + * + * Uncomment to enable generic public key parse functions. + */ +#define MBEDTLS_PK_PARSE_C + +/** + * \def MBEDTLS_PK_WRITE_C + * + * Enable the generic public (asymmetric) key writer. + * + * Module: library/pkwrite.c + * Caller: library/x509write.c + * + * Requires: MBEDTLS_ASN1_WRITE_C, MBEDTLS_OID_C, MBEDTLS_PK_C + * + * Uncomment to enable generic public key write functions. + */ +#define MBEDTLS_PK_WRITE_C + +/** + * \def MBEDTLS_PKCS5_C + * + * Enable PKCS#5 functions. + * + * Module: library/pkcs5.c + * + * Auto-enables: MBEDTLS_MD_C + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any PKCS5 operations. + * + * This module adds support for the PKCS#5 functions. + */ +#define MBEDTLS_PKCS5_C + +/** + * \def MBEDTLS_PKCS7_C + * + * Enable PKCS #7 core for using PKCS #7-formatted signatures. + * RFC Link - https://tools.ietf.org/html/rfc2315 + * + * Module: library/pkcs7.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, + * MBEDTLS_X509_CRT_PARSE_C MBEDTLS_X509_CRL_PARSE_C, + * MBEDTLS_BIGNUM_C, MBEDTLS_MD_C + * + * This module is required for the PKCS #7 parsing modules. + */ +#define MBEDTLS_PKCS7_C + +/** + * \def MBEDTLS_PKCS12_C + * + * Enable PKCS#12 PBE functions. + * Adds algorithms for parsing PKCS#8 encrypted private keys + * + * Module: library/pkcs12.c + * Caller: library/pkparse.c + * + * Requires: MBEDTLS_ASN1_PARSE_C and either MBEDTLS_MD_C or + * MBEDTLS_PSA_CRYPTO_C. + * + * \warning If using a hash that is only provided by PSA drivers, you must + * call psa_crypto_init() before doing any PKCS12 operations. + * + * This module enables PKCS#12 functions. + */ +#define MBEDTLS_PKCS12_C + +/** + * \def MBEDTLS_PLATFORM_C + * + * Enable the platform abstraction layer that allows you to re-assign + * functions like calloc(), free(), snprintf(), printf(), fprintf(), exit(). + * + * Enabling MBEDTLS_PLATFORM_C enables to use of MBEDTLS_PLATFORM_XXX_ALT + * or MBEDTLS_PLATFORM_XXX_MACRO directives, allowing the functions mentioned + * above to be specified at runtime or compile time respectively. + * + * \note This abstraction layer must be enabled on Windows (including MSYS2) + * as other modules rely on it for a fixed snprintf implementation. + * + * Module: library/platform.c + * Caller: Most other .c files + * + * This module enables abstraction of common (libc) functions. + */ +#define MBEDTLS_PLATFORM_C + +/** + * \def MBEDTLS_POLY1305_C + * + * Enable the Poly1305 MAC algorithm. + * + * Module: library/poly1305.c + * Caller: library/chachapoly.c + */ +#define MBEDTLS_POLY1305_C + +/** + * \def MBEDTLS_PSA_CRYPTO_C + * + * Enable the Platform Security Architecture cryptography API. + * + * Module: library/psa_crypto.c + * + * Requires: either MBEDTLS_CTR_DRBG_C and MBEDTLS_ENTROPY_C, + * or MBEDTLS_HMAC_DRBG_C and MBEDTLS_ENTROPY_C, + * or MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG. + * Auto-enables: MBEDTLS_CIPHER_C if any unauthenticated (ie, non-AEAD) cipher + * is enabled in PSA (unless it's fully accelerated, see + * docs/driver-only-builds.md about that). + */ +#define MBEDTLS_PSA_CRYPTO_C + +/** + * \def MBEDTLS_PSA_CRYPTO_SE_C + * + * Enable dynamic secure element support in the Platform Security Architecture + * cryptography API. + * + * \deprecated This feature is deprecated. Please switch to the PSA driver + * interface. + * + * \warning This feature is not thread-safe, and should not be used in a + * multi-threaded environment. + * + * Module: library/psa_crypto_se.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, MBEDTLS_PSA_CRYPTO_STORAGE_C + * + */ +//#define MBEDTLS_PSA_CRYPTO_SE_C + +/** + * \def MBEDTLS_PSA_CRYPTO_STORAGE_C + * + * Enable the Platform Security Architecture persistent key storage. + * + * Module: library/psa_crypto_storage.c + * + * Requires: MBEDTLS_PSA_CRYPTO_C, + * either MBEDTLS_PSA_ITS_FILE_C or a native implementation of + * the PSA ITS interface + */ +#define MBEDTLS_PSA_CRYPTO_STORAGE_C + +/** + * \def MBEDTLS_PSA_ITS_FILE_C + * + * Enable the emulation of the Platform Security Architecture + * Internal Trusted Storage (PSA ITS) over files. + * + * Module: library/psa_its_file.c + * + * Requires: MBEDTLS_FS_IO + */ +#define MBEDTLS_PSA_ITS_FILE_C + +/** + * \def MBEDTLS_RIPEMD160_C + * + * Enable the RIPEMD-160 hash algorithm. + * + * Module: library/ripemd160.c + * Caller: library/md.c + * + */ +#define MBEDTLS_RIPEMD160_C + +/** + * \def MBEDTLS_RSA_C + * + * Enable the RSA public-key cryptosystem. + * + * Module: library/rsa.c + * library/rsa_alt_helpers.c + * Caller: library/pk.c + * library/psa_crypto.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module is used by the following key exchanges: + * RSA, DHE-RSA, ECDHE-RSA, RSA-PSK + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C + */ +#define MBEDTLS_RSA_C + +/** + * \def MBEDTLS_SHA1_C + * + * Enable the SHA1 cryptographic hash algorithm. + * + * Module: library/sha1.c + * Caller: library/md.c + * library/psa_crypto_hash.c + * + * This module is required for TLS 1.2 depending on the handshake parameters, + * and for SHA1-signed certificates. + * + * \warning SHA-1 is considered a weak message digest and its use constitutes + * a security risk. If possible, we recommend avoiding dependencies + * on it, and considering stronger message digests instead. + * + */ +#define MBEDTLS_SHA1_C + +/** + * \def MBEDTLS_SHA224_C + * + * Enable the SHA-224 cryptographic hash algorithm. + * + * Module: library/sha256.c + * Caller: library/md.c + * library/ssl_cookie.c + * + * This module adds support for SHA-224. + */ +#define MBEDTLS_SHA224_C + +/** + * \def MBEDTLS_SHA256_C + * + * Enable the SHA-256 cryptographic hash algorithm. + * + * Module: library/sha256.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * This module adds support for SHA-256. + * This module is required for the SSL/TLS 1.2 PRF function. + */ +#define MBEDTLS_SHA256_C + +/** + * \def MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT + * + * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions if they are available at runtime. + * If not, the library will fall back to the C implementation. + * + * \note If MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT is defined when building + * for a non-Armv8-A build it will be silently ignored. + * + * \note Minimum compiler versions for this feature are Clang 4.0, + * armclang 6.6 or GCC 6.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for + * armclang <= 6.9 + * + * \note This was previously known as MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT. + * That name is deprecated, but may still be used as an alternative form for this + * option. + * + * \warning MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT cannot be defined at the + * same time as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY. + * + * Requires: MBEDTLS_SHA256_C. + * + * Module: library/sha256.c + * + * Uncomment to have the library check for the Armv8-A SHA-256 crypto extensions + * and use them if available. + */ +#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT + +/** + * \def MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + * + * \deprecated This is now known as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT. + * This name is now deprecated, but may still be used as an alternative form for + * this option. + */ +#define MBEDTLS_SHA256_USE_A64_CRYPTO_IF_PRESENT + +/** + * \def MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY + * + * Enable acceleration of the SHA-256 and SHA-224 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions, which must be available at runtime + * or else an illegal instruction fault will occur. + * + * \note This allows builds with a smaller code size than with + * MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT + * + * \note Minimum compiler versions for this feature are Clang 4.0, + * armclang 6.6 or GCC 6.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8-a+crypto for + * armclang <= 6.9 + * + * \note This was previously known as MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY. + * That name is deprecated, but may still be used as an alternative form for this + * option. + * + * \warning MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY cannot be defined at the same + * time as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_IF_PRESENT. + * + * Requires: MBEDTLS_SHA256_C. + * + * Module: library/sha256.c + * + * Uncomment to have the library use the Armv8-A SHA-256 crypto extensions + * unconditionally. + */ +//#define MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY + +/** + * \def MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + * + * \deprecated This is now known as MBEDTLS_SHA256_USE_ARMV8_A_CRYPTO_ONLY. + * This name is now deprecated, but may still be used as an alternative form for + * this option. + */ +//#define MBEDTLS_SHA256_USE_A64_CRYPTO_ONLY + +/** + * \def MBEDTLS_SHA384_C + * + * Enable the SHA-384 cryptographic hash algorithm. + * + * Module: library/sha512.c + * Caller: library/md.c + * library/psa_crypto_hash.c + * library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * Comment to disable SHA-384 + */ +#define MBEDTLS_SHA384_C + +/** + * \def MBEDTLS_SHA512_C + * + * Enable SHA-512 cryptographic hash algorithms. + * + * Module: library/sha512.c + * Caller: library/entropy.c + * library/md.c + * library/ssl_tls.c + * library/ssl_cookie.c + * + * This module adds support for SHA-512. + */ +#define MBEDTLS_SHA512_C + +/** + * \def MBEDTLS_SHA3_C + * + * Enable the SHA3 cryptographic hash algorithm. + * + * Module: library/sha3.c + * + * This module adds support for SHA3. + */ +#define MBEDTLS_SHA3_C + +/** + * \def MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + * + * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions if they are available at runtime. + * If not, the library will fall back to the C implementation. + * + * \note If MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT is defined when building + * for a non-Aarch64 build it will be silently ignored. + * + * \note Minimum compiler versions for this feature are Clang 7.0, + * armclang 6.9 or GCC 8.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for + * armclang 6.9 + * + * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT cannot be defined at the + * same time as MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY. + * + * Requires: MBEDTLS_SHA512_C. + * + * Module: library/sha512.c + * + * Uncomment to have the library check for the A64 SHA-512 crypto extensions + * and use them if available. + */ +#define MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + +/** + * \def MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY + * + * Enable acceleration of the SHA-512 and SHA-384 cryptographic hash algorithms + * with the ARMv8 cryptographic extensions, which must be available at runtime + * or else an illegal instruction fault will occur. + * + * \note This allows builds with a smaller code size than with + * MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT + * + * \note Minimum compiler versions for this feature are Clang 7.0, + * armclang 6.9 or GCC 8.0. + * + * \note \c CFLAGS must be set to a minimum of \c -march=armv8.2-a+sha3 for + * armclang 6.9 + * + * \warning MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY cannot be defined at the same + * time as MBEDTLS_SHA512_USE_A64_CRYPTO_IF_PRESENT. + * + * Requires: MBEDTLS_SHA512_C. + * + * Module: library/sha512.c + * + * Uncomment to have the library use the A64 SHA-512 crypto extensions + * unconditionally. + */ +// #define MBEDTLS_SHA512_USE_A64_CRYPTO_ONLY + +/** + * \def MBEDTLS_SSL_CACHE_C + * + * Enable simple SSL cache implementation. + * + * Module: library/ssl_cache.c + * Caller: + * + * Requires: MBEDTLS_SSL_CACHE_C + */ +#define MBEDTLS_SSL_CACHE_C + +/** + * \def MBEDTLS_SSL_COOKIE_C + * + * Enable basic implementation of DTLS cookies for hello verification. + * + * Module: library/ssl_cookie.c + * Caller: + */ +#define MBEDTLS_SSL_COOKIE_C + +/** + * \def MBEDTLS_SSL_TICKET_C + * + * Enable an implementation of TLS server-side callbacks for session tickets. + * + * Module: library/ssl_ticket.c + * Caller: + * + * Requires: (MBEDTLS_CIPHER_C || MBEDTLS_USE_PSA_CRYPTO) && + * (MBEDTLS_GCM_C || MBEDTLS_CCM_C || MBEDTLS_CHACHAPOLY_C) + */ +#define MBEDTLS_SSL_TICKET_C + +/** + * \def MBEDTLS_SSL_CLI_C + * + * Enable the SSL/TLS client code. + * + * Module: library/ssl*_client.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS client support. + */ #define MBEDTLS_SSL_CLI_C + +/** + * \def MBEDTLS_SSL_SRV_C + * + * Enable the SSL/TLS server code. + * + * Module: library/ssl*_server.c + * Caller: + * + * Requires: MBEDTLS_SSL_TLS_C + * + * This module is required for SSL/TLS server support. + */ +#define MBEDTLS_SSL_SRV_C + +/** + * \def MBEDTLS_SSL_TLS_C + * + * Enable the generic SSL/TLS code. + * + * Module: library/ssl_tls.c + * Caller: library/ssl*_client.c + * library/ssl*_server.c + * + * Requires: MBEDTLS_CIPHER_C, MBEDTLS_MD_C + * and at least one of the MBEDTLS_SSL_PROTO_XXX defines + * + * This module is required for SSL/TLS. + */ #define MBEDTLS_SSL_TLS_C -#define MBEDTLS_THREADING_PTHREAD + +/** + * \def MBEDTLS_THREADING_C + * + * Enable the threading abstraction layer. + * By default Mbed TLS assumes it is used in a non-threaded environment or that + * contexts are not shared between threads. If you do intend to use contexts + * between threads, you will need to enable this layer to prevent race + * conditions. See also our Knowledge Base article about threading: + * https://mbed-tls.readthedocs.io/en/latest/kb/development/thread-safety-and-multi-threading + * + * Module: library/threading.c + * + * This allows different threading implementations (self-implemented or + * provided). + * + * You will have to enable either MBEDTLS_THREADING_ALT or + * MBEDTLS_THREADING_PTHREAD. + * + * Enable this layer to allow use of mutexes within Mbed TLS + */ #define MBEDTLS_THREADING_C + +/** + * \def MBEDTLS_TIMING_C + * + * Enable the semi-portable timing interface. + * + * \note The provided implementation only works on POSIX/Unix (including Linux, + * BSD and OS X) and Windows. On other platforms, you can either disable that + * module and provide your own implementations of the callbacks needed by + * \c mbedtls_ssl_set_timer_cb() for DTLS, or leave it enabled and provide + * your own implementation of the whole module by setting + * \c MBEDTLS_TIMING_ALT in the current file. + * + * \note The timing module will include time.h on suitable platforms + * regardless of the setting of MBEDTLS_HAVE_TIME, unless + * MBEDTLS_TIMING_ALT is used. See timing.c for more information. + * + * \note See also our Knowledge Base article about porting to a new + * environment: + * https://mbed-tls.readthedocs.io/en/latest/kb/how-to/how-do-i-port-mbed-tls-to-a-new-environment-OS + * + * Module: library/timing.c + */ +#define MBEDTLS_TIMING_C + +/** + * \def MBEDTLS_VERSION_C + * + * Enable run-time version information. + * + * Module: library/version.c + * + * This module provides run-time version information. + */ +#define MBEDTLS_VERSION_C + +/** + * \def MBEDTLS_X509_USE_C + * + * Enable X.509 core for using certificates. + * + * Module: library/x509.c + * Caller: library/x509_crl.c + * library/x509_crt.c + * library/x509_csr.c + * + * Requires: MBEDTLS_ASN1_PARSE_C, MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, + * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) + * + * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call + * psa_crypto_init() before doing any X.509 operation. + * + * This module is required for the X.509 parsing modules. + */ #define MBEDTLS_X509_USE_C -#define MBEDTLS_X509_CREATE_C + +/** + * \def MBEDTLS_X509_CRT_PARSE_C + * + * Enable X.509 certificate parsing. + * + * Module: library/x509_crt.c + * Caller: library/ssl_tls.c + * library/ssl*_client.c + * library/ssl*_server.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 certificate parsing. + */ #define MBEDTLS_X509_CRT_PARSE_C + +/** + * \def MBEDTLS_X509_CRL_PARSE_C + * + * Enable X.509 CRL parsing. + * + * Module: library/x509_crl.c + * Caller: library/x509_crt.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is required for X.509 CRL parsing. + */ +#define MBEDTLS_X509_CRL_PARSE_C + +/** + * \def MBEDTLS_X509_CSR_PARSE_C + * + * Enable X.509 Certificate Signing Request (CSR) parsing. + * + * Module: library/x509_csr.c + * Caller: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_USE_C + * + * This module is used for reading X.509 certificate request. + */ +#define MBEDTLS_X509_CSR_PARSE_C + +/** + * \def MBEDTLS_X509_CREATE_C + * + * Enable X.509 core for creating certificates. + * + * Module: library/x509_create.c + * + * Requires: MBEDTLS_BIGNUM_C, MBEDTLS_OID_C, MBEDTLS_PK_PARSE_C, + * (MBEDTLS_MD_C or MBEDTLS_USE_PSA_CRYPTO) + * + * \warning If building with MBEDTLS_USE_PSA_CRYPTO, you must call + * psa_crypto_init() before doing any X.509 create operation. + * + * This module is the basis for creating X.509 certificates and CSRs. + */ +#define MBEDTLS_X509_CREATE_C + +/** + * \def MBEDTLS_X509_CRT_WRITE_C + * + * Enable creating X.509 certificates. + * + * Module: library/x509_crt_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate creation. + */ +#define MBEDTLS_X509_CRT_WRITE_C + +/** + * \def MBEDTLS_X509_CSR_WRITE_C + * + * Enable creating X.509 Certificate Signing Requests (CSR). + * + * Module: library/x509_csr_write.c + * + * Requires: MBEDTLS_X509_CREATE_C + * + * This module is required for X.509 certificate request writing. + */ #define MBEDTLS_X509_CSR_WRITE_C -#define MBEDTLS_NET_C -#define MBEDTLS_TIMING_C -#define MBEDTLS_ENTROPY_PLATFORM -#define MBEDTLS_FS_IO -#define MBEDTLS_HAVE_TIME_DATE -#define MBEDTLS_HAVE_TIME +/** \} name SECTION: Mbed TLS modules */ + +/** + * \name SECTION: General configuration options + * + * This section contains Mbed TLS build settings that are not associated + * with a particular module. + * + * \{ + */ + +/** + * \def MBEDTLS_CONFIG_FILE + * + * If defined, this is a header which will be included instead of + * `"mbedtls/mbedtls_config.h"`. + * This header file specifies the compile-time configuration of Mbed TLS. + * Unlike other configuration options, this one must be defined on the + * compiler command line: a definition in `mbedtls_config.h` would have + * no effect. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_CONFIG_FILE "mbedtls/mbedtls_config.h" + +/** + * \def MBEDTLS_USER_CONFIG_FILE + * + * If defined, this is a header which will be included after + * `"mbedtls/mbedtls_config.h"` or #MBEDTLS_CONFIG_FILE. + * This allows you to modify the default configuration, including the ability + * to undefine options that are enabled by default. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_USER_CONFIG_FILE "/dev/null" + +/** + * \def MBEDTLS_PSA_CRYPTO_CONFIG_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_config.h"`. + * This header file specifies which cryptographic mechanisms are available + * through the PSA API when #MBEDTLS_PSA_CRYPTO_CONFIG is enabled, and + * is not used when #MBEDTLS_PSA_CRYPTO_CONFIG is disabled. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_CONFIG_FILE "psa/crypto_config.h" + +/** + * \def MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE + * + * If defined, this is a header which will be included after + * `"psa/crypto_config.h"` or #MBEDTLS_PSA_CRYPTO_CONFIG_FILE. + * This allows you to modify the default configuration, including the ability + * to undefine options that are enabled by default. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_USER_CONFIG_FILE "/dev/null" + +/** + * \def MBEDTLS_PSA_CRYPTO_PLATFORM_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_platform.h"`. This file should declare the same identifiers + * as the one in Mbed TLS, but with definitions adapted to the platform on + * which the library code will run. + * + * \note The required content of this header can vary from one version of + * Mbed TLS to the next. Integrators who provide an alternative file + * should review the changes in the original file whenever they + * upgrade Mbed TLS. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_PLATFORM_FILE "psa/crypto_platform_alt.h" + +/** + * \def MBEDTLS_PSA_CRYPTO_STRUCT_FILE + * + * If defined, this is a header which will be included instead of + * `"psa/crypto_struct.h"`. This file should declare the same identifiers + * as the one in Mbed TLS, but with definitions adapted to the environment + * in which the library code will run. The typical use for this feature + * is to provide alternative type definitions on the client side in + * client-server integrations of PSA crypto, where operation structures + * contain handles instead of cryptographic data. + * + * \note The required content of this header can vary from one version of + * Mbed TLS to the next. Integrators who provide an alternative file + * should review the changes in the original file whenever they + * upgrade Mbed TLS. + * + * This macro is expanded after an \#include directive. This is a popular but + * non-standard feature of the C language, so this feature is only available + * with compilers that perform macro expansion on an \#include line. + * + * The value of this symbol is typically a path in double quotes, either + * absolute or relative to a directory on the include search path. + */ +//#define MBEDTLS_PSA_CRYPTO_STRUCT_FILE "psa/crypto_struct_alt.h" + +/** \} name SECTION: General configuration options */ + +/** + * \name SECTION: Module configuration options + * + * This section allows for the setting of module specific sizes and + * configuration options. The default values are already present in the + * relevant header files and should suffice for the regular use cases. + * + * Our advice is to enable options and change their values here + * only if you have a good reason and know the consequences. + * \{ + */ +/* The Doxygen documentation here is used when a user comments out a + * setting and runs doxygen themselves. On the other hand, when we typeset + * the full documentation including disabled settings, the documentation + * in specific modules' header files is used if present. When editing this + * file, make sure that each option is documented in exactly one place, + * plus optionally a same-line Doxygen comment here if there is a Doxygen + * comment in the specific module. */ + +/* MPI / BIGNUM options */ +//#define MBEDTLS_MPI_WINDOW_SIZE 2 /**< Maximum window size used. */ +//#define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ + +/* CTR_DRBG options */ +//#define MBEDTLS_CTR_DRBG_ENTROPY_LEN 48 /**< Amount of entropy used per seed by default (48 with SHA-512, 32 with SHA-256) */ +//#define MBEDTLS_CTR_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_CTR_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_CTR_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_CTR_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* HMAC_DRBG options */ +//#define MBEDTLS_HMAC_DRBG_RESEED_INTERVAL 10000 /**< Interval before reseed is performed by default */ +//#define MBEDTLS_HMAC_DRBG_MAX_INPUT 256 /**< Maximum number of additional input bytes */ +//#define MBEDTLS_HMAC_DRBG_MAX_REQUEST 1024 /**< Maximum number of requested bytes per call */ +//#define MBEDTLS_HMAC_DRBG_MAX_SEED_INPUT 384 /**< Maximum size of (re)seed buffer */ + +/* ECP options */ +//#define MBEDTLS_ECP_WINDOW_SIZE 4 /**< Maximum window size used */ +//#define MBEDTLS_ECP_FIXED_POINT_OPTIM 1 /**< Enable fixed-point speed-up */ + +/* Entropy options */ +//#define MBEDTLS_ENTROPY_MAX_SOURCES 20 /**< Maximum number of sources supported */ +//#define MBEDTLS_ENTROPY_MAX_GATHER 128 /**< Maximum amount requested from entropy sources */ +//#define MBEDTLS_ENTROPY_MIN_HARDWARE 32 /**< Default minimum number of bytes required for the hardware entropy source mbedtls_hardware_poll() before entropy is released */ + +/* Memory buffer allocator options */ +//#define MBEDTLS_MEMORY_ALIGN_MULTIPLE 4 /**< Align on multiples of this value */ + +/* Platform options */ +//#define MBEDTLS_PLATFORM_STD_MEM_HDR /**< Header to include if MBEDTLS_PLATFORM_NO_STD_FUNCTIONS is defined. Don't define if no header is needed. */ + +/** \def MBEDTLS_PLATFORM_STD_CALLOC + * + * Default allocator to use, can be undefined. + * It must initialize the allocated buffer memory to zeroes. + * The size of the buffer is the product of the two parameters. + * The calloc function returns either a null pointer or a pointer to the allocated space. + * If the product is 0, the function may either return NULL or a valid pointer to an array of size 0 which is a valid input to the deallocation function. + * An uninitialized #MBEDTLS_PLATFORM_STD_CALLOC always fails, returning a null pointer. + * See the description of #MBEDTLS_PLATFORM_MEMORY for more details. + * The corresponding deallocation function is #MBEDTLS_PLATFORM_STD_FREE. + */ +//#define MBEDTLS_PLATFORM_STD_CALLOC calloc + +/** \def MBEDTLS_PLATFORM_STD_FREE + * + * Default free to use, can be undefined. + * NULL is a valid parameter, and the function must do nothing. + * A non-null parameter will always be a pointer previously returned by #MBEDTLS_PLATFORM_STD_CALLOC and not yet freed. + * An uninitialized #MBEDTLS_PLATFORM_STD_FREE does not do anything. + * See the description of #MBEDTLS_PLATFORM_MEMORY for more details (same principles as for MBEDTLS_PLATFORM_STD_CALLOC apply). + */ +//#define MBEDTLS_PLATFORM_STD_FREE free +//#define MBEDTLS_PLATFORM_STD_SETBUF setbuf /**< Default setbuf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT exit /**< Default exit to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_TIME time /**< Default time to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_STD_FPRINTF fprintf /**< Default fprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_PRINTF printf /**< Default printf to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_STD_SNPRINTF snprintf /**< Default snprintf to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_SUCCESS 0 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_EXIT_FAILURE 1 /**< Default exit value to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_READ mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_WRITE mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_STD_NV_SEED_FILE "seedfile" /**< Seed file to read/write with default implementation */ + +/* To use the following function macros, MBEDTLS_PLATFORM_C must be enabled. */ +/* MBEDTLS_PLATFORM_XXX_MACRO and MBEDTLS_PLATFORM_XXX_ALT cannot both be defined */ +//#define MBEDTLS_PLATFORM_CALLOC_MACRO calloc /**< Default allocator macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_CALLOC for requirements. */ +//#define MBEDTLS_PLATFORM_FREE_MACRO free /**< Default free macro to use, can be undefined. See MBEDTLS_PLATFORM_STD_FREE for requirements. */ +//#define MBEDTLS_PLATFORM_EXIT_MACRO exit /**< Default exit macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_SETBUF_MACRO setbuf /**< Default setbuf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_TIME_MACRO time /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_TIME_TYPE_MACRO time_t /**< Default time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled */ +//#define MBEDTLS_PLATFORM_FPRINTF_MACRO fprintf /**< Default fprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_PRINTF_MACRO printf /**< Default printf macro to use, can be undefined */ +/* Note: your snprintf must correctly zero-terminate the buffer! */ +//#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf /**< Default snprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_VSNPRINTF_MACRO vsnprintf /**< Default vsnprintf macro to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_READ_MACRO mbedtls_platform_std_nv_seed_read /**< Default nv_seed_read function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_NV_SEED_WRITE_MACRO mbedtls_platform_std_nv_seed_write /**< Default nv_seed_write function to use, can be undefined */ +//#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t //#define MBEDTLS_PLATFORM_MS_TIME_TYPE_MACRO int64_t /**< Default milliseconds time macro to use, can be undefined. MBEDTLS_HAVE_TIME must be enabled. It must be signed, and at least 64 bits. If it is changed from the default, MBEDTLS_PRINTF_MS_TIME must be updated to match.*/ +//#define MBEDTLS_PRINTF_MS_TIME PRId64 /**< Default fmt for printf. That's avoid compiler warning if mbedtls_ms_time_t is redefined */ + +/** \def MBEDTLS_CHECK_RETURN + * + * This macro is used at the beginning of the declaration of a function + * to indicate that its return value should be checked. It should + * instruct the compiler to emit a warning or an error if the function + * is called without checking its return value. + * + * There is a default implementation for popular compilers in platform_util.h. + * You can override the default implementation by defining your own here. + * + * If the implementation here is empty, this will effectively disable the + * checking of functions' return values. + */ +//#define MBEDTLS_CHECK_RETURN __attribute__((__warn_unused_result__)) + +/** \def MBEDTLS_IGNORE_RETURN + * + * This macro requires one argument, which should be a C function call. + * If that function call would cause a #MBEDTLS_CHECK_RETURN warning, this + * warning is suppressed. + */ +//#define MBEDTLS_IGNORE_RETURN( result ) ((void) !(result)) + +/* PSA options */ +/** + * Use HMAC_DRBG with the specified hash algorithm for HMAC_DRBG for the + * PSA crypto subsystem. + * + * If this option is unset: + * - If CTR_DRBG is available, the PSA subsystem uses it rather than HMAC_DRBG. + * - Otherwise, the PSA subsystem uses HMAC_DRBG with either + * #MBEDTLS_MD_SHA512 or #MBEDTLS_MD_SHA256 based on availability and + * on unspecified heuristics. + */ +//#define MBEDTLS_PSA_HMAC_DRBG_MD_TYPE MBEDTLS_MD_SHA256 + +/** \def MBEDTLS_PSA_KEY_SLOT_COUNT + * Restrict the PSA library to supporting a maximum amount of simultaneously + * loaded keys. A loaded key is a key stored by the PSA Crypto core as a + * volatile key, or a persistent key which is loaded temporarily by the + * library as part of a crypto operation in flight. + * + * If this option is unset, the library will fall back to a default value of + * 32 keys. + */ +//#define MBEDTLS_PSA_KEY_SLOT_COUNT 32 + +/* RSA OPTIONS */ +//#define MBEDTLS_RSA_GEN_KEY_MIN_BITS 1024 /**< Minimum RSA key size that can be generated in bits (Minimum possible value is 128 bits) */ + +/* SSL Cache options */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_TIMEOUT 86400 /**< 1 day */ +//#define MBEDTLS_SSL_CACHE_DEFAULT_MAX_ENTRIES 50 /**< Maximum entries in cache */ + +/* SSL options */ + +/** \def MBEDTLS_SSL_IN_CONTENT_LEN + * + * Maximum length (in bytes) of incoming plaintext fragments. + * + * This determines the size of the incoming TLS I/O buffer in such a way + * that it is capable of holding the specified amount of plaintext data, + * regardless of the protection mechanism used. + * + * \note When using a value less than the default of 16KB on the client, it is + * recommended to use the Maximum Fragment Length (MFL) extension to + * inform the server about this limitation. On the server, there + * is no supported, standardized way of informing the client about + * restriction on the maximum size of incoming messages, and unless + * the limitation has been communicated by other means, it is recommended + * to only change the outgoing buffer size #MBEDTLS_SSL_OUT_CONTENT_LEN + * while keeping the default value of 16KB for the incoming buffer. + * + * Uncomment to set the maximum plaintext size of the incoming I/O buffer. + */ +//#define MBEDTLS_SSL_IN_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_CID_IN_LEN_MAX + * + * The maximum length of CIDs used for incoming DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_IN_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_OUT_LEN_MAX + * + * The maximum length of CIDs used for outgoing DTLS messages. + * + */ +//#define MBEDTLS_SSL_CID_OUT_LEN_MAX 32 + +/** \def MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY + * + * This option controls the use of record plaintext padding + * in TLS 1.3 and when using the Connection ID extension in DTLS 1.2. + * + * The padding will always be chosen so that the length of the + * padded plaintext is a multiple of the value of this option. + * + * Note: A value of \c 1 means that no padding will be used + * for outgoing records. + * + * Note: On systems lacking division instructions, + * a power of two should be preferred. + */ +//#define MBEDTLS_SSL_CID_TLS1_3_PADDING_GRANULARITY 16 + +/** \def MBEDTLS_SSL_OUT_CONTENT_LEN + * + * Maximum length (in bytes) of outgoing plaintext fragments. + * + * This determines the size of the outgoing TLS I/O buffer in such a way + * that it is capable of holding the specified amount of plaintext data, + * regardless of the protection mechanism used. + * + * It is possible to save RAM by setting a smaller outward buffer, while keeping + * the default inward 16384 byte buffer to conform to the TLS specification. + * + * The minimum required outward buffer size is determined by the handshake + * protocol's usage. Handshaking will fail if the outward buffer is too small. + * The specific size requirement depends on the configured ciphers and any + * certificate data which is sent during the handshake. + * + * Uncomment to set the maximum plaintext size of the outgoing I/O buffer. + */ +//#define MBEDTLS_SSL_OUT_CONTENT_LEN 16384 + +/** \def MBEDTLS_SSL_DTLS_MAX_BUFFERING + * + * Maximum number of heap-allocated bytes for the purpose of + * DTLS handshake message reassembly and future message buffering. + * + * This should be at least 9/8 * MBEDTLS_SSL_IN_CONTENT_LEN + * to account for a reassembled handshake message of maximum size, + * together with its reassembly bitmap. + * + * A value of 2 * MBEDTLS_SSL_IN_CONTENT_LEN (32768 by default) + * should be sufficient for all practical situations as it allows + * to reassembly a large handshake message (such as a certificate) + * while buffering multiple smaller handshake messages. + * + */ +//#define MBEDTLS_SSL_DTLS_MAX_BUFFERING 32768 + +//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 or 384 bits) */ +//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */ + +/** + * Complete list of ciphersuites to use, in order of preference. + * + * \warning No dependency checking is done on that field! This option can only + * be used to restrict the set of available ciphersuites. It is your + * responsibility to make sure the needed modules are active. + * + * Use this to save a few hundred bytes of ROM (default ordering of all + * available ciphersuites) and a few to a few hundred bytes of RAM. + * + * The value below is only an example, not the default. + */ +//#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + +/** + * \def MBEDTLS_SSL_MAX_EARLY_DATA_SIZE + * + * The default maximum amount of 0-RTT data. See the documentation of + * \c mbedtls_ssl_conf_max_early_data_size() for more information. + * + * It must be positive and smaller than UINT32_MAX. + * + * If MBEDTLS_SSL_EARLY_DATA is not defined, this default value does not + * have any impact on the build. + */ +//#define MBEDTLS_SSL_MAX_EARLY_DATA_SIZE 1024 + +/** + * \def MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE + * + * Maximum allowed ticket age difference in milliseconds tolerated between + * server and client. Default value is 6000. This is not used in TLS 1.2. + * + * - The client ticket age is the time difference between the time when the + * client proposes to the server to use the ticket and the time the client + * received the ticket from the server. + * - The server ticket age is the time difference between the time when the + * server receives a proposition from the client to use the ticket and the + * time when the ticket was created by the server. + * + * The ages might be different due to the client and server clocks not running + * at the same pace. The typical accuracy of an RTC crystal is ±100 to ±20 parts + * per million (360 to 72 milliseconds per hour). Default tolerance window is + * 6s, thus in the worst case clients and servers must sync up their system time + * every 6000/360/2~=8 hours. + * + * See section 8.3 of the TLS 1.3 specification(RFC 8446) for more information. + */ +//#define MBEDTLS_SSL_TLS1_3_TICKET_AGE_TOLERANCE 6000 + +/** + * \def MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH + * + * Size in bytes of a ticket nonce. This is not used in TLS 1.2. + * + * This must be less than 256. + */ +//#define MBEDTLS_SSL_TLS1_3_TICKET_NONCE_LENGTH 32 + +/** + * \def MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS + * + * Default number of NewSessionTicket messages to be sent by a TLS 1.3 server + * after handshake completion. This is not used in TLS 1.2 and relevant only if + * the MBEDTLS_SSL_SESSION_TICKETS option is enabled. + * + */ +//#define MBEDTLS_SSL_TLS1_3_DEFAULT_NEW_SESSION_TICKETS 1 -#include "mbedtls/check_config.h" +/* X509 options */ +//#define MBEDTLS_X509_MAX_INTERMEDIATE_CA 8 /**< Maximum number of intermediate CAs in a verification chain. */ +//#define MBEDTLS_X509_MAX_FILE_PATH_LEN 512 /**< Maximum length of a path/filename string in bytes including the null terminator character ('\0'). */ -#endif /* ifndef MBEDTLS_CONFIG_H_ */ +/** \} name SECTION: Module configuration options */ diff --git a/platform/posix/posixFilePaths.cmake b/platform/posix/posixFilePaths.cmake index 732a18116a..b9cc0cbbd6 100644 --- a/platform/posix/posixFilePaths.cmake +++ b/platform/posix/posixFilePaths.cmake @@ -18,6 +18,10 @@ set( OPENSSL_TRANSPORT_SOURCES ${CMAKE_CURRENT_LIST_DIR}/transport/src/openssl_posix.c ) # MbedTLS transport source files. +set( MBEDTLS_TRANSPORT_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/transport/src/mbedtls_posix.c ) + +# MbedTLS corePKCS11 transport source files. set( MBEDTLS_PKCS11_TRANSPORT_SOURCES ${CMAKE_CURRENT_LIST_DIR}/transport/src/mbedtls_pkcs11_posix.c ) diff --git a/platform/posix/transport/CMakeLists.txt b/platform/posix/transport/CMakeLists.txt index f5ee9ddbb9..192db642a0 100644 --- a/platform/posix/transport/CMakeLists.txt +++ b/platform/posix/transport/CMakeLists.txt @@ -40,40 +40,25 @@ target_link_libraries( openssl_posix # requires explicit linking. ${CMAKE_DL_LIBS} ) -# Set path to corePKCS11 and it's third party libraries. -set(COREPKCS11_LOCATION "${CMAKE_SOURCE_DIR}/libraries/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") - -# Include PKCS #11 library's source and header path variables. -include( ${COREPKCS11_LOCATION}/pkcsFilePaths.cmake ) - -list(APPEND PKCS_SOURCES - "${COREPKCS11_LOCATION}/source/portable/os/posix/core_pkcs11_pal.c" - "${COREPKCS11_LOCATION}/source/portable/os/core_pkcs11_pal_utils.c" - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c" +target_include_directories( openssl_posix + PUBLIC + ${OPENSSL_INCLUDE_DIR} ) -# Create target for POSIX implementation of MbedTLS transport with PKCS #11. -add_library( transport_mbedtls_pkcs11_posix - ${MBEDTLS_PKCS11_TRANSPORT_SOURCES} - ${PKCS_SOURCES} ) +# Create target for POSIX implementation of MbedTLS transport +add_library( transport_mbedtls_posix + ${MBEDTLS_TRANSPORT_SOURCES} ) -target_link_libraries( transport_mbedtls_pkcs11_posix +target_link_libraries( transport_mbedtls_posix PRIVATE - mbedtls ) + mbedtls ) target_include_directories( - transport_mbedtls_pkcs11_posix + transport_mbedtls_posix PUBLIC ${COMMON_TRANSPORT_INCLUDE_PUBLIC_DIRS} ${LOGGING_INCLUDE_DIRS} ${TRANSPORT_INTERFACE_INCLUDE_DIR} - ${PKCS_INCLUDE_PUBLIC_DIRS} - "${COREPKCS11_LOCATION}/source/portable/os" - ${CORE_PKCS11_3RDPARTY_LOCATION}/pkcs11 - ${DEMOS_DIR}/pkcs11/common/include - PRIVATE - ${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils ) # Install transport implementations as both shared and static libraries. @@ -82,7 +67,7 @@ if(INSTALL_PLATFORM_ABSTRACTIONS) openssl_posix plaintext_posix sockets_posix - transport_mbedtls_pkcs11_posix + transport_mbedtls_posix LIBRARY DESTINATION "${CSDK_LIB_INSTALL_PATH}" ARCHIVE DESTINATION "${CSDK_LIB_INSTALL_PATH}") endif() diff --git a/platform/posix/transport/include/mbedtls_pkcs11_posix.h b/platform/posix/transport/include/mbedtls_posix.h similarity index 65% rename from platform/posix/transport/include/mbedtls_pkcs11_posix.h rename to platform/posix/transport/include/mbedtls_posix.h index 076cec867c..1311ece488 100644 --- a/platform/posix/transport/include/mbedtls_pkcs11_posix.h +++ b/platform/posix/transport/include/mbedtls_posix.h @@ -20,14 +20,14 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#ifndef MBEDTLS_PKCS11_POSIX_H_ -#define MBEDTLS_PKCS11_POSIX_H_ +#ifndef MBEDTLS_POSIX_H_ +#define MBEDTLS_POSIX_H_ /** - * @file mbedtls_pkcs11_posix.h + * @file mbedtls_posix.h * * @brief Implementation for the transport interface using a mutually - * authenticated TLS connection with MbedTLS for TLS and corePKCS11 for secure + * authenticated TLS connection with MbedTLS for TLS and core for secure * credential management. */ @@ -47,7 +47,7 @@ /* Logging configuration for the transport interface implementation which uses * MbedTLS and Sockets. */ #ifndef LIBRARY_LOG_NAME - #define LIBRARY_LOG_NAME "Transport_MbedTLS_PKCS11" + #define LIBRARY_LOG_NAME "Transport_MbedTLS_Posix" #endif #ifndef LIBRARY_LOG_LEVEL #define LIBRARY_LOG_LEVEL LOG_WARN @@ -66,18 +66,18 @@ /* Standard includes. */ #include +#define MBEDTLS_ALLOW_PRIVATE_ACCESS + /* MbedTLS includes. */ #include "mbedtls/net_sockets.h" #include "mbedtls/ssl.h" #include "mbedtls/pk.h" -#include "mbedtls/pk_internal.h" +#include "mbedtls/entropy.h" +#include "mbedtls/ctr_drbg.h" /* Transport interface include. */ #include "transport_interface.h" -/* PKCS #11 includes. */ -#include "core_pkcs11.h" - /** * @brief Debug logging level to use for MbedTLS. * @@ -88,14 +88,14 @@ #define MBEDTLS_DEBUG_LOG_LEVEL 0 /** - * @brief Context containing state for the MbedTLS and corePKCS11 based + * @brief Context containing state for the MbedTLS and core based * transport interface implementation. * * @note Applications using this transport interface implementation should use * this struct as the #NetworkContext_t for the transport interface * configuration passed to coreMQTT or coreHTTP. */ -typedef struct MbedtlsPkcs11Context +typedef struct MbedtlsContext { mbedtls_net_context socketContext; /**< @brief MbedTLS socket context. */ mbedtls_ssl_config config; /**< @brief SSL connection configuration. */ @@ -104,33 +104,28 @@ typedef struct MbedtlsPkcs11Context mbedtls_x509_crt rootCa; /**< @brief Root CA certificate context. */ mbedtls_x509_crt clientCert; /**< @brief Client certificate context. */ mbedtls_pk_context privKey; /**< @brief Client private key context. */ - mbedtls_pk_info_t privKeyInfo; /**< @brief Client private key info. */ - - /* PKCS #11. */ - CK_FUNCTION_LIST_PTR pP11FunctionList; /**< @brief PKCS #11 function list. */ - CK_SESSION_HANDLE p11Session; /**< @brief PKCS #11 session. */ - CK_OBJECT_HANDLE p11PrivateKey; /**< @brief PKCS #11 handle for the private key to use for client authentication. */ - CK_KEY_TYPE keyType; /**< @brief PKCS #11 key type corresponding to #p11PrivateKey. */ -} MbedtlsPkcs11Context_t; + mbedtls_entropy_context entropyCtx; /**< @brief Entropy context */ + mbedtls_ctr_drbg_context ctrDrbgCtx; /**< @brief Random number generator context */ +} MbedtlsContext_t; /** * @brief TLS Connect / Disconnect return status. */ -typedef enum MbedtlsPkcs11Status +typedef enum MbedtlsStatus { - MBEDTLS_PKCS11_SUCCESS = 0, /**< Function successfully completed. */ - MBEDTLS_PKCS11_INVALID_PARAMETER, /**< At least one parameter was invalid. */ - MBEDTLS_PKCS11_INSUFFICIENT_MEMORY, /**< Insufficient memory required to establish connection. */ - MBEDTLS_PKCS11_INVALID_CREDENTIALS, /**< Provided credentials were invalid. */ - MBEDTLS_PKCS11_HANDSHAKE_FAILED, /**< Performing TLS handshake with server failed. */ - MBEDTLS_PKCS11_INTERNAL_ERROR, /**< A call to a system API resulted in an internal error. */ - MBEDTLS_PKCS11_CONNECT_FAILURE /**< Initial connection to the server failed. */ -} MbedtlsPkcs11Status_t; + MBEDTLS_SUCCESS = 0, /**< Function successfully completed. */ + MBEDTLS_INVALID_PARAMETER, /**< At least one parameter was invalid. */ + MBEDTLS_INSUFFICIENT_MEMORY, /**< Insufficient memory required to establish connection. */ + MBEDTLS_INVALID_CREDENTIALS, /**< Provided credentials were invalid. */ + MBEDTLS_HANDSHAKE_FAILED, /**< Performing TLS handshake with server failed. */ + MBEDTLS_INTERNAL_ERROR, /**< A call to a system API resulted in an internal error. */ + MBEDTLS_CONNECT_FAILURE /**< Initial connection to the server failed. */ +} MbedtlsStatus_t; /** * @brief Contains the credentials necessary for tls connection setup. */ -typedef struct MbedtlsPkcs11Credentials +typedef struct MbedtlsCredentials { /** * @brief To use ALPN, set this to a NULL-terminated list of supported @@ -148,41 +143,40 @@ typedef struct MbedtlsPkcs11Credentials bool disableSni; const char * pRootCaPath; /**< @brief String representing a trusted server root certificate. */ - char * pClientCertLabel; /**< @brief String representing the PKCS #11 label for the client certificate. */ - char * pPrivateKeyLabel; /**< @brief String representing the PKCS #11 label for the private key. */ - CK_SESSION_HANDLE p11Session; /**< @brief PKCS #11 session handle. */ -} MbedtlsPkcs11Credentials_t; + const char * pClientCertPath; /**< @brief String representing the PKCS #11 label for the client certificate. */ + const char * pPrivateKeyPath; /**< @brief String representing the PKCS #11 label for the private key. */ +} MbedtlsCredentials_t; /** * @brief Sets up a mutually authenticated TLS session on top of a TCP - * connection using the MbedTLS library for TLS and the corePKCS11 library for + * connection using the MbedTLS library for TLS and the core library for * credential management. * * @param[out] pNetworkContext The output parameter to return the created network context. * @param[in] pHostName The hostname of the remote endpoint. * @param[in] port The destination port. - * @param[in] pMbedtlsPkcs11Credentials Credentials for the TLS connection. + * @param[in] pMbedtlsCredentials Credentials for the TLS connection. * @param[in] recvTimeoutMs The timeout for socket receive operations. * - * @note #recvTimeoutMs sets the maximum blocking time of the #Mbedtls_Pkcs11_Recv function. + * @note #recvTimeoutMs sets the maximum blocking time of the #Mbedtls_Recv function. * - * @return #MBEDTLS_PKCS11_SUCCESS on success; - * #MBEDTLS_PKCS11_INSUFFICIENT_MEMORY, #MBEDTLS_PKCS11_INVALID_CREDENTIALS, - * #MBEDTLS_PKCS11_HANDSHAKE_FAILED, #MBEDTLS_PKCS11_INTERNAL_ERROR, - * or #MBEDTLS_PKCS11_CONNECT_FAILURE on failure. + * @return #MBEDTLS_SUCCESS on success; + * #MBEDTLS_INSUFFICIENT_MEMORY, #MBEDTLS_INVALID_CREDENTIALS, + * #MBEDTLS_HANDSHAKE_FAILED, #MBEDTLS_INTERNAL_ERROR, + * or #MBEDTLS_CONNECT_FAILURE on failure. */ -MbedtlsPkcs11Status_t Mbedtls_Pkcs11_Connect( NetworkContext_t * pNetworkContext, - const char * pHostName, - uint16_t port, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials, - uint32_t recvTimeoutMs ); +MbedtlsStatus_t Mbedtls_Connect( NetworkContext_t * pNetworkContext, + const char * pHostName, + uint16_t port, + const MbedtlsCredentials_t * pMbedtlsCredentials, + uint32_t recvTimeoutMs ); /** * @brief Gracefully disconnect an established TLS connection. * * @param[in] pNetworkContext Network context. */ -void Mbedtls_Pkcs11_Disconnect( NetworkContext_t * pNetworkContext ); +void Mbedtls_Disconnect( NetworkContext_t * pNetworkContext ); /** * @brief Receives data over an established TLS session using the MbedTLS API. @@ -190,16 +184,16 @@ void Mbedtls_Pkcs11_Disconnect( NetworkContext_t * pNetworkContext ); * This function can be used as the #TransportInterface.recv implementation of * the transport interface to receive data from the network. * - * @param[in] pNetworkContext The network context created using Mbedtls_Pkcs11_Connect API. + * @param[in] pNetworkContext The network context created using Mbedtls_Connect API. * @param[out] pBuffer Buffer to receive network data into. * @param[in] bytesToRecv Number of bytes requested from the network. * * @return Number of bytes received if successful; negative value to indicate failure. * A return value of zero represents that the receive operation can be retried. */ -int32_t Mbedtls_Pkcs11_Recv( NetworkContext_t * pNetworkContext, - void * pBuffer, - size_t bytesToRecv ); +int32_t Mbedtls_Recv( NetworkContext_t * pNetworkContext, + void * pBuffer, + size_t bytesToRecv ); /** * @brief Sends data over an established TLS session using the MbedTLS API. @@ -207,7 +201,7 @@ int32_t Mbedtls_Pkcs11_Recv( NetworkContext_t * pNetworkContext, * This function can be used as the #TransportInterface.send implementation of * the transport interface to send data over the network. * - * @param[in] pNetworkContext The network context created using Mbedtls_Pkcs11_Connect API. + * @param[in] pNetworkContext The network context created using Mbedtls_Connect API. * @param[in] pBuffer Buffer containing the bytes to send over the network stack. * @param[in] bytesToSend Number of bytes to send over the network. * @@ -216,9 +210,25 @@ int32_t Mbedtls_Pkcs11_Recv( NetworkContext_t * pNetworkContext, * @note This function does not return zero value because it cannot be retried * on send operation failure. */ -int32_t Mbedtls_Pkcs11_Send( NetworkContext_t * pNetworkContext, - const void * pBuffer, - size_t bytesToSend ); +int32_t Mbedtls_Send( NetworkContext_t * pNetworkContext, + const void * pBuffer, + size_t bytesToSend ); + +/** + * @brief Generate a new EC Private Key + * This function generates a new EC private key and writes the resulting key + * in DER format to the provided path. + * + * @param[in] pPrivateKeyPath Path to store the resulting private key. + * + * @return #MBEDTLS_SUCCESS on success + */ +MbedtlsStatus_t Mbedtls_GenerateECKey( const char * pPrivateKeyPath ); + + +MbedtlsStatus_t Mbedtls_GenerateCSR( const char * pPrivateKeyPath, + char * pCsrPemBuffer, + size_t csrPemBufferLength ); /* *INDENT-OFF* */ #ifdef __cplusplus @@ -226,4 +236,4 @@ int32_t Mbedtls_Pkcs11_Send( NetworkContext_t * pNetworkContext, #endif /* *INDENT-ON* */ -#endif /* ifndef MBEDTLS_PKCS11_POSIX_H_ */ +#endif /* ifndef MBEDTLS_POSIX_H_ */ diff --git a/platform/posix/transport/src/mbedtls_pkcs11_posix.c b/platform/posix/transport/src/mbedtls_pkcs11_posix.c deleted file mode 100644 index ba75d643ac..0000000000 --- a/platform/posix/transport/src/mbedtls_pkcs11_posix.c +++ /dev/null @@ -1,969 +0,0 @@ -/* - * AWS IoT Device SDK for Embedded C 202211.00 - * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Standard includes. */ -#include -#include - -/* TLS transport header. */ -#include "mbedtls_pkcs11_posix.h" - -/* MbedTLS includes. */ -#include "mbedtls/debug.h" -#include "mbedtls/error.h" - -/* PKCS #11 includes. */ -#include "core_pki_utils.h" - -/*-----------------------------------------------------------*/ - -/** - * @brief Each compilation unit that consumes the NetworkContext must define it. - * It should contain a single pointer as seen below whenever the header file - * of this transport implementation is included to your project. - * - * @note When using multiple transports in the same compilation unit, - * define this pointer as void *. - */ -struct NetworkContext -{ - MbedtlsPkcs11Context_t * pParams; -}; - -/*-----------------------------------------------------------*/ - -/** - * @brief Represents string to be logged when mbedTLS returned error - * does not contain a high-level code. - */ -static const char * pNoHighLevelMbedTlsCodeStr = ""; - -/** - * @brief Represents string to be logged when mbedTLS returned error - * does not contain a low-level code. - */ -static const char * pNoLowLevelMbedTlsCodeStr = ""; - -/** - * @brief Utility for converting the high-level code in an mbedTLS error to string, - * if the code-contains a high-level code; otherwise, using a default string. - */ -#define mbedtlsHighLevelCodeOrDefault( mbedTlsCode ) \ - ( mbedtls_high_level_strerr( mbedTlsCode ) != NULL ) ? \ - mbedtls_high_level_strerr( mbedTlsCode ) : pNoHighLevelMbedTlsCodeStr - -/** - * @brief Utility for converting the level-level code in an mbedTLS error to string, - * if the code-contains a level-level code; otherwise, using a default string. - */ -#define mbedtlsLowLevelCodeOrDefault( mbedTlsCode ) \ - ( mbedtls_low_level_strerr( mbedTlsCode ) != NULL ) ? \ - mbedtls_low_level_strerr( mbedTlsCode ) : pNoLowLevelMbedTlsCodeStr - -/*-----------------------------------------------------------*/ - -/** - * @brief Initialize the MbedTLS structures in a network connection. - * - * @param[in] pContext The SSL context to initialize. - */ -static void contextInit( MbedtlsPkcs11Context_t * pContext ); - -/** - * @brief Free the MbedTLS structures in a network connection. - * - * @param[in] pContext The SSL context to free. - */ -static void contextFree( MbedtlsPkcs11Context_t * pContext ); - -/** - * @brief Configure MbedTLS for TLS on a TCP connection using PKCS #11 for the - * client credentials. - * - * @param[in] pMbedtlsPkcs11Context Network context. - * @param[in] pHostName Remote host name, used for server name indication. - * @param[in] pMbedtlsPkcs11Credentials TLS setup parameters. - * @param[in] recvTimeoutMs Receive timeout for network socket. - * - * @return #MBEDTLS_PKCS11_SUCCESS, #MBEDTLS_PKCS11_INSUFFICIENT_MEMORY, #MBEDTLS_PKCS11_INVALID_CREDENTIALS, - * #MBEDTLS_PKCS11_HANDSHAKE_FAILED, or #MBEDTLS_PKCS11_INTERNAL_ERROR. - */ -static MbedtlsPkcs11Status_t configureMbedtls( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context, - const char * pHostName, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials, - uint32_t recvTimeoutMs ); - -/** - * @brief Configure the client and Root CA in the MbedTLS SSL context. - * - * @param[in] pMbedtlsPkcs11Context Network context. - * @param[in] pMbedtlsPkcs11Credentials TLS setup parameters. - * - * @return #MBEDTLS_PKCS11_SUCCESS on success, - * #MBEDTLS_PKCS11_INVALID_CREDENTIALS on error. - */ -static MbedtlsPkcs11Status_t configureMbedtlsCertificates( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials ); - -/** - * @brief Configure the SNI and ALPN in the MbedTLS SSL context. - * - * @param[in] pMbedtlsPkcs11Context Network context. - * @param[in] pMbedtlsPkcs11Credentials TLS setup parameters. - * @param[in] pHostName Remote host name, used for server name indication. - * - * @return #MBEDTLS_PKCS11_SUCCESS on success, - * #MBEDTLS_PKCS11_INVALID_CREDENTIALS on error. - */ -static MbedtlsPkcs11Status_t configureMbedtlsSniAlpn( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials, - const char * pHostName ); - -/** - * @brief Configure the Maximum Fragment Length in the MbedTLS SSL context. - * - * @param[in] pMbedtlsPkcs11Context Network context. - * - * @return #MBEDTLS_PKCS11_SUCCESS on success, - * #MBEDTLS_PKCS11_INVALID_CREDENTIALS on error. - */ -static MbedtlsPkcs11Status_t configureMbedtlsFragmentLength( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context ); - -/** - * @brief Callback that wraps PKCS #11 for pseudo-random number generation. This - * is passed to MbedTLS. - * - * @param[in] pCtx Caller context. - * @param[in] pRandom Byte array to fill with random data. - * @param[in] randomLength Length of byte array. - * - * @return Zero on success. - */ -static int32_t generateRandomBytes( void * pCtx, - unsigned char * pRandom, - size_t randomLength ); - -/** - * @brief Helper for reading the specified certificate object, if present, - * out of storage, into RAM, and then into an mbedTLS certificate context - * object. - * - * @param[in] pContext Caller TLS context. - * @param[in] pLabelName PKCS #11 certificate object label. - * @param[out] pCertificateContext Certificate context. - * - * @return True on success. - */ -static bool readCertificateIntoContext( MbedtlsPkcs11Context_t * pContext, - char * pLabelName, - mbedtls_x509_crt * pCertificateContext ); - -/** - * @brief Helper for configuring MbedTLS to use client private key from PKCS #11. - * - * @param pContext Caller context. - * @param pPrivateKeyLabel PKCS #11 label for the private key. - * - * @return True on success. - */ -static bool initializeClientKeys( MbedtlsPkcs11Context_t * pContext, - const char * pPrivateKeyLabel ); - -/** - * @brief Sign a cryptographic hash with the private key. This is passed as a - * callback to MbedTLS. - * - * @param[in] pContext Crypto context. - * @param[in] mdAlg Unused. - * @param[in] pHash Length in bytes of hash to be signed. - * @param[in] hashLen Byte array of hash to be signed. - * @param[out] pSig RSA signature bytes. - * @param[in] pSigLen Length in bytes of signature buffer. - * @param[in] pRng Unused. - * @param[in] pRngContext Unused. - * - * @return Zero on success. - */ -static int32_t privateKeySigningCallback( void * pContext, - mbedtls_md_type_t mdAlg, - const unsigned char * pHash, - size_t hashLen, - unsigned char * pSig, - size_t * pSigLen, - int32_t ( * pRng )( void *, unsigned char *, size_t ), - void * pRngContext ); - -/*-----------------------------------------------------------*/ - -static void contextInit( MbedtlsPkcs11Context_t * pContext ) -{ - assert( pContext != NULL ); - - mbedtls_net_init( &( pContext->socketContext ) ); - mbedtls_ssl_init( &( pContext->context ) ); - mbedtls_ssl_config_init( &( pContext->config ) ); - mbedtls_x509_crt_init( &( pContext->rootCa ) ); - mbedtls_x509_crt_init( &( pContext->clientCert ) ); - - C_GetFunctionList( &( pContext->pP11FunctionList ) ); -} -/*-----------------------------------------------------------*/ - -static void contextFree( MbedtlsPkcs11Context_t * pContext ) -{ - if( pContext != NULL ) - { - mbedtls_net_free( &( pContext->socketContext ) ); - mbedtls_ssl_free( &( pContext->context ) ); - mbedtls_ssl_config_free( &( pContext->config ) ); - mbedtls_x509_crt_free( &( pContext->rootCa ) ); - mbedtls_x509_crt_free( &( pContext->clientCert ) ); - } -} - -/*-----------------------------------------------------------*/ - -static void mbedtlsDebugPrint( void * ctx, - int level, - const char * pFile, - int line, - const char * pStr ) -{ - /* Unused parameters. */ - ( void ) ctx; - ( void ) pFile; - ( void ) line; - - /* Send the debug string to the portable logger. */ - printf( "mbedTLS: |%d| %s", level, pStr ); -} - -/*-----------------------------------------------------------*/ - -static MbedtlsPkcs11Status_t configureMbedtls( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context, - const char * pHostName, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials, - uint32_t recvTimeoutMs ) -{ - MbedtlsPkcs11Status_t returnStatus = MBEDTLS_PKCS11_SUCCESS; - int32_t mbedtlsError = 0; - - assert( pMbedtlsPkcs11Context != NULL ); - assert( pHostName != NULL ); - assert( pMbedtlsPkcs11Credentials != NULL ); - assert( pMbedtlsPkcs11Credentials->pRootCaPath != NULL ); - - /* Initialize the MbedTLS context structures. */ - contextInit( pMbedtlsPkcs11Context ); - pMbedtlsPkcs11Context->p11Session = pMbedtlsPkcs11Credentials->p11Session; - - mbedtlsError = mbedtls_ssl_config_defaults( &( pMbedtlsPkcs11Context->config ), - MBEDTLS_SSL_IS_CLIENT, - MBEDTLS_SSL_TRANSPORT_STREAM, - MBEDTLS_SSL_PRESET_DEFAULT ); - - if( mbedtlsError != 0 ) - { - LogError( ( "Failed to set default SSL configuration: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsError ), - mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); - - /* Per MbedTLS docs, mbedtls_ssl_config_defaults only fails on memory allocation. */ - returnStatus = MBEDTLS_PKCS11_INSUFFICIENT_MEMORY; - } - else - { - /* Set up the certificate security profile, starting from the default value. */ - pMbedtlsPkcs11Context->certProfile = mbedtls_x509_crt_profile_default; - - /* Set SSL authmode and the RNG context. */ - mbedtls_ssl_conf_authmode( &( pMbedtlsPkcs11Context->config ), MBEDTLS_SSL_VERIFY_REQUIRED ); - mbedtls_ssl_conf_rng( &( pMbedtlsPkcs11Context->config ), generateRandomBytes, pMbedtlsPkcs11Context ); - mbedtls_ssl_conf_cert_profile( &( pMbedtlsPkcs11Context->config ), &( pMbedtlsPkcs11Context->certProfile ) ); - mbedtls_ssl_conf_read_timeout( &( pMbedtlsPkcs11Context->config ), recvTimeoutMs ); - mbedtls_ssl_conf_dbg( &pMbedtlsPkcs11Context->config, mbedtlsDebugPrint, NULL ); - mbedtls_debug_set_threshold( MBEDTLS_DEBUG_LOG_LEVEL ); - - returnStatus = configureMbedtlsCertificates( pMbedtlsPkcs11Context, pMbedtlsPkcs11Credentials ); - } - - if( returnStatus == MBEDTLS_PKCS11_SUCCESS ) - { - returnStatus = configureMbedtlsSniAlpn( pMbedtlsPkcs11Context, pMbedtlsPkcs11Credentials, pHostName ); - } - - if( returnStatus == MBEDTLS_PKCS11_SUCCESS ) - { - /* Initialize the MbedTLS secured connection context. */ - mbedtlsError = mbedtls_ssl_setup( &( pMbedtlsPkcs11Context->context ), - &( pMbedtlsPkcs11Context->config ) ); - - if( mbedtlsError != 0 ) - { - LogError( ( "Failed to set up MbedTLS SSL context: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsError ), - mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); - returnStatus = MBEDTLS_PKCS11_INTERNAL_ERROR; - } - } - - if( returnStatus == MBEDTLS_PKCS11_SUCCESS ) - { - /* Set the underlying IO for the TLS connection. */ - mbedtls_ssl_set_bio( &( pMbedtlsPkcs11Context->context ), - ( void * ) &( pMbedtlsPkcs11Context->socketContext ), - mbedtls_net_send, - mbedtls_net_recv, - mbedtls_net_recv_timeout ); - - returnStatus = configureMbedtlsFragmentLength( pMbedtlsPkcs11Context ); - } - - if( returnStatus != MBEDTLS_PKCS11_SUCCESS ) - { - contextFree( pMbedtlsPkcs11Context ); - } - else - { - LogDebug( ( "Configured MbedTLS context." ) ); - } - - return returnStatus; -} - -/*-----------------------------------------------------------*/ - -static MbedtlsPkcs11Status_t configureMbedtlsCertificates( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials ) - -{ - MbedtlsPkcs11Status_t returnStatus = MBEDTLS_PKCS11_SUCCESS; - int32_t mbedtlsError = 0; - bool result; - - assert( pMbedtlsPkcs11Context != NULL ); - assert( pMbedtlsPkcs11Credentials != NULL ); - assert( pMbedtlsPkcs11Credentials->pRootCaPath != NULL ); - - /* Parse the server root CA certificate into the SSL context. */ - mbedtlsError = mbedtls_x509_crt_parse_file( &( pMbedtlsPkcs11Context->rootCa ), - pMbedtlsPkcs11Credentials->pRootCaPath ); - - if( mbedtlsError != 0 ) - { - LogError( ( "Failed to parse server root CA certificate: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsError ), - mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); - returnStatus = MBEDTLS_PKCS11_INVALID_CREDENTIALS; - } - else - { - mbedtls_ssl_conf_ca_chain( &( pMbedtlsPkcs11Context->config ), - &( pMbedtlsPkcs11Context->rootCa ), - NULL ); - /* Setup the client private key. */ - result = initializeClientKeys( pMbedtlsPkcs11Context, - pMbedtlsPkcs11Credentials->pPrivateKeyLabel ); - - if( result == false ) - { - LogError( ( "Failed to setup key handling by PKCS #11." ) ); - returnStatus = MBEDTLS_PKCS11_INVALID_CREDENTIALS; - } - } - - if( returnStatus == MBEDTLS_PKCS11_SUCCESS ) - { - /* Setup the client certificate. */ - result = readCertificateIntoContext( pMbedtlsPkcs11Context, - pMbedtlsPkcs11Credentials->pClientCertLabel, - &( pMbedtlsPkcs11Context->clientCert ) ); - - if( result == false ) - { - LogError( ( "Failed to get certificate from PKCS #11 module." ) ); - returnStatus = MBEDTLS_PKCS11_INVALID_CREDENTIALS; - } - } - - if( returnStatus == MBEDTLS_PKCS11_SUCCESS ) - { - ( void ) mbedtls_ssl_conf_own_cert( &( pMbedtlsPkcs11Context->config ), - &( pMbedtlsPkcs11Context->clientCert ), - &( pMbedtlsPkcs11Context->privKey ) ); - } - - return returnStatus; -} - -/*-----------------------------------------------------------*/ - -static MbedtlsPkcs11Status_t configureMbedtlsSniAlpn( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials, - const char * pHostName ) -{ - MbedtlsPkcs11Status_t returnStatus = MBEDTLS_PKCS11_SUCCESS; - int32_t mbedtlsError = 0; - - assert( pMbedtlsPkcs11Context != NULL ); - assert( pHostName != NULL ); - assert( pMbedtlsPkcs11Credentials != NULL ); - assert( pMbedtlsPkcs11Credentials->pRootCaPath != NULL ); - - if( pMbedtlsPkcs11Credentials->pAlpnProtos != NULL ) - { - /* Include an application protocol list in the TLS ClientHello message. */ - mbedtlsError = mbedtls_ssl_conf_alpn_protocols( &( pMbedtlsPkcs11Context->config ), - pMbedtlsPkcs11Credentials->pAlpnProtos ); - - if( mbedtlsError != 0 ) - { - LogError( ( "Failed to configure ALPN protocol in MbedTLS: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsError ), - mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); - returnStatus = MBEDTLS_PKCS11_INTERNAL_ERROR; - } - } - - /* Enable SNI if requested. */ - if( ( returnStatus == MBEDTLS_PKCS11_SUCCESS ) && - ( pMbedtlsPkcs11Credentials->disableSni == false ) ) - { - mbedtlsError = mbedtls_ssl_set_hostname( &( pMbedtlsPkcs11Context->context ), - pHostName ); - - if( mbedtlsError != 0 ) - { - LogError( ( "Failed to set server name: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsError ), - mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); - returnStatus = MBEDTLS_PKCS11_INTERNAL_ERROR; - } - } - - return returnStatus; -} - -/*-----------------------------------------------------------*/ - -static MbedtlsPkcs11Status_t configureMbedtlsFragmentLength( MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context ) -{ - MbedtlsPkcs11Status_t returnStatus = MBEDTLS_PKCS11_SUCCESS; - int32_t mbedtlsError = 0; - - assert( pMbedtlsPkcs11Context != NULL ); - - /* Set Maximum Fragment Length if enabled. */ - #ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH - - /* Enable the max fragment extension. 4096 bytes is currently the largest fragment size permitted. - * See RFC 6066 https://tools.ietf.org/html/rfc6066#page-8 for more information. - * - * Smaller values can be found in "mbedtls/include/ssl.h". - */ - mbedtlsError = mbedtls_ssl_conf_max_frag_len( &( pMbedtlsPkcs11Context->config ), MBEDTLS_SSL_MAX_FRAG_LEN_4096 ); - - if( mbedtlsError != 0 ) - { - LogError( ( "Failed to maximum fragment length extension: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsError ), - mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); - returnStatus = MBEDTLS_PKCS11_INTERNAL_ERROR; - } - #endif /* ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ - return returnStatus; -} - -/*-----------------------------------------------------------*/ - -static int32_t generateRandomBytes( void * pCtx, - unsigned char * pRandom, - size_t randomLength ) -{ - /* Must cast from void pointer to conform to MbedTLS API. */ - MbedtlsPkcs11Context_t * pContext = ( MbedtlsPkcs11Context_t * ) pCtx; - CK_RV xResult; - - assert( pCtx != NULL ); - assert( pRandom != NULL ); - - xResult = pContext->pP11FunctionList->C_GenerateRandom( pContext->p11Session, pRandom, randomLength ); - - if( xResult != CKR_OK ) - { - LogError( ( "Failed to generate random bytes from the PKCS #11 module." ) ); - } - - return ( int32_t ) xResult; -} - -/*----------------------------------------------------------*/ - -static bool readCertificateIntoContext( MbedtlsPkcs11Context_t * pContext, - char * pLabelName, - mbedtls_x509_crt * pCertificateContext ) -{ - CK_RV pkcs11Ret = CKR_OK; - CK_ATTRIBUTE template = { 0 }; - CK_OBJECT_HANDLE certificateHandle = 0; - int32_t mbedtlsRet = -1; - - assert( pContext != NULL ); - assert( pLabelName != NULL ); - assert( pCertificateContext != NULL ); - - /* Get the handle of the certificate. */ - pkcs11Ret = xFindObjectWithLabelAndClass( pContext->p11Session, - pLabelName, - strlen( pLabelName ), - CKO_CERTIFICATE, - &certificateHandle ); - - if( ( pkcs11Ret == CKR_OK ) && ( certificateHandle == CK_INVALID_HANDLE ) ) - { - pkcs11Ret = CKR_OBJECT_HANDLE_INVALID; - } - - /* Query the certificate size. */ - if( pkcs11Ret == CKR_OK ) - { - template.type = CKA_VALUE; - template.ulValueLen = 0; - template.pValue = NULL; - pkcs11Ret = pContext->pP11FunctionList->C_GetAttributeValue( pContext->p11Session, - certificateHandle, - &template, - 1 ); - } - - /* Create a buffer for the certificate. */ - if( pkcs11Ret == CKR_OK ) - { - template.pValue = malloc( template.ulValueLen ); - - if( NULL == template.pValue ) - { - LogError( ( "Failed to allocate %lu bytes of memory for certificate buffer.", - template.ulValueLen ) ); - pkcs11Ret = CKR_HOST_MEMORY; - } - } - - /* Export the certificate. */ - if( pkcs11Ret == CKR_OK ) - { - pkcs11Ret = pContext->pP11FunctionList->C_GetAttributeValue( pContext->p11Session, - certificateHandle, - &template, - 1 ); - } - - /* Decode the certificate. */ - if( pkcs11Ret == CKR_OK ) - { - mbedtlsRet = mbedtls_x509_crt_parse( pCertificateContext, - ( const unsigned char * ) template.pValue, - template.ulValueLen ); - } - - /* Free memory. */ - free( template.pValue ); - - return( mbedtlsRet == 0 ); -} - -/*-----------------------------------------------------------*/ - -static bool initializeClientKeys( MbedtlsPkcs11Context_t * pContext, - const char * pPrivateKeyLabel ) -{ - CK_RV ret = CKR_OK; - CK_ATTRIBUTE template[ 2 ] = { 0 }; - mbedtls_pk_type_t keyAlgo = 0; - - assert( pContext != NULL ); - assert( pPrivateKeyLabel != NULL ); - - /* Get the handle of the device private key. */ - ret = xFindObjectWithLabelAndClass( pContext->p11Session, - ( char * ) pPrivateKeyLabel, - strlen( pPrivateKeyLabel ), - CKO_PRIVATE_KEY, - &pContext->p11PrivateKey ); - - if( ( ret == CKR_OK ) && ( pContext->p11PrivateKey == CK_INVALID_HANDLE ) ) - { - ret = CK_INVALID_HANDLE; - LogError( ( "Could not find private key." ) ); - } - - /* Query the device private key type. */ - if( ret == CKR_OK ) - { - template[ 0 ].type = CKA_KEY_TYPE; - template[ 0 ].pValue = &pContext->keyType; - template[ 0 ].ulValueLen = sizeof( &pContext->keyType ); - ret = pContext->pP11FunctionList->C_GetAttributeValue( pContext->p11Session, - pContext->p11PrivateKey, - template, - 1 ); - } - - /* Map the PKCS #11 key type to an mbedTLS algorithm. */ - if( ret == CKR_OK ) - { - switch( pContext->keyType ) - { - case CKK_RSA: - keyAlgo = MBEDTLS_PK_RSA; - break; - - case CKK_EC: - keyAlgo = MBEDTLS_PK_ECKEY; - break; - - default: - ret = CKR_ATTRIBUTE_VALUE_INVALID; - break; - } - } - - /* Map the mbedTLS algorithm to its internal metadata. */ - if( ret == CKR_OK ) - { - memcpy( &pContext->privKeyInfo, mbedtls_pk_info_from_type( keyAlgo ), sizeof( mbedtls_pk_info_t ) ); - - pContext->privKeyInfo.sign_func = privateKeySigningCallback; - pContext->privKey.pk_info = &pContext->privKeyInfo; - pContext->privKey.pk_ctx = pContext; - } - - return( ret == CKR_OK ); -} - -/*-----------------------------------------------------------*/ - -static int32_t privateKeySigningCallback( void * pContext, - mbedtls_md_type_t mdAlg, - const unsigned char * pHash, - size_t hashLen, - unsigned char * pSig, - size_t * pSigLen, - int32_t ( * pRng )( void *, - unsigned char *, - size_t ), - void * pRngContext ) -{ - CK_RV ret = CKR_OK; - int32_t result = 0; - MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context = ( MbedtlsPkcs11Context_t * ) pContext; - CK_MECHANISM mech = { 0 }; - /* Buffer big enough to hold data to be signed. */ - CK_BYTE toBeSigned[ 256 ]; - CK_ULONG toBeSignedLen = sizeof( toBeSigned ); - - /* Unreferenced parameters. */ - ( void ) ( pRng ); - ( void ) ( pRngContext ); - ( void ) ( mdAlg ); - - assert( pContext != NULL ); - assert( pHash != NULL ); - assert( pSigLen != NULL ); - - /* Sanity check buffer length. */ - if( hashLen > sizeof( toBeSigned ) ) - { - ret = CKR_ARGUMENTS_BAD; - } - - /* Format the hash data to be signed. */ - if( pMbedtlsPkcs11Context->keyType == CKK_RSA ) - { - mech.mechanism = CKM_RSA_PKCS; - - /* mbedTLS expects hashed data without padding, but PKCS #11 C_Sign function performs a hash - * & sign if hash algorithm is specified. This helper function applies padding - * indicating data was hashed with SHA-256 while still allowing pre-hashed data to - * be provided. */ - ret = vAppendSHA256AlgorithmIdentifierSequence( ( const uint8_t * ) pHash, toBeSigned ); - toBeSignedLen = pkcs11RSA_SIGNATURE_INPUT_LENGTH; - } - else if( pMbedtlsPkcs11Context->keyType == CKK_EC ) - { - mech.mechanism = CKM_ECDSA; - memcpy( toBeSigned, pHash, hashLen ); - toBeSignedLen = hashLen; - } - else - { - ret = CKR_ARGUMENTS_BAD; - } - - if( ret == CKR_OK ) - { - /* Use the PKCS #11 module to sign. */ - ret = pMbedtlsPkcs11Context->pP11FunctionList->C_SignInit( pMbedtlsPkcs11Context->p11Session, - &mech, - pMbedtlsPkcs11Context->p11PrivateKey ); - } - - if( ret == CKR_OK ) - { - *pSigLen = sizeof( toBeSigned ); - ret = pMbedtlsPkcs11Context->pP11FunctionList->C_Sign( pMbedtlsPkcs11Context->p11Session, - toBeSigned, - toBeSignedLen, - pSig, - ( CK_ULONG_PTR ) pSigLen ); - } - - if( ( ret == CKR_OK ) && ( pMbedtlsPkcs11Context->keyType == CKK_EC ) ) - { - /* PKCS #11 for P256 returns a 64-byte signature with 32 bytes for R and 32 bytes for S. - * This must be converted to an ASN.1 encoded array. */ - if( *pSigLen != pkcs11ECDSA_P256_SIGNATURE_LENGTH ) - { - ret = CKR_FUNCTION_FAILED; - } - - if( ret == CKR_OK ) - { - PKI_pkcs11SignatureTombedTLSSignature( pSig, pSigLen ); - } - } - - if( ret != CKR_OK ) - { - LogError( ( "Failed to sign message using PKCS #11 with error code %lu.", ( unsigned long ) ret ) ); - } - - return result; -} - -/*-----------------------------------------------------------*/ - -MbedtlsPkcs11Status_t Mbedtls_Pkcs11_Connect( NetworkContext_t * pNetworkContext, - const char * pHostName, - uint16_t port, - const MbedtlsPkcs11Credentials_t * pMbedtlsPkcs11Credentials, - uint32_t recvTimeoutMs ) -{ - MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context = NULL; - MbedtlsPkcs11Status_t returnStatus = MBEDTLS_PKCS11_SUCCESS; - int32_t mbedtlsError = 0; - char portStr[ 6 ] = { 0 }; - - if( ( pNetworkContext == NULL ) || - ( pNetworkContext->pParams == NULL ) || - ( pHostName == NULL ) || - ( pMbedtlsPkcs11Credentials == NULL ) || - ( pMbedtlsPkcs11Credentials->pRootCaPath == NULL ) || - ( pMbedtlsPkcs11Credentials->pClientCertLabel == NULL ) || - ( pMbedtlsPkcs11Credentials->pPrivateKeyLabel == NULL ) ) - { - LogError( ( "Invalid input parameter(s): Arguments cannot be NULL. pNetworkContext=%p, " - "pHostName=%p, pMbedtlsPkcs11Credentials=%p.", - ( void * ) pNetworkContext, - ( const void * ) pHostName, - ( const void * ) pMbedtlsPkcs11Credentials ) ); - returnStatus = MBEDTLS_PKCS11_INVALID_PARAMETER; - } - else - { - snprintf( portStr, sizeof( portStr ), "%u", port ); - pMbedtlsPkcs11Context = pNetworkContext->pParams; - - /* Configure MbedTLS. */ - returnStatus = configureMbedtls( pMbedtlsPkcs11Context, pHostName, pMbedtlsPkcs11Credentials, recvTimeoutMs ); - } - - /* Establish a TCP connection with the server. */ - if( returnStatus == MBEDTLS_PKCS11_SUCCESS ) - { - mbedtlsError = mbedtls_net_connect( &( pMbedtlsPkcs11Context->socketContext ), - pHostName, - portStr, - MBEDTLS_NET_PROTO_TCP ); - - if( mbedtlsError != 0 ) - { - LogError( ( "Failed to connect to %s with error %d.", pHostName, mbedtlsError ) ); - returnStatus = MBEDTLS_PKCS11_CONNECT_FAILURE; - } - } - - if( returnStatus == MBEDTLS_PKCS11_SUCCESS ) - { - /* Perform the TLS handshake. */ - do - { - mbedtlsError = mbedtls_ssl_handshake( &( pMbedtlsPkcs11Context->context ) ); - } while( ( mbedtlsError == MBEDTLS_ERR_SSL_WANT_READ ) || - ( mbedtlsError == MBEDTLS_ERR_SSL_WANT_WRITE ) ); - - if( ( mbedtlsError != 0 ) || ( mbedtls_ssl_get_verify_result( &( pMbedtlsPkcs11Context->context ) ) != 0U ) ) - { - LogError( ( "Failed to perform TLS handshake: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( mbedtlsError ), - mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); - returnStatus = MBEDTLS_PKCS11_HANDSHAKE_FAILED; - } - } - - /* Clean up on failure. */ - if( returnStatus != MBEDTLS_PKCS11_SUCCESS ) - { - contextFree( pMbedtlsPkcs11Context ); - } - else - { - LogInfo( ( "TLS Connection to %s established.", pHostName ) ); - } - - return returnStatus; -} - -/*-----------------------------------------------------------*/ - -void Mbedtls_Pkcs11_Disconnect( NetworkContext_t * pNetworkContext ) -{ - MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context = NULL; - int tlsStatus = 0; - - if( ( pNetworkContext != NULL ) && ( pNetworkContext->pParams != NULL ) ) - { - pMbedtlsPkcs11Context = pNetworkContext->pParams; - /* Attempting to terminate TLS connection. */ - tlsStatus = mbedtls_ssl_close_notify( &( pMbedtlsPkcs11Context->context ) ); - - if( tlsStatus == 0 ) - { - LogInfo( ( "Closing TLS connection: TLS close-notify sent." ) ); - } - else if( ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) || - ( tlsStatus == MBEDTLS_ERR_SSL_WANT_WRITE ) ) - { - /* WANT_READ or WANT_WRITE can be ignored. Logging for debugging purposes. */ - LogInfo( ( "TLS close-notify sent; " - "received %s as the TLS status which can be ignored for close-notify.", - ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) ? "WANT_READ" : "WANT_WRITE" ) ); - } - else - { - /* Ignore the WANT_READ or WANT_WRITE return values. */ - LogError( ( "Failed to send TLS close-notify: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( tlsStatus ), - mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); - } - - /* Free contexts. */ - contextFree( pMbedtlsPkcs11Context ); - } -} - -/*-----------------------------------------------------------*/ - -int32_t Mbedtls_Pkcs11_Recv( NetworkContext_t * pNetworkContext, - void * pBuffer, - size_t bytesToRecv ) -{ - MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context = NULL; - int32_t tlsStatus = 0; - - assert( ( pNetworkContext != NULL ) && ( pNetworkContext->pParams != NULL ) ); - - pMbedtlsPkcs11Context = pNetworkContext->pParams; - tlsStatus = ( int32_t ) mbedtls_ssl_read( &( pMbedtlsPkcs11Context->context ), - pBuffer, - bytesToRecv ); - - if( ( tlsStatus == MBEDTLS_ERR_SSL_TIMEOUT ) || - ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) || - ( tlsStatus == MBEDTLS_ERR_SSL_WANT_WRITE ) ) - { - LogDebug( ( "Failed to read data. However, a read can be retried on this error. " - "mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( tlsStatus ), - mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); - - /* Mark these set of errors as a timeout. The libraries may retry read - * on these errors. */ - tlsStatus = 0; - } - else if( tlsStatus < 0 ) - { - LogError( ( "Failed to read data: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( tlsStatus ), - mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); - } - else - { - /* Empty else marker. */ - } - - return tlsStatus; -} - -/*-----------------------------------------------------------*/ - -int32_t Mbedtls_Pkcs11_Send( NetworkContext_t * pNetworkContext, - const void * pBuffer, - size_t bytesToSend ) -{ - MbedtlsPkcs11Context_t * pMbedtlsPkcs11Context = NULL; - int32_t tlsStatus = 0; - - assert( ( pNetworkContext != NULL ) && ( pNetworkContext->pParams != NULL ) ); - - pMbedtlsPkcs11Context = pNetworkContext->pParams; - tlsStatus = ( int32_t ) mbedtls_ssl_write( &( pMbedtlsPkcs11Context->context ), - pBuffer, - bytesToSend ); - - if( ( tlsStatus == MBEDTLS_ERR_SSL_TIMEOUT ) || - ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) || - ( tlsStatus == MBEDTLS_ERR_SSL_WANT_WRITE ) ) - { - LogDebug( ( "Failed to send data. However, send can be retried on this error. " - "mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( tlsStatus ), - mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); - - /* Mark these set of errors as a timeout. The libraries may retry send - * on these errors. */ - tlsStatus = 0; - } - else if( tlsStatus < 0 ) - { - LogError( ( "Failed to send data: mbedTLSError= %s : %s.", - mbedtlsHighLevelCodeOrDefault( tlsStatus ), - mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); - } - else - { - /* Empty else marker. */ - } - - return tlsStatus; -} -/*-----------------------------------------------------------*/ diff --git a/platform/posix/transport/src/mbedtls_posix.c b/platform/posix/transport/src/mbedtls_posix.c new file mode 100644 index 0000000000..6f171fa131 --- /dev/null +++ b/platform/posix/transport/src/mbedtls_posix.c @@ -0,0 +1,933 @@ +/* + * AWS IoT Device SDK for Embedded C 202211.00 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* Standard includes. */ +#include +#include +#include +#include +#include + +/* TLS transport header. */ +#include "mbedtls_posix.h" + +/* MbedTLS includes. */ +#include "mbedtls/debug.h" +#include "mbedtls/error.h" +#include "mbedtls/x509_csr.h" + +/*-----------------------------------------------------------*/ + +/** + * @brief Each compilation unit that consumes the NetworkContext must define it. + * It should contain a single pointer as seen below whenever the header file + * of this transport implementation is included to your project. + * + * @note When using multiple transports in the same compilation unit, + * define this pointer as void *. + */ +struct NetworkContext +{ + MbedtlsContext_t * pParams; +}; + +/*-----------------------------------------------------------*/ + +/** + * @brief Represents string to be logged when mbedTLS returned error + * does not contain a high-level code. + */ +static const char * pNoHighLevelMbedTlsCodeStr = ""; + +/** + * @brief Represents string to be logged when mbedTLS returned error + * does not contain a low-level code. + */ +static const char * pNoLowLevelMbedTlsCodeStr = ""; + +/** + * @brief Utility for converting the high-level code in an mbedTLS error to string, + * if the code-contains a high-level code; otherwise, using a default string. + */ +#define mbedtlsHighLevelCodeOrDefault( mbedTlsCode ) \ + ( mbedtls_high_level_strerr( mbedTlsCode ) != NULL ) ? \ + mbedtls_high_level_strerr( mbedTlsCode ) : pNoHighLevelMbedTlsCodeStr + +/** + * @brief Utility for converting the level-level code in an mbedTLS error to string, + * if the code-contains a level-level code; otherwise, using a default string. + */ +#define mbedtlsLowLevelCodeOrDefault( mbedTlsCode ) \ + ( mbedtls_low_level_strerr( mbedTlsCode ) != NULL ) ? \ + mbedtls_low_level_strerr( mbedTlsCode ) : pNoLowLevelMbedTlsCodeStr + +/*-----------------------------------------------------------*/ + +/** + * @brief Initialize the MbedTLS structures in a network connection. + * + * @param[in] pContext The SSL context to initialize. + */ +static void contextInit( MbedtlsContext_t * pContext ); + +/** + * @brief Free the MbedTLS structures in a network connection. + * + * @param[in] pContext The SSL context to free. + */ +static void contextFree( MbedtlsContext_t * pContext ); + +/** + * @brief Configure MbedTLS for TLS on a TCP connection using PKCS #11 for the + * client credentials. + * + * @param[in] pMbedtlsContext Network context. + * @param[in] pHostName Remote host name, used for server name indication. + * @param[in] pMbedtlsCredentials TLS setup parameters. + * @param[in] recvTimeoutMs Receive timeout for network socket. + * + * @return #MBEDTLS_SUCCESS, #MBEDTLS_INSUFFICIENT_MEMORY, #MBEDTLS_INVALID_CREDENTIALS, + * #MBEDTLS_HANDSHAKE_FAILED, or #MBEDTLS_INTERNAL_ERROR. + */ +static MbedtlsStatus_t configureMbedtls( MbedtlsContext_t * pMbedtlsContext, + const char * pHostName, + const MbedtlsCredentials_t * pMbedtlsCredentials, + uint32_t recvTimeoutMs ); + +/** + * @brief Configure the client and Root CA in the MbedTLS SSL context. + * + * @param[in] pMbedtlsContext Network context. + * @param[in] pMbedtlsCredentials TLS setup parameters. + * + * @return #MBEDTLS_SUCCESS on success, + * #MBEDTLS_INVALID_CREDENTIALS on error. + */ +static MbedtlsStatus_t configureMbedtlsCertificates( MbedtlsContext_t * pMbedtlsContext, + const MbedtlsCredentials_t * pMbedtlsCredentials ); + +/** + * @brief Configure the SNI and ALPN in the MbedTLS SSL context. + * + * @param[in] pMbedtlsContext Network context. + * @param[in] pMbedtlsCredentials TLS setup parameters. + * @param[in] pHostName Remote host name, used for server name indication. + * + * @return #MBEDTLS_SUCCESS on success, + * #MBEDTLS_INVALID_CREDENTIALS on error. + */ +static MbedtlsStatus_t configureMbedtlsSniAlpn( MbedtlsContext_t * pMbedtlsContext, + const MbedtlsCredentials_t * pMbedtlsCredentials, + const char * pHostName ); + +/** + * @brief Configure the Maximum Fragment Length in the MbedTLS SSL context. + * + * @param[in] pMbedtlsContext Network context. + * + * @return #MBEDTLS_SUCCESS on success, + * #MBEDTLS_INVALID_CREDENTIALS on error. + */ +static MbedtlsStatus_t configureMbedtlsFragmentLength( MbedtlsContext_t * pMbedtlsContext ); + +/*-----------------------------------------------------------*/ + +static void contextInit( MbedtlsContext_t * pContext ) +{ + assert( pContext != NULL ); + psa_crypto_init(); + + mbedtls_net_init( &( pContext->socketContext ) ); + mbedtls_ssl_init( &( pContext->context ) ); + mbedtls_ssl_config_init( &( pContext->config ) ); + mbedtls_x509_crt_init( &( pContext->rootCa ) ); + mbedtls_x509_crt_init( &( pContext->clientCert ) ); + mbedtls_pk_init( &( pContext->privKey ) ); + mbedtls_entropy_init( &( pContext->entropyCtx ) ); + mbedtls_ctr_drbg_init( &( pContext->ctrDrbgCtx ) ); +} +/*-----------------------------------------------------------*/ + +static void contextFree( MbedtlsContext_t * pContext ) +{ + if( pContext != NULL ) + { + mbedtls_net_free( &( pContext->socketContext ) ); + mbedtls_ssl_free( &( pContext->context ) ); + mbedtls_ssl_config_free( &( pContext->config ) ); + mbedtls_x509_crt_free( &( pContext->rootCa ) ); + mbedtls_x509_crt_free( &( pContext->clientCert ) ); + mbedtls_pk_free( &( pContext->privKey ) ); + mbedtls_entropy_free( &( pContext->entropyCtx ) ); + mbedtls_ctr_drbg_free( &( pContext->ctrDrbgCtx ) ); + } +} + +/*-----------------------------------------------------------*/ + +static void mbedtlsDebugPrint( void * ctx, + int level, + const char * pFile, + int line, + const char * pStr ) +{ + /* Unused parameters. */ + ( void ) ctx; + ( void ) pFile; + ( void ) line; + + /* Send the debug string to the portable logger. */ + fprintf( stderr, "mbedTLS: |%d| %s", level, pStr ); +} + +/*-----------------------------------------------------------*/ + +static MbedtlsStatus_t configureMbedtls( MbedtlsContext_t * pMbedtlsContext, + const char * pHostName, + const MbedtlsCredentials_t * pMbedtlsCredentials, + uint32_t recvTimeoutMs ) +{ + MbedtlsStatus_t returnStatus = MBEDTLS_SUCCESS; + int mbedtlsError = 0; + + assert( pMbedtlsContext != NULL ); + assert( pHostName != NULL ); + assert( pMbedtlsCredentials != NULL ); + assert( pMbedtlsCredentials->pRootCaPath != NULL ); + + /* Initialize the MbedTLS context structures. */ + contextInit( pMbedtlsContext ); + + mbedtls_ctr_drbg_set_prediction_resistance( &( pMbedtlsContext->ctrDrbgCtx ), + MBEDTLS_CTR_DRBG_PR_ON ); + + mbedtlsError = mbedtls_ctr_drbg_seed( &( pMbedtlsContext->ctrDrbgCtx ), + mbedtls_entropy_func, + &( pMbedtlsContext->entropyCtx ), + NULL, + 0 ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to seed mbedtls ctr-drgb random number generator: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + + returnStatus = MBEDTLS_INTERNAL_ERROR; + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + mbedtlsError = mbedtls_ssl_config_defaults( &( pMbedtlsContext->config ), + MBEDTLS_SSL_IS_CLIENT, + MBEDTLS_SSL_TRANSPORT_STREAM, + MBEDTLS_SSL_PRESET_DEFAULT ); + + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to set default SSL configuration: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + + /* Per MbedTLS docs, mbedtls_ssl_config_defaults only fails on memory allocation. */ + returnStatus = MBEDTLS_INSUFFICIENT_MEMORY; + } + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + /* Set up the certificate security profile, starting from the default value. */ + pMbedtlsContext->certProfile = mbedtls_x509_crt_profile_default; + + /* Set SSL authmode and the RNG context. */ + mbedtls_ssl_conf_authmode( &( pMbedtlsContext->config ), + MBEDTLS_SSL_VERIFY_REQUIRED ); + + mbedtls_ssl_conf_rng( &( pMbedtlsContext->config ), + mbedtls_ctr_drbg_random, + &( pMbedtlsContext->ctrDrbgCtx ) ); + + mbedtls_ssl_conf_cert_profile( &( pMbedtlsContext->config ), + &( pMbedtlsContext->certProfile ) ); + + mbedtls_ssl_conf_read_timeout( &( pMbedtlsContext->config ), + recvTimeoutMs ); + + mbedtls_ssl_conf_handshake_timeout( &( pMbedtlsContext->config ), + 5000, 60000 ); + + mbedtls_ssl_conf_dbg( &pMbedtlsContext->config, + mbedtlsDebugPrint, + NULL ); + + mbedtls_debug_set_threshold( MBEDTLS_DEBUG_LOG_LEVEL ); + + returnStatus = configureMbedtlsCertificates( pMbedtlsContext, + pMbedtlsCredentials ); + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + returnStatus = configureMbedtlsSniAlpn( pMbedtlsContext, pMbedtlsCredentials, pHostName ); + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + /* Initialize the MbedTLS secured connection context. */ + mbedtlsError = mbedtls_ssl_setup( &( pMbedtlsContext->context ), + &( pMbedtlsContext->config ) ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to set up MbedTLS SSL context: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + returnStatus = MBEDTLS_INTERNAL_ERROR; + } + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + /* Set the underlying IO for the TLS connection. */ + mbedtls_ssl_set_bio( &( pMbedtlsContext->context ), + ( void * ) &( pMbedtlsContext->socketContext ), + mbedtls_net_send, + mbedtls_net_recv, + mbedtls_net_recv_timeout ); + + returnStatus = configureMbedtlsFragmentLength( pMbedtlsContext ); + } + + if( returnStatus != MBEDTLS_SUCCESS ) + { + contextFree( pMbedtlsContext ); + } + else + { + LogDebug( ( "Configured MbedTLS context." ) ); + } + + return returnStatus; +} + +/*-----------------------------------------------------------*/ + +static MbedtlsStatus_t configureMbedtlsCertificates( MbedtlsContext_t * pMbedtlsContext, + const MbedtlsCredentials_t * pMbedtlsCredentials ) + +{ + MbedtlsStatus_t returnStatus = MBEDTLS_SUCCESS; + int mbedtlsError = 0; + + assert( pMbedtlsContext != NULL ); + assert( pMbedtlsCredentials != NULL ); + assert( pMbedtlsCredentials->pRootCaPath != NULL ); + + /* Parse the server root CA certificate into the SSL context. */ + mbedtlsError = mbedtls_x509_crt_parse_file( &( pMbedtlsContext->rootCa ), + pMbedtlsCredentials->pRootCaPath ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to parse server root CA certificate: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + returnStatus = MBEDTLS_INVALID_CREDENTIALS; + } + else + { + mbedtls_ssl_conf_ca_chain( &( pMbedtlsContext->config ), + &( pMbedtlsContext->rootCa ), + NULL ); + + mbedtlsError = mbedtls_pk_parse_keyfile( + &( pMbedtlsContext->privKey ), + pMbedtlsCredentials->pPrivateKeyPath, + NULL, + mbedtls_ctr_drbg_random, + &( pMbedtlsContext->ctrDrbgCtx ) + ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to load private key from path %s", pMbedtlsCredentials->pPrivateKeyPath ) ); + returnStatus = MBEDTLS_INVALID_CREDENTIALS; + } + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + /* Setup the client certificate. */ + mbedtlsError = mbedtls_x509_crt_parse_file( + &( pMbedtlsContext->clientCert ), + pMbedtlsCredentials->pClientCertPath + ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to load client certificate from file: %s.", pMbedtlsCredentials->pClientCertPath ) ); + returnStatus = MBEDTLS_INVALID_CREDENTIALS; + } + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + ( void ) mbedtls_ssl_conf_own_cert( &( pMbedtlsContext->config ), + &( pMbedtlsContext->clientCert ), + &( pMbedtlsContext->privKey ) ); + } + + return returnStatus; +} + +/*-----------------------------------------------------------*/ + +static MbedtlsStatus_t configureMbedtlsSniAlpn( MbedtlsContext_t * pMbedtlsContext, + const MbedtlsCredentials_t * pMbedtlsCredentials, + const char * pHostName ) +{ + MbedtlsStatus_t returnStatus = MBEDTLS_SUCCESS; + int mbedtlsError = 0; + + assert( pMbedtlsContext != NULL ); + assert( pHostName != NULL ); + assert( pMbedtlsCredentials != NULL ); + assert( pMbedtlsCredentials->pRootCaPath != NULL ); + + if( pMbedtlsCredentials->pAlpnProtos != NULL ) + { + /* Include an application protocol list in the TLS ClientHello message. */ + mbedtlsError = mbedtls_ssl_conf_alpn_protocols( &( pMbedtlsContext->config ), + pMbedtlsCredentials->pAlpnProtos ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to configure ALPN protocol in MbedTLS: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + returnStatus = MBEDTLS_INTERNAL_ERROR; + } + } + + /* Enable SNI if requested. */ + if( ( returnStatus == MBEDTLS_SUCCESS ) && + ( pMbedtlsCredentials->disableSni == false ) ) + { + mbedtlsError = mbedtls_ssl_set_hostname( &( pMbedtlsContext->context ), + pHostName ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to set server name: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + returnStatus = MBEDTLS_INTERNAL_ERROR; + } + } + + return returnStatus; +} + +/*-----------------------------------------------------------*/ + +static MbedtlsStatus_t configureMbedtlsFragmentLength( MbedtlsContext_t * pMbedtlsContext ) +{ + MbedtlsStatus_t returnStatus = MBEDTLS_SUCCESS; + int mbedtlsError = 0; + + assert( pMbedtlsContext != NULL ); + + /* Set Maximum Fragment Length if enabled. */ + #ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH + + /* Enable the max fragment extension. 4096 bytes is currently the largest fragment size permitted. + * See RFC 6066 https://tools.ietf.org/html/rfc6066#page-8 for more information. + * + * Smaller values can be found in "mbedtls/include/ssl.h". + */ + mbedtlsError = mbedtls_ssl_conf_max_frag_len( &( pMbedtlsContext->config ), MBEDTLS_SSL_MAX_FRAG_LEN_4096 ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to maximum fragment length extension: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + returnStatus = MBEDTLS_INTERNAL_ERROR; + } + #endif /* ifdef MBEDTLS_SSL_MAX_FRAGMENT_LENGTH */ + return returnStatus; +} + +/*-----------------------------------------------------------*/ + +MbedtlsStatus_t Mbedtls_Connect( NetworkContext_t * pNetworkContext, + const char * pHostName, + uint16_t port, + const MbedtlsCredentials_t * pMbedtlsCredentials, + uint32_t recvTimeoutMs ) +{ + MbedtlsContext_t * pMbedtlsContext = NULL; + MbedtlsStatus_t returnStatus = MBEDTLS_SUCCESS; + int mbedtlsError = 0; + char portStr[ 6 ] = { 0 }; + + if( ( pNetworkContext == NULL ) || + ( pNetworkContext->pParams == NULL ) || + ( pHostName == NULL ) || + ( pMbedtlsCredentials == NULL ) || + ( pMbedtlsCredentials->pRootCaPath == NULL ) || + ( pMbedtlsCredentials->pClientCertPath == NULL ) || + ( pMbedtlsCredentials->pPrivateKeyPath == NULL ) ) + { + LogError( ( "Invalid input parameter(s): Arguments cannot be NULL. pNetworkContext=%p, " + "pHostName=%p, pMbedtlsCredentials=%p.", + ( void * ) pNetworkContext, + ( const void * ) pHostName, + ( const void * ) pMbedtlsCredentials ) ); + returnStatus = MBEDTLS_INVALID_PARAMETER; + } + else + { + snprintf( portStr, sizeof( portStr ), "%u", port ); + pMbedtlsContext = pNetworkContext->pParams; + + /* Configure MbedTLS. */ + returnStatus = configureMbedtls( pMbedtlsContext, pHostName, pMbedtlsCredentials, recvTimeoutMs ); + } + + /* Establish a TCP connection with the server. */ + if( returnStatus == MBEDTLS_SUCCESS ) + { + mbedtlsError = mbedtls_net_connect( &( pMbedtlsContext->socketContext ), + pHostName, + portStr, + MBEDTLS_NET_PROTO_TCP ); + + if( mbedtlsError != 0 ) + { + LogError( ( "Failed to connect to %s with error %d.", pHostName, mbedtlsError ) ); + returnStatus = MBEDTLS_CONNECT_FAILURE; + } + } + + if( returnStatus == MBEDTLS_SUCCESS ) + { + /* Perform the TLS handshake. */ + do + { + mbedtlsError = mbedtls_ssl_handshake( &( pMbedtlsContext->context ) ); + } while( ( mbedtlsError == MBEDTLS_ERR_SSL_WANT_READ ) || + ( mbedtlsError == MBEDTLS_ERR_SSL_WANT_WRITE ) ); + + if( ( mbedtlsError != 0 ) || ( mbedtls_ssl_get_verify_result( &( pMbedtlsContext->context ) ) != 0U ) ) + { + LogError( ( "Failed to perform TLS handshake: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( mbedtlsError ), + mbedtlsLowLevelCodeOrDefault( mbedtlsError ) ) ); + returnStatus = MBEDTLS_HANDSHAKE_FAILED; + } + } + + /* Clean up on failure. */ + if( returnStatus != MBEDTLS_SUCCESS ) + { + contextFree( pMbedtlsContext ); + } + else + { + LogInfo( ( "TLS Connection to %s established.", pHostName ) ); + } + + return returnStatus; +} + +/*-----------------------------------------------------------*/ + +void Mbedtls_Disconnect( NetworkContext_t * pNetworkContext ) +{ + MbedtlsContext_t * pMbedtlsContext = NULL; + int tlsStatus = 0; + + if( ( pNetworkContext != NULL ) && ( pNetworkContext->pParams != NULL ) ) + { + pMbedtlsContext = pNetworkContext->pParams; + /* Attempting to terminate TLS connection. */ + tlsStatus = mbedtls_ssl_close_notify( &( pMbedtlsContext->context ) ); + + if( tlsStatus == 0 ) + { + LogInfo( ( "Closing TLS connection: TLS close-notify sent." ) ); + } + else if( ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) || + ( tlsStatus == MBEDTLS_ERR_SSL_WANT_WRITE ) ) + { + /* WANT_READ or WANT_WRITE can be ignored. Logging for debugging purposes. */ + LogInfo( ( "TLS close-notify sent; " + "received %s as the TLS status which can be ignored for close-notify.", + ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) ? "WANT_READ" : "WANT_WRITE" ) ); + } + else + { + /* Ignore the WANT_READ or WANT_WRITE return values. */ + LogError( ( "Failed to send TLS close-notify: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( tlsStatus ), + mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); + } + + /* Free contexts. */ + contextFree( pMbedtlsContext ); + } +} + +/*-----------------------------------------------------------*/ + +int Mbedtls_Recv( NetworkContext_t * pNetworkContext, + void * pBuffer, + size_t bytesToRecv ) +{ + MbedtlsContext_t * pMbedtlsContext = NULL; + int tlsStatus = 0; + + assert( ( pNetworkContext != NULL ) && ( pNetworkContext->pParams != NULL ) ); + + pMbedtlsContext = pNetworkContext->pParams; + tlsStatus = ( int ) mbedtls_ssl_read( &( pMbedtlsContext->context ), + pBuffer, + bytesToRecv ); + + if( ( tlsStatus == MBEDTLS_ERR_SSL_TIMEOUT ) || + ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) || + ( tlsStatus == MBEDTLS_ERR_SSL_WANT_WRITE ) ) + { + LogDebug( ( "Failed to read data. However, a read can be retried on this error. " + "mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( tlsStatus ), + mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); + + /* Mark these set of errors as a timeout. The libraries may retry read + * on these errors. */ + tlsStatus = 0; + } + else if( tlsStatus < 0 ) + { + LogError( ( "Failed to read data: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( tlsStatus ), + mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); + } + else + { + /* Empty else marker. */ + } + + return tlsStatus; +} + +/*-----------------------------------------------------------*/ + +int Mbedtls_Send( NetworkContext_t * pNetworkContext, + const void * pBuffer, + size_t bytesToSend ) +{ + MbedtlsContext_t * pMbedtlsContext = NULL; + int tlsStatus = 0; + + assert( ( pNetworkContext != NULL ) && ( pNetworkContext->pParams != NULL ) ); + + pMbedtlsContext = pNetworkContext->pParams; + tlsStatus = ( int ) mbedtls_ssl_write( &( pMbedtlsContext->context ), + pBuffer, + bytesToSend ); + + if( ( tlsStatus == MBEDTLS_ERR_SSL_TIMEOUT ) || + ( tlsStatus == MBEDTLS_ERR_SSL_WANT_READ ) || + ( tlsStatus == MBEDTLS_ERR_SSL_WANT_WRITE ) ) + { + LogDebug( ( "Failed to send data. However, send can be retried on this error. " + "mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( tlsStatus ), + mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); + + /* Mark these set of errors as a timeout. The libraries may retry send + * on these errors. */ + tlsStatus = 0; + } + else if( tlsStatus < 0 ) + { + LogError( ( "Failed to send data: mbedTLSError= %s : %s.", + mbedtlsHighLevelCodeOrDefault( tlsStatus ), + mbedtlsLowLevelCodeOrDefault( tlsStatus ) ) ); + } + else + { + /* Empty else marker. */ + } + + return tlsStatus; +} + +/*-----------------------------------------------------------*/ + +static MbedtlsStatus_t writeKeyToFile( const char * pKeyPath, + mbedtls_pk_context * pPkCtx ) +{ + unsigned char pKeyBuffer[ 2048 ]; + MbedtlsStatus_t status = MBEDTLS_SUCCESS; + int result = 0; + + /* Serialize the private to a buffer */ + result = mbedtls_pk_write_key_pem( pPkCtx, + pKeyBuffer, + 2048 ); + + if( result < 0 ) + { + LogError( ( "Failed to serialize EC key pair: result= %s : %s.", + mbedtlsHighLevelCodeOrDefault( result ), + mbedtlsLowLevelCodeOrDefault( result ) ) ); + + status = MBEDTLS_INTERNAL_ERROR; + } + else + { + FILE * pKeyFile; + size_t pemKeyLength = strnlen( ( char * ) pKeyBuffer, 2048 ); + + pKeyFile = fopen( pKeyPath, "wb" ); + if( pKeyFile == NULL ) + { + LogError( ( "Failed to open path: %s, result: %s.", + pKeyPath, + strerror( errno ) ) ); + + status = MBEDTLS_INVALID_PARAMETER; + } + else + { + if( fwrite( pKeyBuffer, 1, pemKeyLength, pKeyFile ) != pemKeyLength ) + { + LogError( ( "Failed to write %lu bytes path: %s, result: %s.", + ( unsigned long ) pemKeyLength, + pKeyPath, + strerror( errno ) ) ); + + status = MBEDTLS_INTERNAL_ERROR; + } + + if( fclose( pKeyFile ) != 0 ) + { + LogError( ( "Failed to close file path: %s, result: %s.", + pKeyPath, + strerror( errno ) ) ); + + status = MBEDTLS_INTERNAL_ERROR; + } + } + } + memset( pKeyBuffer, 0, 128 ); + + return status; +} + +/*-----------------------------------------------------------*/ + +MbedtlsStatus_t Mbedtls_GenerateECKey( const char * pPrivateKeyPath ) +{ + MbedtlsStatus_t status = MBEDTLS_SUCCESS; + mbedtls_entropy_context entropyCtx; + mbedtls_ctr_drbg_context ctrDrbgCtx; + mbedtls_pk_context pkCtx; + int result = 0; + + assert( pPrivateKeyPath != NULL ); + // assert( access( pPrivateKeyPath, W_OK ) == 0 ); + + /* Initialize mbedtls entropy, prng, and pk contexts */ + mbedtls_entropy_init( &entropyCtx ); + mbedtls_ctr_drbg_init( &ctrDrbgCtx ); + mbedtls_pk_init( &pkCtx ); + + /* Seed the CTR-DRBG Pesudo Random Number Generator */ + mbedtls_ctr_drbg_set_prediction_resistance( &ctrDrbgCtx, MBEDTLS_CTR_DRBG_PR_ON ); + result = mbedtls_ctr_drbg_seed( &ctrDrbgCtx, + mbedtls_entropy_func, + &entropyCtx, + NULL, + 0 ); + if( result != 0 ) + { + LogError( ( "Failed to seed CTR-DRBG: result= %s : %s.", + mbedtlsHighLevelCodeOrDefault( result ), + mbedtlsLowLevelCodeOrDefault( result ) ) ); + status = MBEDTLS_INTERNAL_ERROR; + } + + if( status == MBEDTLS_SUCCESS ) + { + /* Setup / allocate the mbedtls PK context */ + result = mbedtls_pk_setup( &pkCtx, + mbedtls_pk_info_from_type( MBEDTLS_PK_ECKEY ) ); + + if( result != 0 ) + { + LogError( ( "Failed to setup mbedtls pk context: result= %s : %s.", + mbedtlsHighLevelCodeOrDefault( result ), + mbedtlsLowLevelCodeOrDefault( result ) ) ); + status = MBEDTLS_INTERNAL_ERROR; + } + } + + if( status == MBEDTLS_SUCCESS ) + { + /* Generate a new ECP key pair */ + result = mbedtls_ecp_gen_key( MBEDTLS_ECP_DP_SECP256R1, + mbedtls_pk_ec( pkCtx ), + mbedtls_ctr_drbg_random, + &ctrDrbgCtx ); + + if( result != 0 ) + { + LogError( ( "Failed to generate an EC key: result= %s : %s.", + mbedtlsHighLevelCodeOrDefault( result ), + mbedtlsLowLevelCodeOrDefault( result ) ) ); + status = MBEDTLS_INTERNAL_ERROR; + } + } + + if( status == MBEDTLS_SUCCESS ) + { + status = writeKeyToFile( pPrivateKeyPath, &pkCtx ); + } + + mbedtls_pk_free( &pkCtx ); + mbedtls_ctr_drbg_free( &ctrDrbgCtx ); + mbedtls_entropy_free( &entropyCtx ); + + return status; +} + +/*-----------------------------------------------------------*/ + +MbedtlsStatus_t Mbedtls_GenerateCSR( const char * pPrivateKeyPath, + char * pCsrPemBuffer, + size_t csrPemBufferLength ) +{ + MbedtlsStatus_t status = MBEDTLS_SUCCESS; + mbedtls_entropy_context entropyCtx; + mbedtls_ctr_drbg_context ctrDrbgCtx; + mbedtls_pk_context pkCtx; + mbedtls_x509write_csr csrCtx; + int result = 0; + + if( pPrivateKeyPath == NULL || pCsrPemBuffer == NULL ) + { + return MBEDTLS_INVALID_PARAMETER; + } + + /* Initialize mbedtls entropy, prng, pk, and csr contexts */ + mbedtls_entropy_init( &entropyCtx ); + mbedtls_ctr_drbg_init( &ctrDrbgCtx ); + mbedtls_pk_init( &pkCtx ); + mbedtls_x509write_csr_init( &csrCtx ); + + /* Seed the CTR-DRBG Pesudo Random Number Generator */ + mbedtls_ctr_drbg_set_prediction_resistance( &ctrDrbgCtx, MBEDTLS_CTR_DRBG_PR_ON ); + result = mbedtls_ctr_drbg_seed( &ctrDrbgCtx, + mbedtls_entropy_func, + &entropyCtx, + NULL, + 0 ); + if( result != 0 ) + { + LogError( ( "Failed to seed CTR-DRBG: result= %s : %s.", + mbedtlsHighLevelCodeOrDefault( result ), + mbedtlsLowLevelCodeOrDefault( result ) ) ); + status = MBEDTLS_INTERNAL_ERROR; + } + + if( status == MBEDTLS_SUCCESS ) + { + /* Load private key from file */ + result = mbedtls_pk_parse_keyfile( &pkCtx, + pPrivateKeyPath, + NULL, + mbedtls_ctr_drbg_random, + &ctrDrbgCtx ); + + if( result != 0 ) + { + LogError( ( "Failed to read key from file: %s, result= %s : %s.", + pPrivateKeyPath, + mbedtlsHighLevelCodeOrDefault( result ), + mbedtlsLowLevelCodeOrDefault( result ) ) ); + status = MBEDTLS_INTERNAL_ERROR; + } + } + + if( status == MBEDTLS_SUCCESS ) + { + /* Create CSR */ + mbedtls_x509write_csr_set_md_alg( &csrCtx, MBEDTLS_MD_SHA256 ); + mbedtls_x509write_csr_set_key( &csrCtx, &pkCtx ); + + result = mbedtls_x509write_csr_set_key_usage( &csrCtx, MBEDTLS_X509_KU_DIGITAL_SIGNATURE ); + + if( result == 0 ) + { + result = mbedtls_x509write_csr_set_ns_cert_type( &csrCtx, MBEDTLS_X509_NS_CERT_TYPE_SSL_CLIENT ); + } + + if( result == 0 ) + { + //TODO: Set this to device serial number / thing name + result = mbedtls_x509write_csr_set_subject_name( &csrCtx, "CN=MyDevice" ); + } + + if( result == 0 ) + { + result = mbedtls_x509write_csr_pem( &csrCtx, + ( unsigned char * ) pCsrPemBuffer, + csrPemBufferLength, + mbedtls_ctr_drbg_random, + &ctrDrbgCtx ); + } + + if( result < 0 ) + { + LogError( ( "Failed to generate CSR. result= %s : %s.", + mbedtlsHighLevelCodeOrDefault( result ), + mbedtlsLowLevelCodeOrDefault( result ) ) ); + status = MBEDTLS_INTERNAL_ERROR; + } + } + + mbedtls_x509write_csr_free( &csrCtx ); + mbedtls_pk_free( &pkCtx ); + mbedtls_ctr_drbg_free( &ctrDrbgCtx ); + mbedtls_entropy_free( &entropyCtx ); + + return status; +} + +/*-----------------------------------------------------------*/ + + diff --git a/tools/cmake/install.cmake b/tools/cmake/install.cmake index 157ebe8842..bbea2e38b8 100644 --- a/tools/cmake/install.cmake +++ b/tools/cmake/install.cmake @@ -9,7 +9,6 @@ set(FILEPATH_LOCATIONS ${MODULES_DIR}/standard/coreHTTP/httpFilePaths.cmake ${MODULES_DIR}/standard/coreJSON/jsonFilePaths.cmake ${MODULES_DIR}/standard/coreMQTT/mqttFilePaths.cmake - ${MODULES_DIR}/standard/corePKCS11/pkcsFilePaths.cmake ${PLATFORM_DIR}/posix/posixFilePaths.cmake ) @@ -30,23 +29,11 @@ set(LIBRARY_PREFIXES "OTA_MQTT" "BACKOFF_ALGORITHM" "HTTP" - "MQTT" - "PKCS") - -set(COREPKCS11_LOCATION "${MODULES_DIR}/standard/corePKCS11") -set(CORE_PKCS11_3RDPARTY_LOCATION "${COREPKCS11_LOCATION}/source/dependency/3rdparty") + "MQTT") # Define any extra sources or includes outside the standard, making sure to use the same prefix. set(MQTT_EXTRA_SOURCES ${MQTT_SERIALIZER_SOURCES}) -set(PKCS_EXTRA_SOURCES - "${COREPKCS11_LOCATION}/source/portable/os/posix/core_pkcs11_pal.c" - "${COREPKCS11_LOCATION}/source/portable/os/core_pkcs11_pal_utils.c" - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils/mbedtls_utils.c") -set(PKCS_EXTRA_INCLUDE_PRIVATE_DIRS - PRIVATE - "${CORE_PKCS11_3RDPARTY_LOCATION}/mbedtls_utils" - "${COREPKCS11_LOCATION}/source/portable/os") set(OTA_BACKENDS "OTA_HTTP" "OTA_MQTT") foreach(ota_backend ${OTA_BACKENDS}) set("${ota_backend}_EXTRA_INCLUDE_PUBLIC_DIRS" @@ -106,13 +93,6 @@ foreach(library_prefix ${LIBRARY_PREFIXES}) PRIVATE ${${config_prefix}_CUSTOM_CONFIG_DIR}) else() target_compile_definitions("${library_name}" PRIVATE -D${config_prefix}_DO_NOT_USE_CUSTOM_CONFIG) - # PKCS11 requires a config so include the one from the demos by default. - if(${config_prefix} STREQUAL "PKCS") - target_include_directories("${library_name}" PRIVATE - ${DEMOS_DIR}/pkcs11/common/include - ${LOGGING_INCLUDE_DIRS}) - target_link_libraries("${library_name}" PRIVATE mbedtls ) - endif() endif() # Add public include directories to library target.