Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
pal_crypto_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 "pal_Crypto.h" 00019 #include "unity.h" 00020 #include "unity_fixture.h" 00021 #include "pal_crypto_test_data.h" 00022 #include "string.h" 00023 #include "time.h" 00024 00025 00026 TEST_GROUP(pal_crypto); 00027 00028 TEST_SETUP(pal_crypto) 00029 { 00030 pal_init(); 00031 palStatus_t status = PAL_SUCCESS; 00032 uint64_t currentTime = 1512572014; //GMT: Wed, 06 Dec 2017 14:53:33 GMT 00033 status = pal_osSetTime(currentTime); 00034 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 00035 } 00036 00037 TEST_TEAR_DOWN(pal_crypto) 00038 { 00039 pal_destroy(); 00040 } 00041 00042 /** 00043 * @brief Testing AES encryption and decryption of buffers in CTR mode. 00044 * 00045 * The test encrypts a buffer, compares it against a desired result and then decrypts it back and compares with the original buffer. 00046 * 00047 * Uses CtrVector. 00048 * 00049 * | # | Step | Expected | 00050 * |---|--------------------------------|-------------| 00051 * | 1 | Initialize an AES context. | PAL_SUCCESS | 00052 * | 2 | Set an AES 128bit key for encryption. | PAL_SUCCESS | 00053 * | 3 | Perform AES CTR encryption on an input vector and check that the result is as expected. | PAL_SUCCESS | 00054 * | 4 | Release AES context. | PAL_SUCCESS | 00055 * | 5 | Initialize an AES context. | PAL_SUCCESS | 00056 * | 6 | Set an AES 128bit key for encryption (used for decryption, see AES CTR docs) | PAL_SUCCESS | 00057 * | 7 | Perform AES CTR decryption on an input vector and check that the result is as expected. | PAL_SUCCESS | 00058 * | 8 | Release AES context. | PAL_SUCCESS | 00059 */ 00060 TEST(pal_crypto, AES_CTR) 00061 { 00062 palStatus_t result; 00063 palAesHandle_t ctx_enc = NULLPTR, ctx_dec = NULLPTR; 00064 unsigned char out[16] = {0}; 00065 unsigned char iv[16] = {0}; 00066 00067 memcpy(iv, CtrVector.nonce, sizeof(CtrVector.nonce)); 00068 00069 /*#1*/ 00070 result = pal_initAes(&ctx_enc); 00071 TEST_ASSERT_NOT_EQUAL(ctx_enc, NULLPTR); 00072 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00073 00074 /*#2*/ 00075 result = pal_setAesKey(ctx_enc, CtrVector.key, 128, PAL_KEY_TARGET_ENCRYPTION); 00076 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00077 00078 /*#3*/ 00079 result = pal_aesCTR(ctx_enc, CtrVector.input, out, sizeof(CtrVector.input), iv); 00080 TEST_ASSERT_EQUAL_MEMORY(CtrVector.output, out, sizeof(CtrVector.output)); 00081 00082 /*#4*/ 00083 result = pal_freeAes(&ctx_enc); 00084 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00085 00086 memcpy(iv, CtrVector.nonce, sizeof(CtrVector.nonce)); 00087 memset(out, 0, sizeof(out)); 00088 00089 /*#5*/ 00090 result = pal_initAes(&ctx_dec); 00091 TEST_ASSERT_NOT_EQUAL(ctx_dec, NULLPTR); 00092 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00093 00094 /*#6*/ 00095 result = pal_setAesKey(ctx_dec, CtrVector.key, 128, PAL_KEY_TARGET_ENCRYPTION); 00096 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00097 00098 /*#7*/ 00099 result = pal_aesCTR(ctx_dec, CtrVector.output, out, sizeof(CtrVector.output), iv); 00100 TEST_ASSERT_EQUAL_MEMORY(CtrVector.input, out, sizeof(CtrVector.output)); 00101 00102 /*#8*/ 00103 result = pal_freeAes(&ctx_dec); 00104 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00105 } 00106 00107 /** 00108 * @brief Testing AES encryption and decryption of buffers in CTR mode. 00109 * 00110 * The test encrypts a buffer, compares it against the desired result and then decrypts it back and compares with the original buffer. 00111 * 00112 * Uses CtrVector. 00113 * 00114 * | # | Step | Expected | 00115 * |---|--------------------------------|-------------| 00116 * | 1 | Initialize an AES context. | PAL_SUCCESS | 00117 * | 2 | Set an AES 128bit key for encryption. | PAL_SUCCESS | 00118 * | 3 | Perform AES CTR encryption on input vector and check the encryption output. | PAL_SUCCESS | 00119 * | 4 | Release AES context. | PAL_SUCCESS | 00120 * | 5 | Initialize an AES context. | PAL_SUCCESS | 00121 * | 6 | Set an AES 128bit key for encryption (used for decryption, see AES CTR docs). | PAL_SUCCESS | 00122 * | 7 | Perform AES CTR decryption on an input vector and check that the result is as expected.| PAL_SUCCESS | 00123 * | 8 | Release AES context. | PAL_SUCCESS | 00124 */ 00125 TEST(pal_crypto, AES_CTR_ZeroOffset) 00126 { 00127 palStatus_t result; 00128 palAesHandle_t ctx_enc = NULLPTR, ctx_dec = NULLPTR; 00129 unsigned char out[16] = {0}; 00130 unsigned char iv[16] = {0}; 00131 00132 memcpy(iv, CtrVector.nonce, sizeof(CtrVector.nonce)); 00133 00134 /*#1*/ 00135 result = pal_initAes(&ctx_enc); 00136 TEST_ASSERT_NOT_EQUAL(ctx_enc, NULLPTR); 00137 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00138 00139 /*#2*/ 00140 result = pal_setAesKey(ctx_enc, CtrVector.key, 128, PAL_KEY_TARGET_ENCRYPTION); 00141 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00142 00143 /*#3*/ 00144 result = pal_aesCTRWithZeroOffset(ctx_enc, CtrVector.input, out, sizeof(CtrVector.input), iv); 00145 TEST_ASSERT_EQUAL_MEMORY(CtrVector.output, out, sizeof(CtrVector.output)); 00146 00147 /*#4*/ 00148 result = pal_freeAes(&ctx_enc); 00149 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00150 00151 memcpy(iv, CtrVector.nonce, sizeof(CtrVector.nonce)); 00152 memset(out, 0, sizeof(out)); 00153 00154 /*#5*/ 00155 result = pal_initAes(&ctx_dec); 00156 TEST_ASSERT_NOT_EQUAL(ctx_dec, NULLPTR); 00157 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00158 00159 /*#6*/ 00160 result = pal_setAesKey(ctx_dec, CtrVector.key, 128, PAL_KEY_TARGET_ENCRYPTION); 00161 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00162 00163 /*#7*/ 00164 result = pal_aesCTRWithZeroOffset(ctx_dec, CtrVector.output, out, sizeof(CtrVector.output), iv); 00165 TEST_ASSERT_EQUAL_MEMORY(CtrVector.input, out, sizeof(CtrVector.output)); 00166 00167 /*#8*/ 00168 result = pal_freeAes(&ctx_dec); 00169 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00170 } 00171 00172 00173 /** 00174 * @brief Testing AES encryption and decryption of buffers in ECB mode. 00175 * 00176 * The test encrypts a buffer, compares it against the desired result and then decrypts it back and compares with the original buffer. 00177 * 00178 * Uses EcbVector. 00179 * 00180 * | # | Step | Expected | 00181 * |---|--------------------------------|-------------| 00182 * | 1 | Initialize an AES context. | PAL_SUCCESS | 00183 * | 2 | Set an AES 128bit key for encryption. | PAL_SUCCESS | 00184 * | 3 | Perform AES ECB encryption on input vector and check the encryption output. | PAL_SUCCESS | 00185 * | 4 | Release AES context. | PAL_SUCCESS | 00186 * | 5 | Initialize an AES context. | PAL_SUCCESS | 00187 * | 6 | Set an AES 128bit key for decryption. | PAL_SUCCESS | 00188 * | 7 | Perform AES ECB decryption on an input vector and check that the result is as expected.| PAL_SUCCESS | 00189 * | 8 | Release AES context. | PAL_SUCCESS | 00190 */ 00191 TEST(pal_crypto, AES_ECB) 00192 { 00193 palStatus_t result; 00194 palAesHandle_t ctx_enc = NULLPTR, ctx_dec = NULLPTR; 00195 unsigned char out[16] = {0}; 00196 unsigned char iv[16] = {0}; 00197 00198 memcpy(iv, EcbVector.nonce, sizeof(EcbVector.nonce)); 00199 00200 /*#1*/ 00201 result = pal_initAes(&ctx_enc); 00202 TEST_ASSERT_NOT_EQUAL(ctx_enc, NULLPTR); 00203 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00204 00205 /*#2*/ 00206 result = pal_setAesKey(ctx_enc, EcbVector.key, 128, PAL_KEY_TARGET_ENCRYPTION); 00207 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00208 00209 /*#3*/ 00210 result = pal_aesECB(ctx_enc, EcbVector.input, out, PAL_AES_ENCRYPT); 00211 TEST_ASSERT_EQUAL_MEMORY(EcbVector.output, out, sizeof(EcbVector.output)); 00212 00213 /*#4*/ 00214 result = pal_freeAes(&ctx_enc); 00215 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00216 00217 memcpy(iv, EcbVector.nonce, sizeof(EcbVector.nonce)); 00218 memset(out, 0, sizeof(out)); 00219 00220 /*#5*/ 00221 result = pal_initAes(&ctx_dec); 00222 TEST_ASSERT_NOT_EQUAL(ctx_dec, NULLPTR); 00223 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00224 00225 /*#6*/ 00226 result = pal_setAesKey(ctx_dec, EcbVector.key, 128, PAL_KEY_TARGET_DECRYPTION); 00227 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00228 00229 /*#7*/ 00230 result = pal_aesECB(ctx_dec, EcbVector.output, out, PAL_AES_DECRYPT); 00231 TEST_ASSERT_EQUAL_MEMORY(EcbVector.input, out, sizeof(EcbVector.output)); 00232 00233 /*#8*/ 00234 result = pal_freeAes(&ctx_dec); 00235 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00236 } 00237 00238 00239 /** 00240 * @brief Testing AES encryption and decryption of buffers in CCM mode. 00241 * 00242 * The test encrypts a buffer, compares it against the desired result and then decrypts it back and compares with the original buffer. 00243 * 00244 * Uses aesCcmVectors. 00245 * 00246 * For each vector: 00247 * | # | Step | Expected | 00248 * |---|--------------------------------|-------------| 00249 * | 1 | Initialize an AES CCM context. | PAL_SUCCESS | 00250 * | 2 | Set an AES 128bit key for this particular vector. | PAL_SUCCESS | 00251 * | 3 | Perform AES CCM encryption on input vector and check the encryption output. | PAL_SUCCESS | 00252 * | 4 | Perform AES CCM decryption on an input vector and check that the result is as expected.| PAL_SUCCESS | 00253 * | 5 | Release AES CCM context. | PAL_SUCCESS | 00254 */ 00255 TEST(pal_crypto, AES_CCM) 00256 { 00257 palStatus_t result; 00258 palCCMHandle_t ctx = NULLPTR; 00259 00260 unsigned char iv[16] = {0}; 00261 unsigned char encryptBuffer[32] = {0}; 00262 unsigned char decryptBuffer[32] = {0}; 00263 00264 00265 for (size_t i = 0; i < sizeof(aesCcmVectors) / sizeof(palAesCcmVector_t); ++i) 00266 { 00267 memset(encryptBuffer, 0, sizeof(encryptBuffer)); 00268 memset(decryptBuffer, 0, sizeof(decryptBuffer)); 00269 memset(iv, 0, sizeof(iv)); 00270 memcpy(iv, aesCcmVectors[i].iv, aesCcmVectors[i].ivLen); 00271 00272 /*#1*/ 00273 result = pal_CCMInit(&ctx); 00274 TEST_ASSERT_NOT_EQUAL(ctx, NULLPTR); 00275 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00276 00277 /*#2*/ 00278 result = pal_CCMSetKey(ctx, aesCcmVectors[i].key, 128, PAL_CIPHER_ID_AES); 00279 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00280 00281 /*#3*/ 00282 result = pal_CCMEncrypt(ctx, (unsigned char*)aesCcmVectors[i].in, aesCcmVectors[i].inLen, 00283 iv, aesCcmVectors[i].ivLen, (unsigned char*)aesCcmVectors[i].ad, aesCcmVectors[i].adLen, 00284 encryptBuffer, encryptBuffer + aesCcmVectors[i].inLen, aesCcmVectors[i].tagLen); 00285 00286 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00287 TEST_ASSERT_EQUAL_MEMORY(aesCcmVectors[i].out, encryptBuffer, aesCcmVectors[i].inLen + aesCcmVectors[i].tagLen); 00288 00289 /*#4*/ 00290 result = pal_CCMDecrypt(ctx, encryptBuffer, aesCcmVectors[i].inLen, 00291 iv, aesCcmVectors[i].ivLen, (unsigned char*)aesCcmVectors[i].ad, aesCcmVectors[i].adLen, 00292 encryptBuffer + aesCcmVectors[i].inLen, aesCcmVectors[i].tagLen, decryptBuffer); 00293 00294 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00295 TEST_ASSERT_EQUAL_MEMORY(aesCcmVectors[i].in, decryptBuffer, aesCcmVectors[i].inLen); 00296 00297 /*#5*/ 00298 result = pal_CCMFree(&ctx); 00299 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00300 } 00301 } 00302 00303 00304 /** 00305 * @brief Testing SHA256 hash algorithm. 00306 * 00307 * The test hashes a few buffers and compares them with a well known result using SHA256. 00308 * 00309 * Uses sha256Vectors. 00310 * 00311 * For each vector: 00312 * | # | Step | Expected | 00313 * |---|--------------------------------|-------------| 00314 * | 1 | Perform SHA256 hash on the input vector and check the resulting digest Small input Buffers. | PAL_SUCCESS | 00315 * | 2 | Perform SHA256 hash on the input vector and check the resulting digest BIG input buffer. | PAL_SUCCESS | 00316 */ 00317 TEST(pal_crypto, SHA256) 00318 { 00319 palStatus_t result; 00320 unsigned char output[32]; 00321 00322 for (size_t i = 0; i < sizeof(sha256Vectors) / sizeof(palSha256Vector_t); ++i) 00323 { 00324 memset(output, 0x0, sizeof(output)); 00325 /*#1*/ 00326 result = pal_sha256 (sha256Vectors[i].input, sha256Vectors[i].inLenInBytes, output); 00327 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00328 00329 TEST_ASSERT_EQUAL_MEMORY(sha256Vectors[i].output, output, sizeof(sha256Vectors[i].output)); 00330 } 00331 00332 memset(output, 0x0, sizeof(output)); 00333 /*#2*/ 00334 result = pal_sha256 (sha256Vectors_2nd.input, sha256Vectors_2nd.inLenInBytes, output); 00335 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00336 TEST_ASSERT_EQUAL_MEMORY(sha256Vectors_2nd.output, output, sizeof(sha256Vectors_2nd.output)); 00337 00338 } 00339 00340 00341 /** 00342 * @brief Testing message digest using SHA256 hash algorithm. 00343 * 00344 * The test calculates a message digest of the buffers and compares them against the expected results. 00345 * 00346 * Uses sha256Vectors. 00347 * 00348 * For each vector: 00349 * | # | Step | Expected | 00350 * |---|--------------------------------|-------------| 00351 * | 1 | Initialize a message digest context. | PAL_SUCCESS | 00352 * | 2 | Perform `pal_mdUpdate` on vector input data and check the status. | PAL_SUCCESS | 00353 * | 3 | Get the output size using `pal_mdGetOutputSize` and check the result. | PAL_SUCCESS | 00354 * | 4 | Get the digest result using `pal_mdFinal` and check its value. | PAL_SUCCESS | 00355 * | 5 | Release message digest context. | PAL_SUCCESS | 00356 * | 6 | Initialize a message digest context. with Big input buffer | PAL_SUCCESS | 00357 * | 7 | Perform `pal_mdUpdate` on vector input data and check the status. with Big input buffer | PAL_SUCCESS | 00358 * | 8 | Get the output size using `pal_mdGetOutputSize` and check the result. with Big input buffer| PAL_SUCCESS | 00359 * | 9 | Get the digest result using `pal_mdFinal` and check its value. with Big input buffer | PAL_SUCCESS | 00360 * | 10 | Release message digest context. with Big input buffer | PAL_SUCCESS | 00361 */ 00362 TEST(pal_crypto, md) 00363 { 00364 palStatus_t result; 00365 palMDHandle_t handle = NULLPTR; 00366 size_t bufferSize = 0; 00367 uint8_t output[32] = {0}; 00368 00369 for (size_t i = 0; i < sizeof(sha256Vectors) / sizeof(palSha256Vector_t); ++i) 00370 { 00371 memset(output, 0x0, sizeof(output)); 00372 /*#1*/ 00373 result = pal_mdInit(&handle, PAL_SHA256); 00374 TEST_ASSERT_NOT_EQUAL(handle, NULLPTR); 00375 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00376 00377 /*#2*/ 00378 result = pal_mdUpdate(handle, sha256Vectors[i].input, sha256Vectors[i].inLenInBytes); 00379 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00380 00381 /*#3*/ 00382 result = pal_mdGetOutputSize(handle, &bufferSize); 00383 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00384 TEST_ASSERT_EQUAL_HEX(sha256Vectors[i].outLenInBytes, bufferSize); 00385 00386 /*#4*/ 00387 result = pal_mdFinal(handle, output); 00388 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00389 TEST_ASSERT_EQUAL_MEMORY(sha256Vectors[i].output, output, sizeof(sha256Vectors[i].output)); 00390 00391 /*#5*/ 00392 result = pal_mdFree(&handle); 00393 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00394 } 00395 00396 memset(output, 0x0, sizeof(output)); 00397 /*#6*/ 00398 result = pal_mdInit(&handle, PAL_SHA256); 00399 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00400 00401 /*#7*/ 00402 result = pal_mdUpdate(handle, sha256Vectors_2nd.input, sha256Vectors_2nd.inLenInBytes); 00403 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00404 00405 /*#8*/ 00406 result = pal_mdGetOutputSize(handle, &bufferSize); 00407 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00408 TEST_ASSERT_EQUAL_HEX(sha256Vectors_2nd.outLenInBytes, bufferSize); 00409 00410 /*#9*/ 00411 result = pal_mdFinal(handle, output); 00412 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00413 TEST_ASSERT_EQUAL_MEMORY(sha256Vectors_2nd.output, output, sizeof(sha256Vectors_2nd.output)); 00414 00415 /*#10*/ 00416 result = pal_mdFree(&handle); 00417 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00418 } 00419 00420 00421 /** 00422 * @brief Testing random number generation using deterministic random bit generators. 00423 * 00424 * The test generates a 128 bit number for 100 times and checks that there are no similar keys. 00425 * 00426 * Uses `ctr_drbg_buf` and `ctr_drbg_nonce_pers`. 00427 * 00428 * | # | Step | Expected | 00429 * |---|--------------------------------|-------------| 00430 * | 1 | Initialize a CTR DRBG context. | PAL_SUCCESS | 00431 * | 2 | Generate 100 128bit random values using `pal_CtrDRBGGenerate`. | PAL_SUCCESS | 00432 * | 3 | Release message CTR DRBG context. | PAL_SUCCESS | 00433 * | 4 | Check that all generated numbers are different. | PAL_SUCCESS | 00434 */ 00435 TEST(pal_crypto, CTR_DRBG) 00436 { 00437 palStatus_t result; 00438 palCtrDrbgCtxHandle_t ctx = NULLPTR; 00439 00440 memset(ctr_drbg_buf, 0x0, sizeof(ctr_drbg_buf)); 00441 00442 /*#1*/ 00443 result = pal_CtrDRBGInit(&ctx,ctr_drbg_nonce_pers, sizeof(ctr_drbg_nonce_pers)); 00444 TEST_ASSERT_NOT_EQUAL(ctx, NULLPTR); 00445 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00446 00447 /*#2*/ 00448 for (int i = 0; i < 100; ++i) { 00449 result = pal_CtrDRBGGenerate(ctx, ctr_drbg_buf[i], sizeof(ctr_drbg_buf[i])); 00450 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00451 } 00452 00453 /*#3*/ 00454 result = pal_CtrDRBGFree(&ctx); 00455 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00456 00457 /*#4*/ 00458 for (int i = 0; i < 99; ++i) { 00459 for (int j = i + 1; j < 100; ++j) { 00460 TEST_ASSERT_NOT_EQUAL(0, memcmp(ctr_drbg_buf[i], ctr_drbg_buf[j], sizeof(ctr_drbg_buf[i]))); 00461 } 00462 } 00463 } 00464 00465 00466 /** 00467 * @brief Testing CMAC operation on a buffer with one operation. 00468 * 00469 * The test signs a buffer using CMAC and compares with the expected result buffer. 00470 * 00471 * Uses cmacSingleUseVector. 00472 * 00473 * For each vector: 00474 * | # | Step | Expected | 00475 * |---|--------------------------------|-------------| 00476 * | 1 | Perform CMAC using `pal_cipherCMAC` and check the result. | PAL_SUCCESS | 00477 * | 2 | Check the CMAC output against the test vector. | PAL_SUCCESS | 00478 */ 00479 TEST(pal_crypto, CMAC_one_shot) 00480 { 00481 palStatus_t result; 00482 unsigned char output[16] = {0}; 00483 00484 for (size_t i = 0; i < sizeof(cmacSingleUseVector) / sizeof(palAesCMACVector_t); ++i){ 00485 memset(output, 0x0, sizeof(output)); 00486 /*#1*/ 00487 result = pal_cipherCMAC(cmacSingleUseVector[i].key, 128, cmacSingleUseVector[i].in, cmacSingleUseVector[i].inLen, output); 00488 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00489 /*#2*/ 00490 TEST_ASSERT_EQUAL_MEMORY(cmacSingleUseVector[i].out, output, sizeof(cmacSingleUseVector[i].out)); 00491 } 00492 } 00493 00494 /** 00495 * @brief Testing CMAC operation on a buffer with multiple operations and blocks. 00496 * 00497 * The test signs a buffer using CMAC multiple times and compares with the expected result buffer. 00498 * 00499 * Uses cmacIterativeUseVector. 00500 * 00501 * For each vector: 00502 * | # | Step | Expected | 00503 * |---|--------------------------------|-------------| 00504 * | 1 | Initialize CMAC context using `pal_CMACStart`. | PAL_SUCCESS | 00505 * | 2 | Add a block of data from test vector for CMAC processing using `pal_CMACFinish`. | PAL_SUCCESS | 00506 * | 3 | Add a block of data from test vector for CMAC processing using `pal_CMACFinish`. | PAL_SUCCESS | 00507 * | 4 | Add a block of data from test vector for CMAC processing using `pal_CMACFinish`. | PAL_SUCCESS | 00508 * | 5 | Add a block of data from test vector for CMAC processing using `pal_CMACFinish`. | PAL_SUCCESS | 00509 * | 6 | Get CMAC output using `pal_CMACFinish` and check the result. | PAL_SUCCESS | 00510 */ 00511 TEST(pal_crypto, CMAC_Iterative) 00512 { 00513 palStatus_t result; 00514 palCMACHandle_t ctx = NULLPTR; 00515 unsigned char output[64] = {0}; 00516 size_t resultLen = 0; 00517 00518 for (size_t i = 0; i < sizeof(cmacIterativeUseVector) / sizeof(palCMACMultipleBlockVector_t); ++i) 00519 { 00520 memset(output, 0x0, sizeof(output)); 00521 /*#1*/ 00522 result = pal_CMACStart(&ctx,cmacIterativeUseVector[i].key_string, cmacIterativeUseVector[i].keybits, cmacIterativeUseVector[i].cipher_type); 00523 TEST_ASSERT_NOT_EQUAL(ctx, NULLPTR); 00524 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00525 /*#2*/ 00526 if (cmacIterativeUseVector[i].block1_len >= 0) { 00527 result = pal_CMACUpdate(ctx, cmacIterativeUseVector[i].block1_string, cmacIterativeUseVector[i].block1_len); 00528 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00529 } 00530 /*#3*/ 00531 if (cmacIterativeUseVector[i].block2_len >= 0) { 00532 result = pal_CMACUpdate(ctx, cmacIterativeUseVector[i].block2_string, cmacIterativeUseVector[i].block2_len); 00533 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00534 } 00535 /*#4*/ 00536 if (cmacIterativeUseVector[i].block3_len >= 0) { 00537 result = pal_CMACUpdate(ctx, cmacIterativeUseVector[i].block3_string, cmacIterativeUseVector[i].block3_len); 00538 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00539 } 00540 /*#5*/ 00541 if (cmacIterativeUseVector[i].block4_len >= 0) { 00542 result = pal_CMACUpdate(ctx, cmacIterativeUseVector[i].block4_string, cmacIterativeUseVector[i].block4_len); 00543 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00544 } 00545 /*#6*/ 00546 result = pal_CMACFinish(&ctx, output, &resultLen); 00547 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00548 TEST_ASSERT_EQUAL_HEX(cmacIterativeUseVector[i].block_size, resultLen); 00549 TEST_ASSERT_EQUAL_MEMORY(cmacIterativeUseVector[i].expected_result_string, output, cmacIterativeUseVector[i].block_size); 00550 } // for ends 00551 } 00552 00553 /** 00554 * @brief Testing HMAC operation on a buffer with one operation. 00555 * 00556 * The test signs a buffer using HMAC and compares with the expected result buffer. 00557 * 00558 * Uses mdHMACVector. 00559 * 00560 * For each vector: 00561 * | # | Step | Expected | 00562 * |---|--------------------------------|-------------| 00563 * | 1 | Perform one shot SHA256 HMAC on input vector using `pal_mdHmacSha256` and check the result. | PAL_SUCCESS | 00564 */ 00565 TEST(pal_crypto, HMAC_SHA256_one_shot) 00566 { 00567 palStatus_t result; 00568 unsigned char output[32] = {0}; 00569 00570 for (size_t i = 0; i < sizeof(mdHMACVector) / sizeof(palMdHMACTestVector_t); ++i){ 00571 memset(output, 0x0, sizeof(output)); 00572 /*#1*/ 00573 result = pal_mdHmacSha256(mdHMACVector[i].key, mdHMACVector[i].keyLen, mdHMACVector[i].input, mdHMACVector[i].inputLen, output, NULL); 00574 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00575 TEST_ASSERT_EQUAL_MEMORY(mdHMACVector[i].output, output, mdHMACVector[i].outputLen); 00576 } 00577 } 00578 00579 /** 00580 * @brief Searching for ASN1 patterns in a DER certificate. 00581 * 00582 * The test extracts ASN1 tags from an existing DER format certificate and validates their types. 00583 * 00584 * Uses ASN1TestVector for coordinates and `asn1_data` as the dummy certificate buffer. 00585 * 00586 * For each vector: 00587 * | # | Step | Expected | 00588 * |---|--------------------------------|-------------| 00589 * | 1 | Get data for an ASN tag using `pal_ASN1GetTag`. | PAL_SUCCESS | 00590 * | 2 | Check if the result is success and the size tag size is correct. | PAL_SUCCESS | 00591 */ 00592 TEST(pal_crypto, ASN1) 00593 { 00594 palStatus_t result; 00595 size_t s = 0; 00596 unsigned char* start = NULL; 00597 const unsigned char* end = NULL; 00598 00599 for (size_t i = 0; i < sizeof(ASN1TestVector) / sizeof(palASN1TestVector_t); ++i) { 00600 start = (unsigned char*)(asn1_data + ASN1TestVector[i].start); 00601 end = asn1_data + ASN1TestVector[i].end; 00602 /*#1*/ 00603 result = pal_ASN1GetTag(&start, end, &s, ASN1TestVector[i].type); 00604 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00605 /*#2*/ 00606 TEST_ASSERT_EQUAL(ASN1TestVector[i].dataLen, s); 00607 } 00608 } 00609 00610 /** 00611 * @brief Test the parsing of a dummy X509 certificate. 00612 * 00613 * uses x509_cert 00614 * 00615 * | # | Step | Expected | 00616 * |---|--------------------------------|-------------| 00617 * | 1 | Initialize the X509 ceritifcate context using `pal_x509Initiate`. | PAL_SUCCESS | 00618 * | 2 | Parse a valid x509 certificate using `pal_x509CertParse`. | PAL_SUCCESS | 00619 * | 3 | Parse an invalid x509 certificate using `pal_x509CertParse`. | PAL_ERR_CERT_PARSING_FAILED | 00620 * | 4 | Parse an invalid x509 certificate using `pal_x509CertParse`. | PAL_ERR_INVALID_MD_TYPE | 00621 * | 5 | Parse an invalid x509 certificate using `pal_x509CertParse`. | PAL_ERR_NOT_SUPPORTED_CURVE | 00622 * | 6 | Release x509 certificate context. | PAL_SUCCESS | 00623 */ 00624 TEST(pal_crypto, X509_Parse) 00625 { 00626 #if (PAL_ENABLE_X509 == 1) 00627 palStatus_t result; 00628 palX509Handle_t ctx = NULLPTR; 00629 /*#1*/ 00630 result = pal_x509Initiate(&ctx); 00631 TEST_ASSERT_NOT_EQUAL(ctx, NULLPTR); 00632 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00633 /*#2*/ 00634 result = pal_x509CertParse(ctx, x509_TI, sizeof(x509_TI)); 00635 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00636 /*#3*/ 00637 result = pal_x509CertParse(ctx, x509_TI_PEM, sizeof(x509_TI_PEM)); 00638 TEST_ASSERT_EQUAL_HEX(PAL_ERR_CERT_PARSING_FAILED, result); 00639 /*#4*/ 00640 result = pal_x509CertParse(ctx, (unsigned char*)testdata_x509_Sha512, sizeof(testdata_x509_Sha512)); 00641 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_MD_TYPE, result); 00642 /*#5*/ 00643 result = pal_x509CertParse(ctx, (unsigned char*)testdata_x509_Curve512r1, sizeof(testdata_x509_Curve512r1)); 00644 TEST_ASSERT_EQUAL_HEX(PAL_ERR_NOT_SUPPORTED_CURVE, result); 00645 /*#6*/ 00646 result = pal_x509Free(&ctx); 00647 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00648 #endif 00649 } 00650 00651 /** 00652 * @brief Test the reading of specific attributes in an X509 certificate. 00653 * 00654 * The test parses a X509 certificate and extracts specific attributes and compare them against the expected result. 00655 * 00656 * Uses `x509_cert` and `cert_not_self_signed`. 00657 * 00658 * | # | Step | Expected | 00659 * |---|--------------------------------|-------------| 00660 * | 1 | Initialize the X509 ceritifcate context using `pal_x509Initiate`. | PAL_SUCCESS | 00661 * | 2 | Parse a valid x509 certificate using `pal_x509CertParse`. | PAL_SUCCESS | 00662 * | 3 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00663 * | 4 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00664 * | 5 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00665 * | 6 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00666 * | 7 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00667 * | 8 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00668 * | 9 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00669 * | 10 | Release x509 certificate context using `pal_x509Free`. | PAL_SUCCESS | 00670 * | 11 | Initialize X509 ceritifcate context using `pal_x509Initiate`. | PAL_SUCCESS | 00671 * | 12 | Parse a valid x509 certificate using `pal_x509CertParse`. | PAL_SUCCESS | 00672 * | 13 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00673 * | 14 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00674 * | 15 | Get the certificate attribute value using `pal_x509CertGetAttribute `and check it. | PAL_SUCCESS | 00675 * | 16 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00676 * | 17 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00677 * | 18 | Get the certificate attribute value with a too small buffer. | PAL_ERR_BUFFER_TOO_SMALL | 00678 * | 19 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it. | PAL_SUCCESS | 00679 * | 20 | Release x509 certificate context using `pal_x509Free`. | PAL_SUCCESS | 00680 */ 00681 TEST(pal_crypto, X509_ReadAttributes) 00682 { 00683 00684 #if (PAL_ENABLE_X509 == 1) 00685 palStatus_t result; 00686 palX509Handle_t ctx = NULLPTR; 00687 char buffer1[512] = {0}; 00688 char validationBuf[12] = {0}; 00689 uint8_t certID1[PAL_CERT_ID_SIZE] = {0}; 00690 uint8_t certID2[PAL_CERT_ID_SIZE] = {0}; 00691 time_t validFrom = 0; 00692 time_t validTo = 0; 00693 time_t tmpTime; 00694 size_t actualOutLen = 0; 00695 00696 /*#1*/ 00697 result = pal_x509Initiate(&ctx); 00698 TEST_ASSERT_NOT_EQUAL(ctx, NULLPTR); 00699 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00700 /*#2*/ 00701 result = pal_x509CertParse(ctx, x509_TI, sizeof(x509_TI)); 00702 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00703 /*#3*/ 00704 result = pal_x509CertGetAttribute(ctx, PAL_X509_ISSUER_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00705 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00706 memset(buffer1, 0, sizeof(buffer1)); 00707 /*#4*/ 00708 result = pal_x509CertGetAttribute(ctx, PAL_X509_SUBJECT_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00709 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00710 memset(buffer1, 0, sizeof(buffer1)); 00711 /*#5*/ 00712 result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_FROM, validationBuf, sizeof(validationBuf), &actualOutLen); 00713 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00714 memcpy(&tmpTime, validationBuf, sizeof(tmpTime)); 00715 memset(validationBuf, 0, sizeof(validationBuf)); 00716 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00717 /*#6*/ 00718 result = pal_x509CertGetAttribute(ctx, PAL_X509_CN_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00719 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00720 TEST_ASSERT_EQUAL_STRING("IOT_PAL", buffer1); 00721 memset(buffer1, 0, sizeof(buffer1)); 00722 /*#7*/ 00723 result = pal_x509CertGetAttribute(ctx, PAL_X509_L_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00724 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00725 memset(buffer1, 0, sizeof(buffer1)); 00726 /*#8*/ 00727 result = pal_x509CertGetAttribute(ctx, PAL_X509_OU_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00728 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00729 TEST_ASSERT_EQUAL_STRING("IOTBU", buffer1); 00730 memset(buffer1, 0, sizeof(buffer1)); 00731 /*#9*/ 00732 result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID1, sizeof(certID1), &actualOutLen); 00733 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00734 result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID2, sizeof(certID2), &actualOutLen); 00735 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00736 TEST_ASSERT_EQUAL_MEMORY(certID1, certID2, sizeof(certID1)); 00737 memset(certID1, 0, sizeof(certID1)); 00738 memset(certID2, 0, sizeof(certID2)); 00739 /*#10*/ 00740 result = pal_x509Free(&ctx); 00741 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00742 00743 /*#11*/ 00744 result = pal_x509Initiate(&ctx); 00745 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00746 /*#12*/ 00747 result = pal_x509CertParse(ctx, cert_not_self_signed, sizeof(cert_not_self_signed)); 00748 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00749 /*#13*/ 00750 result = pal_x509CertGetAttribute(ctx, PAL_X509_ISSUER_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00751 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00752 memset(buffer1, 0, sizeof(buffer1)); 00753 /*#14*/ 00754 result = pal_x509CertGetAttribute(ctx, PAL_X509_SUBJECT_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00755 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00756 memset(buffer1, 0, sizeof(buffer1)); 00757 /*#15*/ 00758 result = pal_x509CertGetAttribute(ctx, PAL_X509_CN_ATTR, buffer1, sizeof(buffer1), &actualOutLen); 00759 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00760 TEST_ASSERT_EQUAL_STRING("IOT_TEST", buffer1); 00761 memset(buffer1, 0, sizeof(buffer1)); 00762 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00763 /*#16*/ 00764 result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_FROM, validationBuf, sizeof(validationBuf), &actualOutLen); 00765 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00766 memcpy(&validFrom, validationBuf, sizeof(tmpTime)); 00767 memset(validationBuf, 0, sizeof(validationBuf)); 00768 /*#17*/ 00769 result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_TO, validationBuf, sizeof(validationBuf), &actualOutLen); 00770 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00771 memcpy(&validTo, validationBuf, sizeof(tmpTime)); 00772 memset(validationBuf, 0, sizeof(validationBuf)); 00773 00774 //Check exact time period 00775 TEST_ASSERT_EQUAL_HEX(0x05a39a7f, validTo - validFrom); 00776 /*#18*/ 00777 //! sending small buffer size to check error value scenario 00778 result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_TO, validationBuf, 1, &actualOutLen); 00779 TEST_ASSERT_EQUAL_HEX(PAL_ERR_BUFFER_TOO_SMALL , result); 00780 TEST_ASSERT_EQUAL(sizeof(uint64_t), actualOutLen); 00781 /*#19*/ 00782 result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID1, sizeof(certID1), &actualOutLen); 00783 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00784 result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID2, sizeof(certID2), &actualOutLen); 00785 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00786 TEST_ASSERT_EQUAL_MEMORY(certID1, certID2, sizeof(certID1)); 00787 memset(certID1, 0, sizeof(certID1)); 00788 memset(certID2, 0, sizeof(certID2)); 00789 00790 /*#20*/ 00791 result = pal_x509Free(&ctx); 00792 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00793 #endif 00794 } 00795 00796 /** 00797 * @brief Test the validity of a X509 certificate. 00798 * 00799 * Reads a X509 certificate, specific attributes such as `PAL_X509_VALID_FROM` and `PAL_X509_VALID_TO` 00800 * and validates with `pal_x509CertVerify`. 00801 * 00802 * Uses `x509_verify_data`. 00803 * 00804 For each test vector: 00805 * | # | Step | Expected | 00806 * |---|--------------------------------|-------------| 00807 * | 1 | If the CA cert is part of vector, initialize X509 certificate context using `pal_x509Initiate`. | PAL_SUCCESS | 00808 * | 2 | If the CA cert is part of vector, parse a valid x509 certificate using `pal_x509CertParse`. | PAL_SUCCESS | 00809 * | 3 | Initialize X509 certificate context using `pal_x509Initiate`. | PAL_SUCCESS | 00810 * | 4 | Parse a valid x509 certificate using `pal_x509CertParse`. | PAL_SUCCESS | 00811 * | 5 | Verify the certificate using `pal_x509CertVerify`. | PAL_SUCCESS | 00812 * | 6 | Release X509 certificate context. | PAL_SUCCESS | 00813 * | 7 | If the CA cert is part of vector, release X509 certificate context. | PAL_SUCCESS | 00814 */ 00815 TEST(pal_crypto, X509_Verify) 00816 { 00817 #if (PAL_ENABLE_X509 == 1) 00818 palStatus_t result = PAL_SUCCESS; 00819 palX509Handle_t cert = NULLPTR; 00820 palX509Handle_t caCert = NULLPTR; 00821 int32_t verifyResult = 0; 00822 00823 for (size_t i = 0; i < sizeof(x509_verify_data) / sizeof(palX509VertifyTestVector_t); ++i) 00824 { 00825 if (x509_verify_data[i].ca != NULL) 00826 { 00827 /*#1*/ 00828 result = pal_x509Initiate(&caCert); 00829 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00830 TEST_ASSERT_NOT_EQUAL(caCert, NULLPTR); 00831 /*#2*/ 00832 result = pal_x509CertParse(caCert, x509_verify_data[i].ca, x509_verify_data[i].ca_size); 00833 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00834 } 00835 00836 /*#3*/ 00837 result = pal_x509Initiate(&cert); 00838 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00839 /*#4*/ 00840 result = pal_x509CertParse(cert, x509_verify_data[i].crt, x509_verify_data[i].crt_size); 00841 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00842 /*#5*/ 00843 result = pal_x509CertVerifyExtended(cert, caCert, &verifyResult); 00844 if (PAL_ERR_X509_CERT_VERIFY_FAILED == result) 00845 { 00846 TEST_ASSERT_TRUE((x509_verify_data[i].result & verifyResult)); 00847 } 00848 else 00849 { 00850 TEST_ASSERT_EQUAL_HEX(x509_verify_data[i].result, result); 00851 } 00852 /*#6*/ 00853 result = pal_x509Free(&cert); 00854 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00855 if (x509_verify_data[i].ca != NULL) 00856 { 00857 /*#7*/ 00858 result = pal_x509Free(&caCert); 00859 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00860 } 00861 } 00862 #endif 00863 } 00864 00865 /** 00866 * @brief Test the parsing of elliptic-curves keys (public and private). 00867 * 00868 * Uses `parse_ec_key_data`. 00869 * 00870 * For each test vector: 00871 * | # | Step | Expected | 00872 * |---|--------------------------------|-------------| 00873 * | 1 | Initialize a new ECC key using `pal_ECKeyNew`. | PAL_SUCCESS | 00874 * | 2 | If private key, parse using `pal_parseECPrivateKeyFromDER`, otherwise parse using `pal_parseECPublicKeyFromDER`. | PAL_SUCCESS | 00875 * | 3 | Check the parsing status according to the test vector. | PAL_SUCCESS | 00876 * | 4 | Release the ECC key using `pal_ECKeyFree`. | PAL_SUCCESS | 00877 */ 00878 TEST(pal_crypto, ECKey_parseKey) 00879 { 00880 palStatus_t result; 00881 palECKeyHandle_t handle = NULLPTR; 00882 00883 for (uint32_t i = 0; i < sizeof(parse_ec_key_data) / sizeof(palParseECKeyTestVector_t) ; ++i) { 00884 /*#1*/ 00885 result = pal_ECKeyNew(&handle); 00886 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00887 /*#2*/ 00888 switch (parse_ec_key_data[i].type) { 00889 case PAL_CHECK_PRIVATE_KEY: 00890 result = pal_parseECPrivateKeyFromDER(parse_ec_key_data[i].key, parse_ec_key_data[i].len, handle); 00891 break; 00892 case PAL_CHECK_PUBLIC_KEY: 00893 result = pal_parseECPublicKeyFromDER(parse_ec_key_data[i].key, parse_ec_key_data[i].len, handle); 00894 break; 00895 default: 00896 TEST_FAIL(); 00897 } 00898 /*#3*/ 00899 if (parse_ec_key_data[i].shouldSucceed) 00900 { 00901 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00902 } 00903 else 00904 { 00905 TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, result); 00906 } 00907 /*#4*/ 00908 result = pal_ECKeyFree(&handle); 00909 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00910 } 00911 } 00912 00913 /** 00914 * @brief Test the validity of elliptic-curves keys (public and private). 00915 * 00916 * Uses `check_ec_key_data`. 00917 * 00918 * For each test vector: 00919 * | # | Step | Expected | 00920 * |---|--------------------------------|-------------| 00921 * | 1 | Initialize and load EC curve using `pal_ECGroupInitAndLoad`. | PAL_SUCCESS | 00922 * | 2 | Initialize a new ECC key using `pal_ECKeyNew`. | PAL_SUCCESS | 00923 * | 3 | If private key, parse using `pal_parseECPrivateKeyFromDER` and check the parsing status according to the test vector.| PAL_SUCCESS | 00924 * | 4 | If successfully parsed, check the key using `pal_ECCheckKey`. | PAL_SUCCESS | 00925 * | 5 | Release the ECC key using `pal_ECKeyFree`. | PAL_SUCCESS | 00926 * | 6 | Initialize a new ECC key using `pal_ECKeyNew`. | PAL_SUCCESS | 00927 * | 7 | If public key, parse using `pal_parseECPublicKeyFromDER` and check the parsing status according to test the vector. | PAL_SUCCESS | 00928 * | 8 | If successfully parsed, check the key using `pal_ECCheckKey`. | PAL_SUCCESS | 00929 * | 9 | Release the ECC key using `pal_ECKeyFree`. | PAL_SUCCESS | 00930 * | 10 | Release the EC curve using `pal_ECGroupFree`. | PAL_SUCCESS | 00931 */ 00932 TEST(pal_crypto, ECKey_checkKey) 00933 { 00934 palStatus_t result; 00935 palCurveHandle_t grp = NULLPTR; 00936 bool verified = false; 00937 palECKeyHandle_t key = NULLPTR; 00938 00939 for (uint32_t i = 0; i < sizeof(check_ec_key_data) / sizeof(palCheckEcKeyTestVector_t); ++i) 00940 { 00941 /*#1*/ 00942 result = pal_ECGroupInitAndLoad(&grp, check_ec_key_data[i].index); 00943 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00944 /*#2*/ 00945 result = pal_ECKeyNew(&key); 00946 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00947 /*#3*/ 00948 result = pal_parseECPrivateKeyFromDER(check_ec_key_data[i].key, check_ec_key_data[i].keyLen, key); 00949 TEST_ASSERT_EQUAL_HEX(check_ec_key_data[i].parsePrvRes, result); 00950 if (PAL_SUCCESS == result) 00951 { 00952 /*#4*/ 00953 result = pal_ECCheckKey(grp, key, PAL_CHECK_PRIVATE_KEY, &verified); 00954 TEST_ASSERT_EQUAL(check_ec_key_data[i].checkPrvRes, result); 00955 TEST_ASSERT_EQUAL(check_ec_key_data[i].verifed, verified); 00956 } 00957 00958 /*#5*/ 00959 result = pal_ECKeyFree(&key); 00960 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00961 /*#6*/ 00962 result = pal_ECKeyNew(&key); 00963 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00964 /*#7*/ 00965 result = pal_parseECPublicKeyFromDER(check_ec_key_data[i].key, check_ec_key_data[i].keyLen, key); 00966 TEST_ASSERT_EQUAL_HEX(check_ec_key_data[i].parsePubRes, result); 00967 if (PAL_SUCCESS == result) 00968 { 00969 /*#8*/ 00970 result = pal_ECCheckKey(grp, key, PAL_CHECK_PUBLIC_KEY, &verified); 00971 TEST_ASSERT_EQUAL(check_ec_key_data[i].checkPubRes, result); 00972 TEST_ASSERT_EQUAL(check_ec_key_data[i].verifed, verified); 00973 } 00974 /*#9*/ 00975 result = pal_ECKeyFree(&key); 00976 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00977 /*#10*/ 00978 result = pal_ECGroupFree(&grp); 00979 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 00980 } 00981 } 00982 00983 /** 00984 * @brief Create a CSR from an elliptic-curve key and assure its validity. 00985 * 00986 * Uses CsrTests. 00987 * 00988 * For each test vector (steps 1A-1O are run for each tect vector): 00989 * | # | Step | Expected | 00990 * |---|--------------------------------|-------------| 00991 * | 1 | Initialize and load the EC curve using `pal_ECGroupInitAndLoad`. | PAL_SUCCESS | 00992 * | 1A | Initialize a new ECC key using `pal_ECKeyNew`. | PAL_SUCCESS | 00993 * | 1B | Parse using `pal_parseECPrivateKeyFromDER` and check the parsing status according to the test vector. | PAL_SUCCESS | 00994 * | 1C | Check the key using `pal_ECCheckKey`. | PAL_SUCCESS | 00995 * | 1D | Initialize a new ECC key using `pal_ECKeyNew`. | PAL_SUCCESS | 00996 * | 1E | Parse using `pal_parseECPublicKeyFromDER` and check the parsing status according to the test vector. | PAL_SUCCESS | 00997 * | 1F | Check the key using `pal_ECCheckKey`. | PAL_SUCCESS | 00998 * | 1G | Initialize the x509 certificate context using `pal_x509CSRInit`. | PAL_SUCCESS | 00999 * | 1H | Set the cert subject using `pal_x509CSRSetSubject`. | PAL_SUCCESS | 01000 * | 1I | Set the cert MD using `pal_x509CSRSetMD`. | PAL_SUCCESS | 01001 * | 1J | Set the cert keys using `pal_x509CSRSetKey`. | PAL_SUCCESS | 01002 * | 1K | Set the cert key usage using `pal_x509CSRSetKey`. | PAL_SUCCESS | 01003 * | 1L | Write the certificate to DER file using `pal_x509CSRWriteDER`. | PAL_SUCCESS | 01004 * | 1M | Release the x509 ceritifcate context using `pal_x509CSRFree`. | PAL_SUCCESS | 01005 * | 1N | Release the ECC key using `pal_ECKeyFree`. | PAL_SUCCESS | 01006 * | 1O | Release the ECC key using `pal_ECKeyFree`. | PAL_SUCCESS | 01007 * | 2 | Release the EC curve using `pal_ECGroupFree`. | PAL_SUCCESS | 01008 */ 01009 TEST(pal_crypto, CSR) 01010 { 01011 01012 #if (PAL_ENABLE_X509 == 1) 01013 palStatus_t result; 01014 palECKeyHandle_t prvKeyHandle = NULLPTR, pubKeyHandle = NULLPTR; 01015 unsigned char outDer[1000] = {0}; 01016 size_t reqLen; 01017 palx509CSRHandle_t CSRHandle = NULLPTR; 01018 01019 bool goodKey = false; 01020 palCurveHandle_t grp = NULLPTR; 01021 palGroupIndex_t index = PAL_ECP_DP_SECP256R1; 01022 /*#1*/ 01023 result = pal_ECGroupInitAndLoad(&grp, index); 01024 TEST_ASSERT_NOT_EQUAL(grp, NULLPTR); 01025 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01026 01027 for (uint32_t i = 0; i < sizeof(CsrTests) / sizeof(palX509CSRTestVector_t); ++i) 01028 { 01029 memset(outDer,0, sizeof(outDer)); 01030 01031 goodKey = false; 01032 /*#1A*/ 01033 result = pal_ECKeyNew(&prvKeyHandle); 01034 TEST_ASSERT_NOT_EQUAL(prvKeyHandle, NULLPTR); 01035 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01036 /*#1B*/ 01037 result = pal_parseECPrivateKeyFromDER(CsrTests[i].prvkey, CsrTests[i].prvkeyLen, prvKeyHandle); 01038 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01039 /*#1C*/ 01040 result = pal_ECCheckKey(grp, prvKeyHandle, PAL_CHECK_PRIVATE_KEY, &goodKey); 01041 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01042 TEST_ASSERT_EQUAL(true, goodKey); 01043 01044 goodKey = false; 01045 /*#1D*/ 01046 result = pal_ECKeyNew(&pubKeyHandle); 01047 TEST_ASSERT_NOT_EQUAL(pubKeyHandle, NULLPTR); 01048 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01049 /*#1E*/ 01050 result = pal_parseECPublicKeyFromDER(CsrTests[i].pubkey, CsrTests[i].pubkeyLen, pubKeyHandle); 01051 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01052 /*#1F*/ 01053 result = pal_ECCheckKey(grp, pubKeyHandle, PAL_CHECK_PUBLIC_KEY, &goodKey); 01054 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01055 TEST_ASSERT_EQUAL(true, goodKey); 01056 /*#1G*/ 01057 result = pal_x509CSRInit(&CSRHandle); 01058 TEST_ASSERT_NOT_EQUAL(CSRHandle, NULLPTR); 01059 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01060 /*#1H*/ 01061 result = pal_x509CSRSetSubject(CSRHandle, CsrTests[i].subject_name); 01062 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01063 /*#1I*/ 01064 result = pal_x509CSRSetMD(CSRHandle, CsrTests[i].mdType); 01065 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01066 /*#1J*/ 01067 result = pal_x509CSRSetKey(CSRHandle, pubKeyHandle, prvKeyHandle); 01068 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01069 /*#1K*/ 01070 result = pal_x509CSRSetKeyUsage(CSRHandle, CsrTests[i].keyUsage); 01071 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01072 /*#1L*/ 01073 //pal_x509CSRSetExtension - need input from provisioning 01074 reqLen = 0; 01075 result = pal_x509CSRWriteDER(CSRHandle, outDer, sizeof(outDer), &reqLen); 01076 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01077 01078 TEST_ASSERT_EQUAL(CsrTests[i].derOutLen, reqLen); 01079 TEST_ASSERT_EQUAL_MEMORY(CsrTests[i].derOut, outDer, reqLen); 01080 /*#1M*/ 01081 result = pal_x509CSRFree(&CSRHandle); 01082 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01083 /*#1N*/ 01084 result = pal_ECKeyFree(&prvKeyHandle); 01085 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01086 /*#1O*/ 01087 result = pal_ECKeyFree(&pubKeyHandle); 01088 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01089 } 01090 /*#2*/ 01091 result = pal_ECGroupFree(&grp); 01092 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01093 01094 #endif 01095 } 01096 01097 #define PAL_CRYPTO_TEST_MAX_ECDSA_LEN 74 01098 01099 /** 01100 * @brief Test hash function of the TBS of an X509 and its verification 01101 * 01102 * Uses `x509_verify_ca` and `x509_verify_cert`. 01103 * 01104 * | # | Step | Expected | 01105 * |---|--------------------------------|-------------| 01106 * | 1 | Instantiate X509 handles using `pal_x509Initiate`. | PAL_SUCCESS | 01107 * | 2 | Parse signer and signee X509 certificates into handles using `pal_x509CertParse`. | PAL_SUCCESS | 01108 * | 3 | Hash the TBS of the signee using `pal_x509CertGetHTBS`. | PAL_SUCCESS | 01109 * | 4 | Acquire the signature from the signee using `pal_x509CertGetAttribute` with PAL_X509_SIGNATUR_ATTR flag. | PAL_SUCCESS | 01110 * | 5 | Verify the hash signed by the CA in the signature of signee equals the hash of the TBS using `pal_verifySignature`. | PAL_SUCCESS | 01111 * | 6 | Verify the signature with the public key of the signee instead of the signer, using `pal_verifySignature` and fail. | PAL_ERR_PK_SIG_VERIFY_FAILED | 01112 * | 7 | Release the two X509 handles using `pal_x509Free`. | PAL_SUCCESS | 01113 */ 01114 TEST(pal_crypto, X509_tbs_hash) 01115 { 01116 #if (PAL_ENABLE_X509 == 1) 01117 palStatus_t status; 01118 unsigned char digest[PAL_SHA256_SIZE] = { 0 }; 01119 unsigned char sig[PAL_CRYPTO_TEST_MAX_ECDSA_LEN] = { 0 }; 01120 size_t sig_len; 01121 size_t digest_len; 01122 palX509Handle_t signee = NULLPTR; 01123 palX509Handle_t signer = NULLPTR; 01124 01125 /*#1*/ 01126 status = pal_x509Initiate(&signee); 01127 TEST_ASSERT_NOT_EQUAL(signee, NULLPTR); 01128 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01129 status = pal_x509Initiate(&signer); 01130 TEST_ASSERT_NOT_EQUAL(signer, NULLPTR); 01131 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01132 01133 /*#2*/ 01134 status = pal_x509CertParse(signee, x509_verify_cert, sizeof(x509_verify_cert)); 01135 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01136 status = pal_x509CertParse(signer, x509_verify_ca, sizeof(x509_verify_ca)); 01137 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01138 01139 /*#3*/ 01140 #ifdef DEBUG 01141 // Check invalid arguments 01142 status = pal_x509CertGetHTBS(NULLPTR, PAL_SHA256, digest, sizeof(digest), &digest_len); 01143 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01144 status = pal_x509CertGetHTBS(signee, PAL_SHA256, NULL, sizeof(digest), &digest_len); 01145 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01146 status = pal_x509CertGetHTBS(signee, PAL_SHA256, digest, sizeof(digest), NULL); 01147 TEST_ASSERT_EQUAL_HEX(PAL_ERR_INVALID_ARGUMENT , status); 01148 #endif 01149 // Check with small buffer 01150 status = pal_x509CertGetHTBS(signee, PAL_SHA256, digest, sizeof(digest) - 1, &digest_len); 01151 TEST_ASSERT_EQUAL_HEX(PAL_ERR_BUFFER_TOO_SMALL , status); 01152 01153 status = pal_x509CertGetHTBS(signee, PAL_SHA256, digest, sizeof(digest), &digest_len); 01154 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01155 TEST_ASSERT_EQUAL_HEX(PAL_SHA256_SIZE, digest_len); 01156 01157 /*#4*/ 01158 status = pal_x509CertGetAttribute(signee, PAL_X509_SIGNATUR_ATTR, sig, sizeof(sig), &sig_len); 01159 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01160 01161 /*#5*/ 01162 status = pal_verifySignature(signer, PAL_SHA256, digest, digest_len, sig, sig_len); 01163 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01164 01165 /*#6*/ 01166 status = pal_verifySignature(signee, PAL_SHA256, digest, PAL_SHA256_SIZE, sig, sig_len); 01167 TEST_ASSERT_EQUAL_HEX(PAL_ERR_PK_SIG_VERIFY_FAILED, status); 01168 01169 /*#7*/ 01170 status = pal_x509Free(&signee); 01171 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01172 01173 status = pal_x509Free(&signer); 01174 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, status); 01175 01176 #endif 01177 } 01178 01179 /** 01180 * @brief Test the generation of elliptic-curves keys (public and private). 01181 * 01182 * Uses `pal_ECKeyGenerateKey`. 01183 * 01184 * | # | Step | Expected | 01185 * |---|--------------------------------|-------------| 01186 * | 1 | Initialize a new EC key using `pal_ECKeyNew`. | PAL_SUCCESS | 01187 * | 2 | Generate EC keys using `pal_ECKeyGenerateKey`. | PAL_SUCCESS | 01188 * | 3 | Initialize and load EC group using `pal_ECGroupInitAndLoad`. | PAL_SUCCESS | 01189 * | 4 | Check both generated keys using `pal_ECCheckKey`. | PAL_SUCCESS | 01190 * | 5 | Compute signature for digest with private key using `pal_ECDSASign`. | PAL_SUCCESS | 01191 * | 6 | Verify signature with public key using `pal_ECDSAVerify`. | PAL_SUCCESS | 01192 * | 7 | Release the EC group using `pal_ECGroupFree`. | PAL_SUCCESS | 01193 * | 8 | Release the EC key using `pal_ECKeyFree`. | PAL_SUCCESS | 01194 */ 01195 TEST(pal_crypto, ECKey_GenerateKeys) 01196 { 01197 palStatus_t result; 01198 palECKeyHandle_t key_handle = NULLPTR; 01199 palGroupIndex_t grpID = PAL_ECP_DP_SECP256R1; 01200 palCurveHandle_t grp_handle = NULLPTR; 01201 bool verified = false; 01202 unsigned char hash_digest[] = 01203 { 0x34, 0x70, 0xCD, 0x54, 0x7B, 0x0A, 0x11, 0x5F, 0xE0, 0x5C, 0xEB, 0xBC, 0x07, 0xBA, 0x91, 0x88, 01204 0x27, 0x20, 0x25, 0x6B, 0xB2, 0x7A, 0x66, 0x89, 0x1A, 0x4B, 0xB7, 0x17, 0x11, 0x04, 0x86, 0x6F }; 01205 unsigned char signature[74] = { 0 }; 01206 size_t act_size_of_sign = sizeof(signature); 01207 01208 /*#1*/ 01209 result = pal_ECKeyNew(&key_handle); 01210 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01211 01212 /*#2*/ 01213 result = pal_ECKeyGenerateKey(grpID, key_handle); 01214 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01215 01216 /*#3*/ 01217 result = pal_ECGroupInitAndLoad(&grp_handle, grpID); 01218 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01219 01220 /*#4*/ 01221 result = pal_ECCheckKey(grp_handle,key_handle, PAL_CHECK_BOTH_KEYS,&verified); 01222 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01223 TEST_ASSERT_EQUAL_HEX(true, verified); 01224 01225 /*#5*/ 01226 result = pal_ECDSASign(grp_handle, PAL_SHA256, key_handle, hash_digest, sizeof(hash_digest), signature, &act_size_of_sign); 01227 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01228 01229 /*#6*/ 01230 verified = false; 01231 result = pal_ECDSAVerify(key_handle, hash_digest, sizeof(hash_digest), signature, act_size_of_sign, &verified); 01232 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01233 TEST_ASSERT_EQUAL_HEX(true, verified); 01234 01235 /*#7*/ 01236 result = pal_ECGroupFree(&grp_handle); 01237 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01238 01239 /*#8*/ 01240 result = pal_ECKeyFree(&key_handle); 01241 TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result); 01242 }
Generated on Tue Jul 12 2022 16:24:18 by
1.7.2