Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_SOTP_test.c Source File

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 *)&currentTime);
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 *)&currentTime);
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 *)&currentTime);
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(&currentTime);
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 }