leo hendrickson / Mbed OS example-Ethernet-mbed-Cloud-connect
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_rot_test.c Source File

pal_rot_test.c

00001 // ----------------------------------------------------------------------------
00002 // Copyright 2016-2019 ARM Ltd.
00003 //
00004 // SPDX-License-Identifier: Apache-2.0
00005 //
00006 // Licensed under the Apache License, Version 2.0 (the "License");
00007 // you may not use this file except in compliance with the License.
00008 // You may obtain a copy of the License at
00009 //
00010 //     http://www.apache.org/licenses/LICENSE-2.0
00011 //
00012 // Unless required by applicable law or agreed to in writing, software
00013 // distributed under the License is distributed on an "AS IS" BASIS,
00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015 // See the License for the specific language governing permissions and
00016 // limitations under the License.
00017 // ----------------------------------------------------------------------------
00018 
00019 #include "pal.h"
00020 #include "unity.h"
00021 #include "unity_fixture.h"
00022 #include "pal_plat_rot.h"
00023 #include "pal_sst.h"
00024 #include <string.h>
00025 #include <stdlib.h>
00026 #ifdef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00027 #include "pal_sst.h"
00028 #else
00029 #include "sotp.h"
00030 #endif
00031 
00032 #define TRACE_GROUP "PAL"
00033 
00034 TEST_GROUP(pal_rot);
00035 
00036 
00037 TEST_SETUP(pal_rot)
00038 {
00039     palStatus_t status = PAL_SUCCESS;
00040 
00041     //init pal
00042     status = pal_init();
00043     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00044 // reset storage before each tests to avoid possible RoT leftovers
00045 #ifdef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00046     pal_SSTReset ();
00047 #if !PAL_USE_HW_TRNG
00048     // If no hardware trng - entropy must be injected for random to work
00049     uint8_t entropy_buf[48] = { 0 };
00050     status = pal_osEntropyInject(entropy_buf, sizeof(entropy_buf));
00051     TEST_ASSERT(status == PAL_SUCCESS || status == PAL_ERR_ENTROPY_EXISTS);
00052 #endif
00053 
00054 #else
00055     sotp_reset();
00056 #endif //MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00057 }
00058 
00059 TEST_TEAR_DOWN(pal_rot)
00060 {
00061 
00062 #ifdef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00063     pal_SSTReset ();
00064 #else
00065     sotp_reset();
00066 #endif //MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00067 
00068     pal_destroy();
00069 }
00070 
00071 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm.
00072  *
00073  * 
00074  *
00075 * | # |    Step                                                                        |   Expected  |
00076 * |---|--------------------------------------------------------------------------------|-------------|
00077 * | 1 | Start a loop to perform the following steps.                                   |             |
00078 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`.                 | PAL_SUCCESS |
00079 * | 3 | Derive a device key for signing using `pal_osGetDeviceKey`.                    | PAL_SUCCESS |
00080 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE |
00081 * | 5 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE |
00082 * | 6 | Check that the derived signing and encryption keys are different.              | PAL_SUCCESS |
00083 * | 7 | Check that all integrations of each type of derivation return the same value.  | PAL_SUCCESS |
00084  */
00085 TEST(pal_rot, GetDeviceKeyTest_CMAC)
00086 {
00087 
00088 #ifndef  MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00089 
00090     palStatus_t status = PAL_SUCCESS;
00091     size_t keyLenBytes = 16;
00092     uint8_t timesToDerive = 4;
00093     unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00094     unsigned char signKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00095     /*#1*/
00096     for (int i=0; i < timesToDerive; i++)
00097     {
00098         /*#2*/
00099         status = pal_osGetDeviceKey(palOsStorageEncryptionKey128Bit, encKeyDerive[i], keyLenBytes);
00100         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00101         /*#3*/
00102         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  signKeyDerive[i], keyLenBytes);
00103         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00104         /*#4*/
00105         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  signKeyDerive[i], keyLenBytes-1);
00106         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00107         /*#5*/
00108         status = pal_osGetDeviceKey(palOsStorageSignatureKey128Bit ,  NULL, keyLenBytes);
00109         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00110         /*#6*/
00111         status = memcmp(encKeyDerive[i], signKeyDerive[i], keyLenBytes);
00112         TEST_ASSERT_NOT_EQUAL(status,0); //The keys MUST be different!
00113         /*#7*/
00114         if (i > 0) //Make sure key derivation is persistent every time
00115         {
00116             TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes);
00117             TEST_ASSERT_EQUAL_MEMORY(signKeyDerive[i-1], signKeyDerive[i], keyLenBytes);
00118 
00119         } //if
00120 
00121     } //for
00122 
00123 #else // MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00124     TEST_IGNORE_MESSAGE("Ignored, MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT is set ");
00125 #endif
00126 
00127 }
00128 
00129 /*! \brief Check derivation of keys from the platform's Root of Trust using the KDF algorithm.
00130  *
00131  * 
00132  *
00133 * | # |    Step                                                                        | Expected            |
00134 * |---|--------------------------------------------------------------------------------|---------------------|
00135 * | 1 | Start a loop to perform the following steps.                                   |                     |
00136 * | 2 | Derive a device key for encryption using `pal_osGetDeviceKey`.                 | PAL_SUCCESS         |
00137 * | 3 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE         |
00138 * | 4 | Call `pal_osGetDeviceKey` with invalid arguments.                              | PAL_FAILURE         |
00139 * | 5 | Check that all integrations of each type of derivation return the same value.  | PAL_SUCCESS         |
00140 * | 6 | Call `pal_osGetDeviceKey` with invalid palDevKeyType_t.                        | PAL_ERR_INVALID_ARGUMENT |
00141  */
00142 
00143 TEST(pal_rot, GetDeviceKeyTest_HMAC_SHA256)
00144 {
00145 
00146 #ifndef  MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00147 
00148     palStatus_t status = PAL_SUCCESS;
00149     size_t keyLenBytes = 32;
00150     uint8_t timesToDerive = 4;
00151     unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //32 bytes=256bit
00152     /*#1*/
00153     for (int i = 0; i < timesToDerive; i++)
00154     {
00155         /*#2*/
00156         status = pal_osGetDeviceKey(palOsStorageHmacSha256 , encKeyDerive[i], keyLenBytes);
00157         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00158 #ifdef DEBUG
00159         /*#3*/
00160         status = pal_osGetDeviceKey(palOsStorageHmacSha256 ,  encKeyDerive[i], keyLenBytes-1);
00161 
00162         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00163         /*#4*/
00164         status = pal_osGetDeviceKey(palOsStorageHmacSha256 ,  NULL, keyLenBytes);
00165         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00166 #endif
00167         /*#5*/
00168         if (i > 0) //Make sure key derivation is persistent every time
00169         {
00170             TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i-1], encKeyDerive[i], keyLenBytes);
00171         } //if
00172 
00173     } //for
00174 
00175 #ifdef DEBUG
00176       /*#6*/
00177     status = pal_osGetDeviceKey((palDevKeyType_t)999, encKeyDerive[0], keyLenBytes);
00178     TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status);
00179 #endif
00180 
00181 #else // MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00182     TEST_IGNORE_MESSAGE("Ignored, MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT is set ");
00183 #endif
00184 }
00185 
00186 
00187 /*! \brief Check rot key from the platform's Root of Trust.
00188 *
00189 *
00190 *
00191 * | # |    Step                                                                        | Expected            |
00192 * |---|--------------------------------------------------------------------------------|---------------------|
00193 * | 1 | Start a loop to perform the following steps.                                   |                     |
00194 * | 2 | Get ROT  key  using `pal_plat_osGetRoT`.                                       | PAL_SUCCESS |
00195 * | 3 | Get ROT  key  using `pal_plat_osGetRoT`.                                       | PAL_SUCCESS |
00196 * | 4 | Get ROT  key  using `pal_plat_osGetRoT` with wrong size.                       | PAL_FAILURE |
00197 * | 5 | Get ROT  key  using `pal_plat_osGetRoT` with null pointer buffer.              | PAL_FAILURE |
00198 * | 6 | Check that both buffers from 2 and 3 are the same                              | PAL_SUCCESS |
00199 * | 7 | Check that all integrations return the same value.                             | PAL_SUCCESS |
00200 */
00201 TEST(pal_rot, GetRoTKeyTest)
00202 {
00203 
00204 #ifdef MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00205 
00206     palStatus_t status = PAL_SUCCESS;
00207     size_t keyLenBytes = 16;
00208     uint8_t timesToDerive = 4;
00209     unsigned char encKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00210     unsigned char signKeyDerive[timesToDerive][keyLenBytes]; //16 bytes=128bit
00211     char *data_vector = "data_vector";
00212 
00213     //Set data with confidentiality flag, this operation will initiate generation of RoT on platforms that support TRNG.
00214     status =   pal_SSTSet ("test_data", data_vector, strlen(data_vector), PAL_SST_CONFIDENTIALITY_FLAG);
00215     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00216                                                              /*#1*/
00217     for (int i = 0; i < timesToDerive; i++)
00218     {
00219 
00220         /*#2*/
00221         status = pal_plat_osGetRoT(encKeyDerive[i], keyLenBytes);
00222         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00223         /*#3*/
00224         status = pal_plat_osGetRoT(signKeyDerive[i], keyLenBytes);
00225         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00226         /*#4*/
00227         status = pal_plat_osGetRoT(signKeyDerive[i], keyLenBytes - 1);
00228         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00229         /*#5*/
00230         status = pal_plat_osGetRoT(NULL, keyLenBytes);
00231         TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, status);
00232         /*#6*/
00233         status = memcmp(encKeyDerive[i], signKeyDerive[i], keyLenBytes);
00234         TEST_ASSERT_EQUAL(status, 0); //The ROT must be the same 
00235         /*#7*/
00236         if (i > 0) //Make sure key is persistent every time
00237         {
00238             TEST_ASSERT_EQUAL_MEMORY(encKeyDerive[i - 1], encKeyDerive[i], keyLenBytes);
00239             TEST_ASSERT_EQUAL_MEMORY(signKeyDerive[i - 1], signKeyDerive[i], keyLenBytes);
00240         } //if
00241     } //for
00242 
00243 
00244 #else // MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT
00245     TEST_IGNORE_MESSAGE("Ignored, MBED_CONF_MBED_CLOUD_CLIENT_EXTERNAL_SST_SUPPORT is not set ");
00246 #endif
00247 
00248 }
00249 
00250 
00251 /*! \brief Check set rot key.
00252 *
00253 *
00254 *
00255 * | # |    Step                                                                        | Expected            |
00256 * |---|--------------------------------------------------------------------------------|---------------------|
00257 * | 1 | Read ROT  key  using `pal_plat_osGetRoT`                                       | PAL_ERR_ITEM_NOT_EXIST  |
00258 * | 2 | Set ROT  key  using `pal_osSetRoT`.                                            | PAL_SUCCESS |
00259 * | 3 | Read ROT  key  using `pal_plat_osGetRoT`                                       | PAL_SUCCESS |
00260 * | 4 | Compare read rot buffer with set rot buffer`                                   | PAL_SUCCESS |
00261 * | 5 | Set ROT  key  using `pal_osSetRoT`.                                            | PAL_ERR_ITEM_EXIST |
00262 * | 6 | Read ROT  key  using `pal_plat_osGetRoT`                                       | PAL_SUCCESS |
00263 * | 7 | Compare read rot buffer with set rot buffer`                                   | PAL_SUCCESS |
00264 */
00265 TEST(pal_rot, SeTRoTKeyTest)
00266 {
00267 #if (PAL_USE_HW_ROT == 0)
00268     palStatus_t status = PAL_SUCCESS;
00269     size_t keyLenBytes = 16;
00270     uint8_t timesToDerive = 1;
00271     uint8_t readRoTKey[keyLenBytes]; //16 bytes=128bit
00272     uint8_t setRoTKey[16] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f }; //16 bytes=128bit
00273 
00274     /*#1*/
00275     status = pal_plat_osGetRoT(readRoTKey, keyLenBytes);
00276     TEST_ASSERT_EQUAL_HEX(PAL_ERR_ITEM_NOT_EXIST , status);
00277     /*#2*/
00278     status = pal_osSetRoT(setRoTKey, keyLenBytes);
00279     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00280     /*#3*/
00281     status = pal_plat_osGetRoT(readRoTKey, keyLenBytes);
00282     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00283     /*#4*/
00284     status = memcmp(readRoTKey, setRoTKey, keyLenBytes);
00285     TEST_ASSERT_EQUAL(status, 0); //The ROT must be the same 
00286     /*#5*/
00287     status = pal_osSetRoT(setRoTKey, keyLenBytes);
00288     TEST_ASSERT_EQUAL_HEX(PAL_ERR_ITEM_EXIST , status);
00289     /*#6*/
00290     status = pal_plat_osGetRoT(readRoTKey, keyLenBytes);
00291     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status);
00292     /*#7*/
00293     status = memcmp(readRoTKey, setRoTKey, keyLenBytes);
00294     TEST_ASSERT_EQUAL(status, 0); //The ROT must be the same 
00295 #else // PAL_USE_HW_ROT =1
00296     TEST_IGNORE_MESSAGE("Ignored, for configuration  PAL_USE_HW_ROT=1, set pal_osSetRoT is not implemented ");
00297 #endif
00298 }