|
| 1 | +# PKCS #11 Test |
| 2 | + |
| 3 | +## On this page: |
| 4 | +1. [Introduction](#1-introduction) |
| 5 | +2. [Prerequisites For PKCS #11 Test](#2-prerequisites-for-pkcs-11-test) |
| 6 | +3. [PKCS #11 Test Configurations](#3-pkcs-11-test-configurations) |
| 7 | +4. [Source Code Organization](#4-source-code-organization) |
| 8 | +5. [Implement PKCS #11 Test Application](#5-implement-pkcs-11-test-application) |
| 9 | +6. [Run The PKCS #11 Test](#6-run-the-pkcs-11-test)<br> |
| 10 | +</t>6.1 [Setup the provisioning mechanism and key function](#61-setup-the-provisioning-mechanism-and-key-function)<br> |
| 11 | +</t>6.2 [Compile and run the PKCS #11 test application](#62-compile-and-run-the-pkcs-11-test-application)<br> |
| 12 | + |
| 13 | +## 1. Introduction |
| 14 | +[PKCS #11 ](https://en.wikipedia.org/wiki/PKCS_11) is a standardize API to allow application software to use, create, modify and delete cryptographic objects. |
| 15 | +The benefit of PKCS #11 is that it allows the app to take advantage of offload crypto while mitigating the threats of private key cloning and theft. |
| 16 | + |
| 17 | +To keep as lean as possible, FreeRTOS uses a subset of PKCS #11 APIs. Implementers are free to integrate more than our required subset of PKCS #11, but it is optional to do so. |
| 18 | + |
| 19 | +The PKCS #11 API functions required by FreeRTOS are described in the following table. |
| 20 | + |
| 21 | +FreeRTOS Library | Required PKCS #11 API Family |
| 22 | +----------------------- | ---------------------------- |
| 23 | +Any | Initialize, Finalize, Open/Close Session, GetSlotList, Login |
| 24 | +Provisioning Demo | GenerateKeyPair, CreateObject, DestroyObject, InitToken, GetTokenInfo |
| 25 | +TLS | Random, Sign, FindObject, GetAttributeValue |
| 26 | +FreeRTOS+TCP | Random, Digest |
| 27 | +OTA | Verify, Digest, FindObject, GetAttributeValue |
| 28 | + |
| 29 | +The PKCS #11 test validates the PKCS #11 subset implementation. The test directly exercises the PKCS #11 implementation on the device under testing. User runs the PKCS #11 test by running a test application. The test application is usually implemented by calling the provided PKCS #11 test routine from the main function. By passing this test, the PKCS #11 subset implementation is validated to support required PKCS #11 functions by FreeRTOS. |
| 30 | + |
| 31 | +The PKCS #11 interface is defined in the open-standard documentation available here http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/os/pkcs11-base-v2.40-os.html. |
| 32 | + |
| 33 | +## 2. Prerequisites For PKCS #11 Test |
| 34 | +The PKCS #11 tests assume the tested platform already has the following components integrated. |
| 35 | +* **The PKCS #11 APIs subset implementation**<br> |
| 36 | + The implementation should support the APIs list in this [section](#1-introduction). |
| 37 | +* **corePKCS11**<br> |
| 38 | + The utilities in corePKCS #11 are used in PKCS #11 test. corePKCS11 library provides software based implementation. Developers can implement the required PKCS #11 APIs using hardware crypto features of their board. The PKCS #11 Test does not mandate specific implementation. |
| 39 | +* **MbedTLS**<br> |
| 40 | + MbedTLS is required to verify the result of the PKCS #11 implementation. |
| 41 | +* **Unity test framework**<br> |
| 42 | + PKCS #11 test make use of the Unity test framework. Reference the [website](https://github.com/ThrowTheSwitch/Unity) for integration guide. |
| 43 | + |
| 44 | +## 3. PKCS #11 Test Configurations |
| 45 | + |
| 46 | +The following table lists the required test configurations for PKCS #11 tests. These test configurations need to be defined in **test_param_config.h**. |
| 47 | + |
| 48 | +|Configuration |Description | |
| 49 | +|--- | --- | |
| 50 | +|PKCS11_TEST_RSA_KEY_SUPPORT |The porting supports RSA key functions. | |
| 51 | +|PKCS11_TEST_EC_KEY_SUPPORT |The porting supports EC key functions. | |
| 52 | +|PKCS11_TEST_IMPORT_PRIVATE_KEY_SUPPORT |The porting supports import private key. RSA and EC key import will be validated in the test if the corresponding key functions are enabled. | |
| 53 | +|PKCS11_TEST_GENERATE_KEYPAIR_SUPPORT |The porting supports keypair generation. EC keypair generation will be validated in the test if the corresponding key functions are enabled. | |
| 54 | +|PKCS11_TEST_PREPROVISIONED_SUPPORT |The porting has pre-provisioned credentials. These test labels, PKCS11_TEST_LABEL_DEVICE_PRIVATE_KEY_FOR_TLS, PKCS11_TEST_LABEL_DEVICE_PUBLIC_KEY_FOR_TLS and PKCS11_TEST_LABEL_DEVICE_CERTIFICATE_FOR_TLS, are the labels of the pre-provisioned credentials. | |
| 55 | +|PKCS11_TEST_LABEL_DEVICE_PRIVATE_KEY_FOR_TLS |The label of the private key used in the test. | |
| 56 | +|PKCS11_TEST_LABEL_DEVICE_PUBLIC_KEY_FOR_TLS |The label of the public key used in the test. | |
| 57 | +|PKCS11_TEST_LABEL_DEVICE_CERTIFICATE_FOR_TLS |The label of the certificate used in the test. | |
| 58 | +|PKCS11_TEST_JITP_CODEVERIFY_ROOT_CERT_SUPPORTED |The porting supports storage for JITP. Set 1 to enable the JITP codeverify test. | |
| 59 | +|PKCS11_TEST_LABEL_CODE_VERIFICATION_KEY |The label of the code verification key used in JITP codeverify test. | |
| 60 | +|PKCS11_TEST_LABEL_JITP_CERTIFICATE |The label of the JITP certificate used in JITP codeverify test. | |
| 61 | +|PKCS11_TEST_LABEL_ROOT_CERTIFICATE |The label of the root certificate used in JITP codeverify test. | |
| 62 | + |
| 63 | + |
| 64 | +FreeRTOS libraries and reference integrations needs at least one of the key function and one of the key provisioning mechanism supported by the PKCS #11 APIs. The test must enable at least one of the following configurations: |
| 65 | + |
| 66 | +* At least one of the key function configurations: |
| 67 | + * PKCS11_TEST_RSA_KEY_SUPPORT |
| 68 | + * PKCS11_TEST_EC_KEY_SUPPORT |
| 69 | +* At least one of the key provisioning mechanisms: |
| 70 | + * PKCS11_TEST_IMPORT_PRIVATE_KEY_SUPPORT |
| 71 | + * PKCS11_TEST_GENERATE_KEYPAIR_SUPPORT |
| 72 | + * PKCS11_TEST_PREPROVISIONED_SUPPORT |
| 73 | + |
| 74 | + |
| 75 | +Pre-provisioned device credential test can not be enabled with other provisioning mechanisms. It must be run in the following conditions: |
| 76 | + |
| 77 | +* Enable **PKCS11_TEST_PREPROVISIONED_SUPPORT** and the other provisioning mechanisms must be disabled |
| 78 | +* Only one of the key function, **PKCS11_TEST_RSA_KEY_SUPPORT** or **PKCS11_TEST_EC_KEY_SUPPORT**, enabled |
| 79 | +* Setup the pre-provisioned key labels according to your key function, including **PKCS11_TEST_LABEL_DEVICE_PRIVATE_KEY_FOR_TLS**, **PKCS11_TEST_LABEL_DEVICE_PUBLIC_KEY_FOR_TLS** and **PKCS11_TEST_LABEL_DEVICE_CERTIFICATE_FOR_TLS**. These credentials must exist in the PKCS #11 before running the test. |
| 80 | + |
| 81 | +You may need to run the test several times with different configurations if your implementation support pre-provisioned credentials and other provisioning mechanisms. |
| 82 | + |
| 83 | + |
| 84 | +>Note: |
| 85 | +Objects with label **PKCS11_TEST_LABEL_DEVICE_PRIVATE_KEY_FOR_TLS**, **PKCS11_TEST_LABEL_DEVICE_PUBLIC_KEY_FOR_TLS** and **PKCS11_TEST_LABEL_DEVICE_CERTIFICATE_FOR_TLS** will be destroyed during the test if any one of **PKCS11_TEST_GENERATE_KEYPAIR_SUPPORT** and **PKCS11_TEST_GENERATE_KEYPAIR_SUPPORT** is enabled. |
| 86 | + |
| 87 | +## 4. Source Code Organization |
| 88 | +The tree only lists the required files to run the PKCS #11 test. |
| 89 | +``` |
| 90 | +./FreeRTOS-Libraries-Integration-Tests/ |
| 91 | +├── config_template |
| 92 | +│ ├── test_execution_config_template.h |
| 93 | +│ └── test_param_config_template.h |
| 94 | +└── src |
| 95 | + ├── common |
| 96 | + │ └── platform_function.h |
| 97 | + ├── pkcs11 |
| 98 | + │ ├── core_pkcs11_test.c |
| 99 | + │ ├── core_pkcs11_test.h |
| 100 | + │ ├── ecdsa_test_credentials.h |
| 101 | + │ ├── rsa_test_credentials.h |
| 102 | + │ └── dev_mode_key_provisioning |
| 103 | + │ ├── dev_mode_key_provisioning.c |
| 104 | + │ └── dev_mode_key_provisioning.h |
| 105 | + ├── qualification_test.c |
| 106 | + └── qualification_test.h |
| 107 | +``` |
| 108 | + |
| 109 | +## 5. Implement PKCS #11 Test Application |
| 110 | +1. Add [FreeRTOS-Libraries-Integration-Tests](https://github.com/FreeRTOS/FreeRTOS-Libraries-Integration-Tests) as a submodule into your project. It doesn’t matter where the submodule is placed in the project, as long as it can be built. |
| 111 | +2. Copy **config_template/test_execution_config_template.h** and **config_template/test_param_config_template.h** to a project location in the build path, and rename them to **test_execution_config.h** and **test_param_config.h**. |
| 112 | +3. Include relevant files into the build system. If using CMake, **qualification_test.cmake** and **src/pkcs11_test.cmake** can be used to include relevant files. |
| 113 | +4. Implement the [platform functions](https://github.com/FreeRTOS/FreeRTOS-Libraries-Integration-Tests/blob/main/src/common/platform_function.h) required by PKCS #11 tests. |
| 114 | +5. Enable the PKCS #11 test config, **PKCS11_TEST_ENABLED**, in **test_execution_config.h**. |
| 115 | +6. Implement the main function and call the **RunQualificationTest**. |
| 116 | + |
| 117 | +The following is an example test application. |
| 118 | + |
| 119 | +```C |
| 120 | +#include "platform_function.h" |
| 121 | +#include "qualification_test.h" |
| 122 | + |
| 123 | +FRTestThreadHandle_t FRTest_ThreadCreate( FRTestThreadFunction_t threadFunc, void * pParam ) |
| 124 | +{ |
| 125 | + /* Thread create function for multithreaded test. */ |
| 126 | +} |
| 127 | + |
| 128 | +int FRTest_ThreadTimedJoin( FRTestThreadHandle_t threadHandle, uint32_t timeoutMs ) |
| 129 | +{ |
| 130 | + /* Thread timed wait function for multithreaded test. */ |
| 131 | +} |
| 132 | +void * FRTest_MemoryAlloc( size_t size ) |
| 133 | +{ |
| 134 | + /* Malloc function to allocate memory for test. */ |
| 135 | +} |
| 136 | + |
| 137 | +void FRTest_MemoryFree( void * ptr ) |
| 138 | +{ |
| 139 | + /* Free function to free memory allocated by FRTest_MemoryAlloc function. */ |
| 140 | +} |
| 141 | + |
| 142 | +void yourMainFunction( void ) |
| 143 | +{ |
| 144 | + RunQualificationTest(); |
| 145 | +} |
| 146 | + |
| 147 | +``` |
| 148 | +
|
| 149 | +## 6. Run The PKCS #11 Test |
| 150 | +### 6.1 Setup the provisioning mechanism and key function |
| 151 | +Setup the provisioning mechanism and key function in **test_param_config.h** according to the device capability. |
| 152 | +The following is a sample test_param_config.h if corePKCS11 is used for the PKCS #11 implementation. |
| 153 | +```C |
| 154 | +#include "core_pkcs11_config.h" |
| 155 | +
|
| 156 | +/* Setup key function. */ |
| 157 | +#define PKCS11_TEST_RSA_KEY_SUPPORT ( 1 ) |
| 158 | +#define PKCS11_TEST_EC_KEY_SUPPORT ( 1 ) |
| 159 | +
|
| 160 | +/* Setup provisioning method. */ |
| 161 | +#define PKCS11_TEST_IMPORT_PRIVATE_KEY_SUPPORT ( 1 ) |
| 162 | +#define PKCS11_TEST_GENERATE_KEYPAIR_SUPPORT ( 1 ) |
| 163 | +#define PKCS11_TEST_PREPROVISIONED_SUPPORT ( 0 ) |
| 164 | +
|
| 165 | +/* The device credential labels. */ |
| 166 | +#define PKCS11_TEST_LABEL_DEVICE_PRIVATE_KEY_FOR_TLS pkcs11configLABEL_DEVICE_PRIVATE_KEY_FOR_TLS |
| 167 | +#define PKCS11_TEST_LABEL_DEVICE_PUBLIC_KEY_FOR_TLS pkcs11configLABEL_DEVICE_PUBLIC_KEY_FOR_TLS |
| 168 | +#define PKCS11_TEST_LABEL_DEVICE_CERTIFICATE_FOR_TLS pkcs11configLABEL_DEVICE_CERTIFICATE_FOR_TLS |
| 169 | +
|
| 170 | +/* JITP credential labels. */ |
| 171 | +#define PKCS11_TEST_JITP_CODEVERIFY_ROOT_CERT_SUPPORTED pkcs11configJITP_CODEVERIFY_ROOT_CERT_SUPPORTED |
| 172 | +#define PKCS11_TEST_LABEL_CODE_VERIFICATION_KEY pkcs11configLABEL_CODE_VERIFICATION_KEY |
| 173 | +#define PKCS11_TEST_LABEL_JITP_CERTIFICATE pkcs11configLABEL_JITP_CERTIFICATE |
| 174 | +#define PKCS11_TEST_LABEL_ROOT_CERTIFICATE pkcs11configLABEL_ROOT_CERTIFICATE |
| 175 | +``` |
| 176 | + |
| 177 | +### 6.2 Compile and run the PKCS #11 test application |
| 178 | +Compile and run the test application in your development environment. |
| 179 | +The following is a sample test result log: |
| 180 | +``` |
| 181 | +TEST(Full_PKCS11_StartFinish, PKCS11_StartFinish_FirstTest) PASS |
| 182 | +TEST(Full_PKCS11_StartFinish, PKCS11_GetFunctionList) PASS |
| 183 | +TEST(Full_PKCS11_StartFinish, PKCS11_InitializeFinalize) PASS |
| 184 | +TEST(Full_PKCS11_StartFinish, PKCS11_GetSlotList) PASS |
| 185 | +TEST(Full_PKCS11_StartFinish, PKCS11_OpenSessionCloseSession) PASS |
| 186 | +TEST(Full_PKCS11_Capabilities, PKCS11_Capabilities) PASS |
| 187 | +TEST(Full_PKCS11_NoObject, PKCS11_Digest) PASS |
| 188 | +TEST(Full_PKCS11_NoObject, PKCS11_Digest_ErrorConditions) PASS |
| 189 | +TEST(Full_PKCS11_NoObject, PKCS11_GenerateRandom) PASS |
| 190 | +TEST(Full_PKCS11_NoObject, PKCS11_GenerateRandomMultiThread) PASS |
| 191 | +TEST(Full_PKCS11_RSA, PKCS11_RSA_CreateObject) PASS |
| 192 | +TEST(Full_PKCS11_RSA, PKCS11_RSA_FindObject) PASS |
| 193 | +TEST(Full_PKCS11_RSA, PKCS11_RSA_GetAttributeValue) PASS |
| 194 | +TEST(Full_PKCS11_RSA, PKCS11_RSA_Sign) PASS |
| 195 | +TEST(Full_PKCS11_RSA, PKCS11_RSA_FindObjectMultiThread) PASS |
| 196 | +TEST(Full_PKCS11_RSA, PKCS11_RSA_GetAttributeValueMultiThread) PASS |
| 197 | +TEST(Full_PKCS11_RSA, PKCS11_RSA_DestroyObject) PASS |
| 198 | +TEST(Full_PKCS11_EC, PKCS11_EC_GenerateKeyPair) PASS |
| 199 | +TEST(Full_PKCS11_EC, PKCS11_EC_CreateObject) PASS |
| 200 | +TEST(Full_PKCS11_EC, PKCS11_EC_FindObject) PASS |
| 201 | +TEST(Full_PKCS11_EC, PKCS11_EC_GetAttributeValue) PASS |
| 202 | +TEST(Full_PKCS11_EC, PKCS11_EC_Sign) PASS |
| 203 | +TEST(Full_PKCS11_EC, PKCS11_EC_Verify) PASS |
| 204 | +TEST(Full_PKCS11_EC, PKCS11_EC_FindObjectMultiThread) PASS |
| 205 | +TEST(Full_PKCS11_EC, PKCS11_EC_GetAttributeValueMultiThread) PASS |
| 206 | +TEST(Full_PKCS11_EC, PKCS11_EC_SignVerifyMultiThread) PASS |
| 207 | +TEST(Full_PKCS11_EC, PKCS11_EC_DestroyObject) PASS |
| 208 | +
|
| 209 | +----------------------- |
| 210 | +27 Tests 0 Failures 0 Ignored |
| 211 | +OK |
| 212 | +
|
| 213 | +``` |
| 214 | + |
| 215 | + |
0 commit comments