Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
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 updatePalTestStatusAfterReboot(); 00189 00190 memset(rotA,0,sizeof(rotA)); 00191 memset(rotB,0,sizeof(rotB)); 00192 00193 status = pal_osGetDeviceKey(ketType, rotA, rotLength); 00194 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00195 00196 status = readDataFromFS(rotB, rotLength, "RoT"); 00197 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00198 00199 TEST_ASSERT_TRUE(0 == memcmp(rotA,rotB,rotLength)) 00200 } 00201 } 00202 00203 TEST(pal_SOTP, timeInit) 00204 { 00205 // call pal destroy as this test need to start before pal_init() 00206 00207 00208 palStatus_t status = PAL_SUCCESS; 00209 00210 status = pal_destroy(); 00211 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00212 /** 00213 this is is splited to 2 different parts because of the ifdefs 00214 if the end of this if is inside the #if (PAL_USE_HW_RTC == 1) 00215 in any other case, if this was a single if this had casue 00216 compilation error 00217 **/ 00218 00219 00220 if (palTestStatus.inner == -1) 00221 { 00222 #if ((PAL_USE_HW_RTC == 1) && (PAL_USE_INTERNAL_FLASH == 1) && (PAL_INT_FLASH_NUM_SECTION ==2)) 00223 { 00224 uint64_t currentTime = 0; 00225 sotpStatus = sotp_delete(SOTP_TYPE_SAVED_TIME); 00226 TEST_ASSERT_TRUE((SOTP_SUCCESS == sotpStatus) || (SOTP_NOT_FOUND == sotpStatus)) 00227 status = pal_plat_osSetRtcTime((uint64_t)PAL_TEST_START_TIME); 00228 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00229 status = pal_init(); 00230 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00231 currentTime = pal_osGetTime(); 00232 TEST_ASSERT_TRUE((currentTime - ACCEPTABLE_DELAY_IN_SEC) <= PAL_TEST_START_TIME); 00233 status = pal_destroy(); 00234 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00235 status = pal_plat_osSetRtcTime((uint64_t)0); 00236 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00237 status = pal_init(); 00238 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00239 status = pal_osDelay(PAL_SOTP_TEST_DELAY_IN_SEC); 00240 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00241 currentTime = pal_osGetTime(); 00242 TEST_ASSERT_EQUAL_HEX(0, currentTime); 00243 status = pal_destroy(); 00244 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00245 currentTime = PAL_TEST_START_TIME; 00246 sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)¤tTime); 00247 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, status); 00248 currentTime -= (PAL_SECONDS_PER_DAY * PAL_DAYS_IN_A_YEAR); // remove an year 00249 status = pal_plat_osSetRtcTime(currentTime); 00250 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00251 status = pal_init(); 00252 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00253 currentTime = pal_osGetTime(); 00254 TEST_ASSERT_TRUE((PAL_TEST_START_TIME - ACCEPTABLE_DELAY_IN_SEC) <= currentTime); 00255 status = pal_destroy(); 00256 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00257 currentTime = PAL_TEST_START_TIME; 00258 status = pal_plat_osSetRtcTime(currentTime); 00259 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00260 currentTime -= (PAL_SECONDS_PER_DAY * PAL_DAYS_IN_A_YEAR); // remove an year 00261 sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)¤tTime); 00262 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, status); 00263 status = pal_init(); 00264 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00265 currentTime = pal_osGetTime(); 00266 TEST_ASSERT_TRUE((currentTime - ACCEPTABLE_DELAY_IN_SEC) <= PAL_TEST_START_TIME); 00267 #endif 00268 00269 00270 #if ((PAL_USE_HW_RTC == 0) && (PAL_USE_INTERNAL_FLASH == 1) && (PAL_INT_FLASH_NUM_SECTION ==2)) 00271 { 00272 uint64_t currentTime = 0; 00273 currentTime = PAL_TEST_START_TIME; // remove an year 00274 sotpStatus = sotp_set(SOTP_TYPE_SAVED_TIME, sizeof(uint64_t), (uint32_t *)¤tTime); 00275 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, status); 00276 status = pal_init(); 00277 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00278 currentTime = pal_osGetTime(); 00279 TEST_ASSERT_TRUE((PAL_TEST_START_TIME - ACCEPTABLE_DELAY_IN_SEC) <= currentTime); 00280 status = pal_destroy(); 00281 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00282 } 00283 #endif 00284 } 00285 #if (PAL_USE_HW_RTC == 1) 00286 { 00287 uint64_t currentTime = 0; 00288 if (palTestStatus.inner == -1) 00289 { 00290 currentTime = PAL_TEST_START_TIME; // remove an year 00291 status = pal_plat_osSetRtcTime(currentTime); 00292 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00293 00294 status = palTestReboot(PAL_TEST_MODULE_SOTP, PAL_TEST_SOTP_TEST_TIME_INIT); 00295 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00296 }//start here after reboot 00297 else 00298 { 00299 updatePalTestStatusAfterReboot(); 00300 status = pal_plat_osGetRtcTime(¤tTime); 00301 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00302 00303 TEST_ASSERT_TRUE((currentTime - ACCEPTABLE_DELAY_IN_SEC) <= PAL_TEST_START_TIME); 00304 } 00305 } 00306 #endif 00307 } 00308 00309 // the following function is not part of PAL's external API hence extern 00310 extern palStatus_t pal_noiseRead(int32_t buffer[PAL_NOISE_BUFFER_LEN], bool partial, uint16_t* bitsRead); 00311 00312 /*! \brief Test random buffer generation with sotp 00313 * 00314 * | # | Step | Expected | 00315 * |---|----------------------------------------------------------------|-------------| 00316 * | 1 | Save a fixed seed to sotp or read current value is exists. | PAL_SUCCESS | 00317 * | 2 | Generate short & long term seed. | PAL_SUCCESS | 00318 * | 3 | Generate expected random. | PAL_SUCCESS | 00319 * | 4 | Call pal_osRandomBuffer and compare expected to actual random. | PAL_SUCCESS | 00320 * | 5 | Validate counter and next (boot) long term seed. | PAL_SUCCESS | 00321 */ 00322 TEST(pal_SOTP, random) 00323 { 00324 palStatus_t status; 00325 sotp_result_e res; 00326 uint16_t bytesRead = 0; 00327 uint32_t counter = 0; 00328 uint32_t counterCopy = 0; 00329 uint8_t buf[(PAL_INITIAL_RANDOM_SIZE * 2 + sizeof(counter))] PAL_PTR_ADDR_ALIGN_UINT8_TO_UINT32 = { 0 }; 00330 bool sotpRandomExists = false; 00331 00332 #if !PAL_USE_HW_TRNG 00333 uint16_t bitsRead = 0; 00334 int32_t noiseBuffer[PAL_NOISE_BUFFER_LEN] = { 0 }; 00335 pal_noiseRead(noiseBuffer, true, &bitsRead); 00336 #endif // !PAL_USE_HW_TRNG 00337 00338 /*#1*/ 00339 res = sotp_get(SOTP_TYPE_RANDOM_SEED, (PAL_INITIAL_RANDOM_SIZE + sizeof(counter)), (uint32_t*)buf, &bytesRead); // read 48 drbg bytes + 4 counter bytes 00340 TEST_ASSERT_TRUE(SOTP_SUCCESS == res || SOTP_NOT_FOUND == res); 00341 if (SOTP_SUCCESS == res) 00342 { 00343 memcpy((void*)&counter, (void*)&buf[PAL_INITIAL_RANDOM_SIZE], sizeof(counter)); 00344 sotpRandomExists = true; 00345 } 00346 else if (SOTP_NOT_FOUND == res) 00347 { 00348 memset((void*)buf, 7, PAL_INITIAL_RANDOM_SIZE); // fixed dummy seed 00349 res = sotp_set(SOTP_TYPE_RANDOM_SEED, PAL_INITIAL_RANDOM_SIZE, (uint32_t*)buf); 00350 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, res); 00351 } 00352 00353 /*#2*/ 00354 status = pal_CtrDRBGInit(&g_drbgCtx, (void*)buf, PAL_INITIAL_RANDOM_SIZE); 00355 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00356 memset((void*)buf, 0, sizeof(buf)); 00357 status = pal_CtrDRBGGenerate(g_drbgCtx, (unsigned char*)buf, PAL_INITIAL_RANDOM_SIZE * 2); // generate 48 bytes long term & 48 bytes short term seed 00358 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00359 status = pal_CtrDRBGFree(&g_drbgCtx); 00360 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00361 g_drbgCtx = NULLPTR; 00362 00363 /*#3*/ 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, PAL_INITIAL_RANDOM_SIZE); 00367 status = pal_CtrDRBGGenerate(g_drbgCtx, (unsigned char*)buf, PAL_INITIAL_RANDOM_SIZE); // generate expected random buffer 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 /*#4*/ 00374 uint8_t random[PAL_INITIAL_RANDOM_SIZE] = { 0 }; 00375 status = pal_osRandomBuffer(random, PAL_INITIAL_RANDOM_SIZE); // get the actual random buffer 00376 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00377 #if !PAL_USE_HW_TRNG 00378 TEST_ASSERT_EQUAL_MEMORY(buf, random, PAL_INITIAL_RANDOM_SIZE); 00379 #endif // !PAL_USE_HW_TRNG 00380 00381 /*#5*/ 00382 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 00383 memset((void*)buf, 0, (PAL_INITIAL_RANDOM_SIZE + sizeof(counter))); 00384 counterCopy = counter; 00385 res = sotp_get(SOTP_TYPE_RANDOM_SEED, (PAL_INITIAL_RANDOM_SIZE + sizeof(counter)), (uint32_t*)buf, &bytesRead); 00386 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, res); 00387 TEST_ASSERT_EQUAL((PAL_INITIAL_RANDOM_SIZE + sizeof(counter)), bytesRead); 00388 memcpy((void*)&counter, (void*)&buf[PAL_INITIAL_RANDOM_SIZE], sizeof(counter)); // read the counter from sotp data 00389 TEST_ASSERT_EQUAL(counterCopy + 1, counter); 00390 #if !PAL_USE_HW_TRNG 00391 TEST_ASSERT_EQUAL_MEMORY(&buf[(PAL_INITIAL_RANDOM_SIZE + sizeof(counter))], buf, PAL_INITIAL_RANDOM_SIZE); 00392 #endif // !PAL_USE_HW_TRNG 00393 00394 if (false == sotpRandomExists) 00395 { 00396 res = sotp_delete(SOTP_TYPE_RANDOM_SEED); 00397 TEST_ASSERT_EQUAL_HEX(SOTP_SUCCESS, res); 00398 } 00399 }
Generated on Tue Jul 12 2022 19:12:15 by 1.7.2