Simple interface for Mbed Cloud Client
Embed:
(wiki syntax)
Show/hide line numbers
pal_SOTP_test.c
00001 /******************************************************************************* 00002 * Copyright 2016, 2017 ARM Ltd. 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 *******************************************************************************/ 00016 00017 #include "pal.h" 00018 #include "sotp.h" 00019 #include "unity.h" 00020 #include "unity_fixture.h" 00021 #include "test_runners.h" 00022 00023 00024 #define SOTP_DIR "/sotp" 00025 #define ROT_KEY_SIZE 16 00026 00027 //add 5 years to minimum time 00028 #define PAL_TEST_START_TIME (PAL_MIN_SEC_FROM_EPOCH + ((PAL_SECONDS_PER_DAY * PAL_DAYS_IN_A_YEAR) * 5)) 00029 #define ACCEPTABLE_DELAY_IN_SEC (5) 00030 #define PAL_SOTP_TEST_DELAY_IN_SEC (5 * 1000) 00031 00032 00033 extern palTestsStatusData_t palTestStatus; 00034 00035 TEST_GROUP(pal_SOTP); 00036 00037 #if (PAL_USE_HW_RTC) 00038 static uint64_t systemRealRTC = 0; 00039 static uint64_t systemStartTickCount = 0; 00040 #endif 00041 00042 PAL_PRIVATE palCtrDrbgCtxHandle_t g_drbgCtx = NULLPTR; 00043 00044 TEST_SETUP(pal_SOTP) 00045 { 00046 palStatus_t status = PAL_SUCCESS; 00047 status = pal_init(); 00048 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00049 #if (PAL_USE_HW_RTC == 1) 00050 uint64_t sysTicks = 0; 00051 status = pal_plat_osGetRtcTime(&systemRealRTC); 00052 if (systemRealRTC < (uint64_t)PAL_MIN_RTC_SET_TIME) 00053 { 00054 systemRealRTC = PAL_MIN_RTC_SET_TIME; 00055 } 00056 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00057 systemStartTickCount = pal_osKernelSysTick(); 00058 #endif 00059 } 00060 00061 TEST_TEAR_DOWN(pal_SOTP) 00062 { 00063 palStatus_t status = PAL_SUCCESS; 00064 #if (PAL_USE_HW_RTC == 1) 00065 uint64_t sysTicks = 0; 00066 uint64_t endTickCount = 0; 00067 uint64_t timeToAddInSec = 0; 00068 uint64_t timeToAddInMiliSec = 0; 00069 endTickCount = pal_osKernelSysTick(); 00070 timeToAddInMiliSec = pal_osKernelSysMilliSecTick(endTickCount - systemStartTickCount); //switch from mili to seconds 00071 timeToAddInSec = PAL_MILISEC_TO_SEC(timeToAddInMiliSec); 00072 status = pal_plat_osSetRtcTime(systemRealRTC + timeToAddInSec); 00073 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00074 #endif 00075 if (g_drbgCtx) 00076 { 00077 pal_CtrDRBGFree(&g_drbgCtx); 00078 } 00079 status = pal_destroy(); 00080 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00081 } 00082 00083 static palStatus_t writeDataInFS(uint8_t* data, size_t dataSize, char* dataName) 00084 { 00085 palStatus_t status = PAL_SUCCESS, status2 = PAL_SUCCESS; 00086 char filePath[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; 00087 palFileDescriptor_t fd = 0; 00088 size_t dataSizeWritten = 0; 00089 00090 status = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FILE_AND_FOLDER_LENGTH, filePath); 00091 strncat(filePath,SOTP_DIR,PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath)); 00092 if (PAL_SUCCESS == status) 00093 { 00094 status = pal_fsMkDir(filePath); 00095 if ((PAL_SUCCESS == status) || (PAL_ERR_FS_NAME_ALREADY_EXIST == status)) 00096 { 00097 strncat(filePath,"/",PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath)); 00098 strncat(filePath,dataName,PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath)); 00099 status = pal_fsFopen(filePath,PAL_FS_FLAG_READWRITETRUNC,&fd); 00100 if (PAL_SUCCESS == status) 00101 { 00102 status = pal_fsFwrite(&fd, (void *)data, dataSize, &dataSizeWritten); 00103 status2 = pal_fsFclose(&fd); 00104 if (PAL_SUCCESS != status2) 00105 { 00106 PAL_LOG(ERR,"Failed to close data file of sotp pal testing after write"); 00107 } 00108 } 00109 } 00110 00111 } 00112 return status; 00113 } 00114 00115 static palStatus_t readDataFromFS(uint8_t* data, size_t dataSize, char* dataName) 00116 { 00117 palStatus_t status= PAL_SUCCESS, status2 = PAL_SUCCESS; 00118 char filePath[PAL_MAX_FILE_AND_FOLDER_LENGTH] = {0}; 00119 palFileDescriptor_t fd = 0; 00120 size_t dataSizeWritten = 0; 00121 00122 status = pal_fsGetMountPoint(PAL_FS_PARTITION_PRIMARY, PAL_MAX_FILE_AND_FOLDER_LENGTH, filePath); 00123 strncat(filePath,SOTP_DIR,PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath)); 00124 if (PAL_SUCCESS == status) 00125 { 00126 strncat(filePath,"/",PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath)); 00127 strncat(filePath,dataName,PAL_MAX_FILE_AND_FOLDER_LENGTH - strlen(filePath)); 00128 status = pal_fsFopen(filePath, PAL_FS_FLAG_READONLY, &fd); 00129 if (PAL_SUCCESS == status) 00130 { 00131 status = pal_fsFread(&fd, (void *)data, dataSize, &dataSizeWritten); 00132 status2 = pal_fsFclose(&fd); 00133 if (PAL_SUCCESS != status2) 00134 { 00135 PAL_LOG(ERR,"Failed to close data file of sotp pal testing after read"); 00136 } 00137 status2 = pal_fsUnlink(filePath); 00138 if (PAL_SUCCESS != status2) 00139 { 00140 PAL_LOG(ERR,"Failed to delete data file of sotp pal testing after read"); 00141 } 00142 } 00143 00144 } 00145 return status; 00146 } 00147 00148 TEST(pal_SOTP, SW_HW_RoT) 00149 { 00150 uint32_t rotLength = ROT_KEY_SIZE; 00151 palDevKeyType_t ketType = palOsStorageEncryptionKey128Bit; 00152 uint8_t rotA[ROT_KEY_SIZE] = {0}; 00153 uint8_t rotB[ROT_KEY_SIZE] = {0}; 00154 sotp_result_e sotpStatus = SOTP_SUCCESS; 00155 palStatus_t status = PAL_SUCCESS; 00156 (void)sotpStatus; 00157 if (palTestStatus.inner == -1) { 00158 status = pal_osGetDeviceKey(ketType, rotA, rotLength); 00159 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00160 #if(PAL_USE_HW_ROT == 0) // test SW RoT 00161 status = pal_osGetDeviceKey(ketType, rotB, rotLength); 00162 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00163 00164 TEST_ASSERT_TRUE(0 == memcmp(rotA,rotB,rotLength)) 00165 00166 sotpStatus = sotp_delete(SOTP_TYPE_ROT); 00167 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, sotpStatus); 00168 00169 memset(rotA,0,sizeof(rotA)); 00170 00171 status = pal_osGetDeviceKey(ketType, rotA, rotLength); 00172 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00173 00174 /** 00175 * if there is no HW RoT, The Rot is generated from random. 00176 * So, if deleted and re generated there is no chance that the 00177 * ols RoT and the New will bw the same 00178 **/ 00179 TEST_ASSERT_TRUE(0 != memcmp(rotA,rotB,rotLength)) 00180 #endif 00181 status = writeDataInFS(rotA, rotLength,"RoT"); 00182 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00183 status = palTestReboot(PAL_TEST_MODULE_SOTP, PAL_TEST_SOTP_TEST_SW_HW_ROT); 00184 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00185 }//start here after the reboot 00186 else 00187 { 00188 memset(rotA,0,sizeof(rotA)); 00189 memset(rotB,0,sizeof(rotB)); 00190 00191 if (palTestStatus.numberOfTests != 0) 00192 { 00193 Unity.TestFailures = palTestStatus.numOfTestsFailures; 00194 Unity.NumberOfTests = palTestStatus.numberOfTests; 00195 Unity.CurrentTestIgnored =palTestStatus.numberOfIgnoredTests; 00196 } 00197 00198 status = pal_osGetDeviceKey(ketType, rotA, rotLength); 00199 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00200 00201 status = readDataFromFS(rotB, rotLength, "RoT"); 00202 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00203 00204 TEST_ASSERT_TRUE(0 == memcmp(rotA,rotB,rotLength)) 00205 } 00206 } 00207 00208 TEST(pal_SOTP, timeInit) 00209 { 00210 // call pal destroy as this test need to start before pal_init() 00211 00212 00213 palStatus_t status = PAL_SUCCESS; 00214 00215 status = pal_destroy(); 00216 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00217 /** 00218 this is is splited to 2 different parts because of the ifdefs 00219 if the end of this if is inside the #if (PAL_USE_HW_RTC == 1) 00220 in any other case, if this was a single if this had casue 00221 compilation error 00222 **/ 00223 00224 00225 if (palTestStatus.inner == -1) 00226 { 00227 #if ((PAL_USE_HW_RTC == 1) && (PAL_USE_INTERNAL_FLASH == 1) && (PAL_INT_FLASH_NUM_SECTION ==2)) 00228 { 00229 uint64_t currentTime = 0; 00230 sotpStatus = sotp_delete(SOTP_TYPE_SAVED_TIME); 00231 TEST_ASSERT_TRUE((SOTP_SUCCESS == sotpStatus) || (SOTP_NOT_FOUND == sotpStatus)) 00232 status = pal_plat_osSetRtcTime((uint64_t)PAL_TEST_START_TIME); 00233 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00234 status = pal_init(); 00235 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00236 currentTime = pal_osGetTime(); 00237 TEST_ASSERT_TRUE((currentTime - ACCEPTABLE_DELAY_IN_SEC) <= PAL_TEST_START_TIME); 00238 status = pal_destroy(); 00239 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00240 status = pal_plat_osSetRtcTime((uint64_t)0); 00241 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00242 status = pal_init(); 00243 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00244 status = pal_osDelay(PAL_SOTP_TEST_DELAY_IN_SEC); 00245 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00246 currentTime = pal_osGetTime(); 00247 TEST_ASSERT_EQUAL_HEX(0, currentTime); 00248 status = pal_destroy(); 00249 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00250 currentTime = PAL_TEST_START_TIME; 00251 sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)¤tTime); 00252 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, status); 00253 currentTime -= (PAL_SECONDS_PER_DAY * PAL_DAYS_IN_A_YEAR); // remove an year 00254 status = pal_plat_osSetRtcTime(currentTime); 00255 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00256 status = pal_init(); 00257 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00258 currentTime = pal_osGetTime(); 00259 TEST_ASSERT_TRUE((PAL_TEST_START_TIME - ACCEPTABLE_DELAY_IN_SEC) <= currentTime); 00260 status = pal_destroy(); 00261 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00262 currentTime = PAL_TEST_START_TIME; 00263 status = pal_plat_osSetRtcTime(currentTime); 00264 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00265 currentTime -= (PAL_SECONDS_PER_DAY * PAL_DAYS_IN_A_YEAR); // remove an year 00266 sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)¤tTime); 00267 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, status); 00268 status = pal_init(); 00269 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00270 currentTime = pal_osGetTime(); 00271 TEST_ASSERT_TRUE((currentTime - ACCEPTABLE_DELAY_IN_SEC) <= PAL_TEST_START_TIME); 00272 #endif 00273 00274 00275 #if ((PAL_USE_HW_RTC == 0) && (PAL_USE_INTERNAL_FLASH == 1) && (PAL_INT_FLASH_NUM_SECTION ==2)) 00276 { 00277 uint64_t currentTime = 0; 00278 currentTime = PAL_TEST_START_TIME; // remove an year 00279 sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)¤tTime); 00280 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, status); 00281 status = pal_init(); 00282 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00283 currentTime = pal_osGetTime(); 00284 TEST_ASSERT_TRUE((PAL_TEST_START_TIME - ACCEPTABLE_DELAY_IN_SEC) <= currentTime); 00285 status = pal_destroy(); 00286 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00287 } 00288 #endif 00289 } 00290 #if (PAL_USE_HW_RTC == 1) 00291 { 00292 uint64_t currentTime = 0; 00293 if (palTestStatus.inner == -1) 00294 { 00295 currentTime = PAL_TEST_START_TIME; // remove an year 00296 status = pal_plat_osSetRtcTime(currentTime); 00297 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00298 00299 status = palTestReboot(PAL_TEST_MODULE_SOTP, PAL_TEST_SOTP_TEST_TIME_INIT); 00300 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00301 }//start here after reboot 00302 else 00303 { 00304 if (palTestStatus.numberOfTests != 0) 00305 { 00306 Unity.TestFailures = palTestStatus.numOfTestsFailures; 00307 Unity.NumberOfTests = palTestStatus.numberOfTests; 00308 Unity.CurrentTestIgnored =palTestStatus.numberOfIgnoredTests; 00309 } 00310 status = pal_plat_osGetRtcTime(¤tTime); 00311 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00312 00313 TEST_ASSERT_TRUE((currentTime - ACCEPTABLE_DELAY_IN_SEC) <= PAL_TEST_START_TIME); 00314 } 00315 } 00316 #endif 00317 } 00318 00319 // the following function is not part of PAL's external API hence extern 00320 extern palStatus_t pal_noiseRead(int32_t buffer[PAL_NOISE_BUFFER_LEN], bool partial, uint16_t* bitsRead); 00321 00322 /*! \brief Test random buffer generation with sotp 00323 * 00324 * | # | Step | Expected | 00325 * |---|----------------------------------------------------------------|-------------| 00326 * | 1 | Save a fixed seed to sotp or read current value is exists. | PAL_SUCCESS | 00327 * | 2 | Generate short & long term seed. | PAL_SUCCESS | 00328 * | 3 | Generate expected random. | PAL_SUCCESS | 00329 * | 4 | Call pal_osRandomBuffer and compare expected to actual random. | PAL_SUCCESS | 00330 * | 5 | Validate counter and next (boot) long term seed. | PAL_SUCCESS | 00331 */ 00332 TEST(pal_SOTP, random) 00333 { 00334 palStatus_t status; 00335 sotp_result_e res; 00336 uint16_t bytesRead = 0; 00337 uint32_t counter = 0; 00338 uint32_t counterCopy = 0; 00339 uint8_t buf[(PAL_INITIAL_RANDOM_SIZE * 2 + sizeof(counter))] PAL_PTR_ADDR_ALIGN_UINT8_TO_UINT32 = { 0 }; 00340 bool sotpRandomExists = false; 00341 00342 #if !PAL_USE_HW_TRNG 00343 uint16_t bitsRead = 0; 00344 int32_t noiseBuffer[PAL_NOISE_BUFFER_LEN] = { 0 }; 00345 pal_noiseRead(noiseBuffer, true, &bitsRead); 00346 #endif // !PAL_USE_HW_TRNG 00347 00348 /*#1*/ 00349 res = sotp_get(SOTP_TYPE_RANDOM_SEED, (PAL_INITIAL_RANDOM_SIZE + sizeof(counter)), (uint32_t*)buf, &bytesRead); // read 48 drbg bytes + 4 counter bytes 00350 TEST_ASSERT_TRUE(SOTP_SUCCESS == res || SOTP_NOT_FOUND == res); 00351 if (SOTP_SUCCESS == res) 00352 { 00353 memcpy((void*)&counter, (void*)&buf[PAL_INITIAL_RANDOM_SIZE], sizeof(counter)); 00354 sotpRandomExists = true; 00355 } 00356 else if (SOTP_NOT_FOUND == res) 00357 { 00358 memset((void*)buf, 7, PAL_INITIAL_RANDOM_SIZE); // fixed dummy seed 00359 res = sotp_set(SOTP_TYPE_RANDOM_SEED, PAL_INITIAL_RANDOM_SIZE, (uint32_t*)buf); 00360 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, res); 00361 } 00362 00363 /*#2*/ 00364 status = pal_CtrDRBGInit(&g_drbgCtx, (void*)buf, PAL_INITIAL_RANDOM_SIZE); 00365 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00366 memset((void*)buf, 0, sizeof(buf)); 00367 status = pal_CtrDRBGGenerate(g_drbgCtx, (unsigned char*)buf, PAL_INITIAL_RANDOM_SIZE * 2); // generate 48 bytes long term & 48 bytes short term seed 00368 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00369 status = pal_CtrDRBGFree(&g_drbgCtx); 00370 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00371 g_drbgCtx = NULLPTR; 00372 00373 /*#3*/ 00374 status = pal_CtrDRBGInit(&g_drbgCtx, (void*)buf, PAL_INITIAL_RANDOM_SIZE); 00375 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00376 memset((void*)buf, 0, PAL_INITIAL_RANDOM_SIZE); 00377 status = pal_CtrDRBGGenerate(g_drbgCtx, (unsigned char*)buf, PAL_INITIAL_RANDOM_SIZE); // generate expected random buffer 00378 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00379 status = pal_CtrDRBGFree(&g_drbgCtx); 00380 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00381 g_drbgCtx = NULLPTR; 00382 00383 /*#4*/ 00384 uint8_t random[PAL_INITIAL_RANDOM_SIZE] = { 0 }; 00385 status = pal_osRandomBuffer(random, PAL_INITIAL_RANDOM_SIZE); // get the actual random buffer 00386 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00387 #if !PAL_USE_HW_TRNG 00388 TEST_ASSERT_EQUAL_MEMORY(buf, random, PAL_INITIAL_RANDOM_SIZE); 00389 #endif // !PAL_USE_HW_TRNG 00390 00391 /*#5*/ 00392 memmove(&buf[(PAL_INITIAL_RANDOM_SIZE + sizeof(counter))], &buf[PAL_INITIAL_RANDOM_SIZE], PAL_INITIAL_RANDOM_SIZE); // make space for the counter while preserving next seed bytes 00393 memset((void*)buf, 0, (PAL_INITIAL_RANDOM_SIZE + sizeof(counter))); 00394 counterCopy = counter; 00395 res = sotp_get(SOTP_TYPE_RANDOM_SEED, (PAL_INITIAL_RANDOM_SIZE + sizeof(counter)), (uint32_t*)buf, &bytesRead); 00396 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, res); 00397 TEST_ASSERT_EQUAL((PAL_INITIAL_RANDOM_SIZE + sizeof(counter)), bytesRead); 00398 memcpy((void*)&counter, (void*)&buf[PAL_INITIAL_RANDOM_SIZE], sizeof(counter)); // read the counter from sotp data 00399 TEST_ASSERT_EQUAL(counterCopy + 1, counter); 00400 #if !PAL_USE_HW_TRNG 00401 TEST_ASSERT_EQUAL_MEMORY(&buf[(PAL_INITIAL_RANDOM_SIZE + sizeof(counter))], buf, PAL_INITIAL_RANDOM_SIZE); 00402 #endif // !PAL_USE_HW_TRNG 00403 00404 if (false == sotpRandomExists) 00405 { 00406 res = sotp_delete(SOTP_TYPE_RANDOM_SEED); 00407 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, res); 00408 } 00409 }
Generated on Tue Jul 12 2022 19:01:36 by 1.7.2