Simple interface for Mbed Cloud Client

Dependents:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_crypto_test.c Source File

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 | Release x509 certificate context using `pal_x509Free`.                                       | PAL_SUCCESS |
00669  * | 10 | Initialize X509 ceritifcate context using `pal_x509Initiate`.                                | PAL_SUCCESS |
00670  * | 11 | Parse a valid x509 certificate using `pal_x509CertParse`.                                   | PAL_SUCCESS |
00671  * | 12 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it.          | 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 with a too small buffer.                                | PAL_ERR_BUFFER_TOO_SMALL |
00677  * | 18 | Get the certificate attribute value using `pal_x509CertGetAttribute` and check it.          | PAL_SUCCESS |
00678  * | 19 | Release x509 certificate context using `pal_x509Free`.                                      | PAL_SUCCESS |
00679  */
00680 TEST(pal_crypto, X509_ReadAttributes)
00681 {
00682 
00683 #if (PAL_ENABLE_X509 == 1)
00684     palStatus_t result;
00685     palX509Handle_t ctx = NULLPTR;
00686     char buffer1[512] = {0};
00687     char validationBuf[12] = {0};
00688     uint8_t certID1[PAL_CERT_ID_SIZE] = {0};
00689     uint8_t certID2[PAL_CERT_ID_SIZE] = {0};
00690     time_t validFrom = 0;
00691     time_t validTo = 0;
00692     time_t tmpTime;
00693     size_t actualOutLen = 0;
00694 
00695     /*#1*/
00696     result = pal_x509Initiate(&ctx);
00697     TEST_ASSERT_NOT_EQUAL(ctx, NULLPTR);
00698     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00699     /*#2*/
00700     result = pal_x509CertParse(ctx, x509_TI, sizeof(x509_TI));
00701     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00702     /*#3*/
00703     result = pal_x509CertGetAttribute(ctx, PAL_X509_ISSUER_ATTR, buffer1, sizeof(buffer1), &actualOutLen);
00704     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00705     memset(buffer1, 0, sizeof(buffer1));
00706     /*#4*/
00707     result = pal_x509CertGetAttribute(ctx, PAL_X509_SUBJECT_ATTR, buffer1, sizeof(buffer1), &actualOutLen);
00708     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00709     memset(buffer1, 0, sizeof(buffer1));
00710     /*#5*/
00711     result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_FROM, validationBuf, sizeof(validationBuf), &actualOutLen);
00712     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00713     memcpy(&tmpTime, validationBuf, sizeof(tmpTime));
00714     memset(validationBuf, 0, sizeof(validationBuf));
00715     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00716     /*#6*/
00717     result = pal_x509CertGetAttribute(ctx, PAL_X509_CN_ATTR, buffer1, sizeof(buffer1), &actualOutLen);
00718     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00719     TEST_ASSERT_EQUAL_STRING("IOT_PAL", buffer1);
00720     memset(buffer1, 0, sizeof(buffer1));
00721     /*#7*/
00722     result = pal_x509CertGetAttribute(ctx, PAL_X509_OU_ATTR, buffer1, sizeof(buffer1), &actualOutLen);
00723     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00724     TEST_ASSERT_EQUAL_STRING("IOTBU", buffer1);
00725     memset(buffer1, 0, sizeof(buffer1));
00726     /*#8*/
00727     result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID1, sizeof(certID1), &actualOutLen);
00728     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00729     result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID2, sizeof(certID2), &actualOutLen);
00730     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00731     TEST_ASSERT_EQUAL_MEMORY(certID1, certID2, sizeof(certID1));
00732     memset(certID1, 0, sizeof(certID1));
00733     memset(certID2, 0, sizeof(certID2));
00734     /*#9*/
00735     result = pal_x509Free(&ctx);
00736     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00737 
00738     /*#10*/
00739     result = pal_x509Initiate(&ctx);
00740     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00741     /*#11*/
00742     result = pal_x509CertParse(ctx, cert_not_self_signed, sizeof(cert_not_self_signed));
00743     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00744     /*#12*/
00745     result = pal_x509CertGetAttribute(ctx, PAL_X509_ISSUER_ATTR, buffer1, sizeof(buffer1), &actualOutLen);
00746     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00747     memset(buffer1, 0, sizeof(buffer1));
00748     /*#13*/
00749     result = pal_x509CertGetAttribute(ctx, PAL_X509_SUBJECT_ATTR, buffer1, sizeof(buffer1), &actualOutLen);
00750     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00751     memset(buffer1, 0, sizeof(buffer1));
00752     /*#14*/
00753     result = pal_x509CertGetAttribute(ctx, PAL_X509_CN_ATTR, buffer1, sizeof(buffer1), &actualOutLen);
00754     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00755     TEST_ASSERT_EQUAL_STRING("IOT_TEST", buffer1);
00756     memset(buffer1, 0, sizeof(buffer1));
00757     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00758     /*#15*/
00759     result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_FROM, validationBuf, sizeof(validationBuf), &actualOutLen);
00760     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00761     memcpy(&validFrom, validationBuf, sizeof(tmpTime));
00762     memset(validationBuf, 0, sizeof(validationBuf));
00763     /*#16*/
00764     result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_TO, validationBuf, sizeof(validationBuf), &actualOutLen);
00765     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00766     memcpy(&validTo, validationBuf, sizeof(tmpTime));
00767     memset(validationBuf, 0, sizeof(validationBuf));
00768     
00769     //Check exact time period
00770     TEST_ASSERT_EQUAL_HEX(0x05a39a7f, validTo - validFrom);
00771     /*#17*/
00772     //! sending small buffer size to check error value scenario
00773     result = pal_x509CertGetAttribute(ctx, PAL_X509_VALID_TO, validationBuf, 1, &actualOutLen);
00774     TEST_ASSERT_EQUAL_HEX(PAL_ERR_BUFFER_TOO_SMALL , result);
00775     TEST_ASSERT_EQUAL(sizeof(uint64_t), actualOutLen);
00776     /*#18*/
00777     result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID1, sizeof(certID1), &actualOutLen);
00778     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00779     result = pal_x509CertGetAttribute(ctx, PAL_X509_CERT_ID_ATTR, certID2, sizeof(certID2), &actualOutLen);
00780     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00781     TEST_ASSERT_EQUAL_MEMORY(certID1, certID2, sizeof(certID1));
00782     memset(certID1, 0, sizeof(certID1));
00783     memset(certID2, 0, sizeof(certID2));
00784 
00785     /*#19*/
00786     result = pal_x509Free(&ctx);
00787     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00788 #endif
00789 }
00790     
00791 /**
00792  * @brief Test the validity of a X509 certificate.
00793  *
00794  * Reads a X509 certificate, specific attributes such as `PAL_X509_VALID_FROM` and `PAL_X509_VALID_TO`
00795  * and validates with `pal_x509CertVerify`.
00796  *
00797  * Uses `x509_verify_data`.
00798  *
00799  For each test vector:
00800  * | # |    Step                        |   Expected  |
00801  * |---|--------------------------------|-------------|
00802  * | 1 | If the CA cert is part of vector, initialize X509 certificate context using `pal_x509Initiate`. | PAL_SUCCESS |
00803  * | 2 | If the CA cert is part of vector, parse a valid x509 certificate using `pal_x509CertParse`.     | PAL_SUCCESS |
00804  * | 3 | Initialize X509 certificate context using `pal_x509Initiate`.                                   | PAL_SUCCESS |
00805  * | 4 | Parse a valid x509 certificate using `pal_x509CertParse`.                                       | PAL_SUCCESS |
00806  * | 5 | Verify the certificate using `pal_x509CertVerify`.                                              | PAL_SUCCESS |
00807  * | 6 | Release X509 certificate context.                                                               | PAL_SUCCESS |
00808  * | 7 | If the CA cert is part of vector, release X509 certificate context.                             | PAL_SUCCESS |
00809  */
00810 TEST(pal_crypto, X509_Verify)
00811 {
00812 #if (PAL_ENABLE_X509 == 1)
00813     palStatus_t result = PAL_SUCCESS;
00814     palX509Handle_t cert = NULLPTR;
00815     palX509Handle_t caCert = NULLPTR;
00816     int32_t verifyResult = 0;
00817 
00818     for (size_t i = 0; i < sizeof(x509_verify_data) / sizeof(palX509VertifyTestVector_t); ++i) 
00819     {
00820         if (x509_verify_data[i].ca != NULL)
00821         {
00822             /*#1*/
00823             result = pal_x509Initiate(&caCert);
00824             TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00825             TEST_ASSERT_NOT_EQUAL(caCert, NULLPTR);
00826             /*#2*/
00827             result = pal_x509CertParse(caCert, x509_verify_data[i].ca, x509_verify_data[i].ca_size);
00828             TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00829         }
00830 
00831         /*#3*/
00832         result = pal_x509Initiate(&cert);
00833         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00834         /*#4*/
00835         result = pal_x509CertParse(cert, x509_verify_data[i].crt, x509_verify_data[i].crt_size);
00836         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00837         /*#5*/
00838         result = pal_x509CertVerifyExtended(cert, caCert, &verifyResult);
00839         if (PAL_ERR_X509_CERT_VERIFY_FAILED == result)
00840         {
00841             TEST_ASSERT_TRUE((x509_verify_data[i].result & verifyResult));
00842         }
00843         else
00844         {
00845             TEST_ASSERT_EQUAL_HEX(x509_verify_data[i].result, result);   
00846         }
00847         /*#6*/
00848         result = pal_x509Free(&cert);
00849         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00850         if (x509_verify_data[i].ca != NULL)
00851         {
00852             /*#7*/
00853             result = pal_x509Free(&caCert);
00854             TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00855         }
00856     }
00857 #endif
00858 }
00859 
00860 /**
00861  * @brief Test the parsing of elliptic-curves keys (public and private).
00862  *
00863  * Uses `parse_ec_key_data`.
00864  *
00865  * For each test vector:
00866  * | # |    Step                        |   Expected  |
00867  * |---|--------------------------------|-------------|
00868  * | 1 | Initialize a new ECC key using `pal_ECKeyNew`.                                                                      | PAL_SUCCESS |
00869  * | 2 | If private key, parse using `pal_parseECPrivateKeyFromDER`, otherwise parse using `pal_parseECPublicKeyFromDER`.    | PAL_SUCCESS |
00870  * | 3 | Check the parsing status according to the test vector.                                                              | PAL_SUCCESS |
00871  * | 4 | Release the ECC key using `pal_ECKeyFree`.                                                                          | PAL_SUCCESS |
00872  */
00873 TEST(pal_crypto, ECKey_parseKey)
00874 {
00875     palStatus_t result;
00876     palECKeyHandle_t handle = NULLPTR;
00877 
00878     for (uint32_t i = 0; i < sizeof(parse_ec_key_data) / sizeof(palParseECKeyTestVector_t) ; ++i) {
00879         /*#1*/
00880         result = pal_ECKeyNew(&handle);
00881         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00882         /*#2*/
00883         switch (parse_ec_key_data[i].type) {
00884             case PAL_CHECK_PRIVATE_KEY:
00885                 result = pal_parseECPrivateKeyFromDER(parse_ec_key_data[i].key, parse_ec_key_data[i].len, handle);
00886                 break;
00887             case PAL_CHECK_PUBLIC_KEY:
00888                 result = pal_parseECPublicKeyFromDER(parse_ec_key_data[i].key, parse_ec_key_data[i].len, handle);
00889                 break;
00890             default:
00891                 TEST_FAIL();
00892         }
00893         /*#3*/
00894         if (parse_ec_key_data[i].shouldSucceed)
00895         {
00896             TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00897         }
00898         else
00899         {
00900             TEST_ASSERT_NOT_EQUAL(PAL_SUCCESS, result);
00901         }
00902         /*#4*/
00903         result = pal_ECKeyFree(&handle);
00904         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00905     }
00906 }
00907 
00908 /**
00909  * @brief Test the validity of elliptic-curves keys (public and private).
00910  *
00911  * Uses `check_ec_key_data`.
00912  *
00913  * For each test vector:
00914  * | # |    Step                        |   Expected  |
00915  * |---|--------------------------------|-------------|
00916  * | 1 | Initialize and load EC curve using `pal_ECGroupInitAndLoad`.                                                         | PAL_SUCCESS |
00917  * | 2 | Initialize a new ECC key using `pal_ECKeyNew`.                                                                       | PAL_SUCCESS |
00918  * | 3 | If private key, parse using `pal_parseECPrivateKeyFromDER` and check the parsing status according to the test vector.| PAL_SUCCESS |
00919  * | 4 | If successfully parsed, check the key using `pal_ECCheckKey`.                                                        | PAL_SUCCESS |
00920  * | 5 | Release the ECC key using `pal_ECKeyFree`.                                                                           | PAL_SUCCESS |
00921  * | 6 | Initialize a new ECC key using `pal_ECKeyNew`.                                                                       | PAL_SUCCESS |
00922  * | 7 | If public key, parse using `pal_parseECPublicKeyFromDER` and check the parsing status according to test the vector.  | PAL_SUCCESS |
00923  * | 8 | If successfully parsed, check the key using `pal_ECCheckKey`.                                                        | PAL_SUCCESS |
00924  * | 9 | Release the ECC key using `pal_ECKeyFree`.                                                                           | PAL_SUCCESS |
00925  * | 10 | Release the EC curve using `pal_ECGroupFree`.                                                                       | PAL_SUCCESS |
00926  */
00927 TEST(pal_crypto, ECKey_checkKey)
00928 {
00929     palStatus_t result;
00930     palCurveHandle_t grp = NULLPTR;
00931     bool verified = false;
00932     palECKeyHandle_t key = NULLPTR;
00933 
00934     for (uint32_t i = 0; i < sizeof(check_ec_key_data) / sizeof(palCheckEcKeyTestVector_t); ++i)
00935     {
00936         /*#1*/
00937         result = pal_ECGroupInitAndLoad(&grp, check_ec_key_data[i].index);
00938         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00939         /*#2*/
00940         result = pal_ECKeyNew(&key);
00941         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00942         /*#3*/
00943         result = pal_parseECPrivateKeyFromDER(check_ec_key_data[i].key, check_ec_key_data[i].keyLen, key);
00944         TEST_ASSERT_EQUAL_HEX(check_ec_key_data[i].parsePrvRes, result);
00945         if (PAL_SUCCESS == result)
00946         {
00947             /*#4*/
00948             result = pal_ECCheckKey(grp, key, PAL_CHECK_PRIVATE_KEY, &verified);
00949             TEST_ASSERT_EQUAL(check_ec_key_data[i].checkPrvRes, result);
00950             TEST_ASSERT_EQUAL(check_ec_key_data[i].verifed, verified);
00951         }
00952 
00953         /*#5*/
00954         result = pal_ECKeyFree(&key);
00955         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00956         /*#6*/
00957         result = pal_ECKeyNew(&key);
00958         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00959         /*#7*/
00960         result = pal_parseECPublicKeyFromDER(check_ec_key_data[i].key, check_ec_key_data[i].keyLen, key);
00961         TEST_ASSERT_EQUAL_HEX(check_ec_key_data[i].parsePubRes, result);
00962         if (PAL_SUCCESS == result)
00963         {
00964             /*#8*/
00965             result = pal_ECCheckKey(grp, key, PAL_CHECK_PUBLIC_KEY, &verified);
00966             TEST_ASSERT_EQUAL(check_ec_key_data[i].checkPubRes, result);
00967             TEST_ASSERT_EQUAL(check_ec_key_data[i].verifed, verified);
00968         }
00969         /*#9*/
00970         result = pal_ECKeyFree(&key);
00971         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00972         /*#10*/
00973         result = pal_ECGroupFree(&grp);
00974         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
00975     }
00976 }
00977 
00978 /**
00979  * @brief Create a CSR from an elliptic-curve key and assure its validity.
00980  *
00981  * Uses CsrTests.
00982  *
00983  * For each test vector (steps 1A-1O are run for each tect vector):
00984  * | # |    Step                        |   Expected  |
00985  * |---|--------------------------------|-------------|
00986  * | 1 | Initialize and load the EC curve using `pal_ECGroupInitAndLoad`.                                                     | PAL_SUCCESS |
00987  * | 1A | Initialize a new ECC key using `pal_ECKeyNew`.                                                                      | PAL_SUCCESS |
00988  * | 1B | Parse using `pal_parseECPrivateKeyFromDER` and check the parsing status according to the test vector.               | PAL_SUCCESS |
00989  * | 1C | Check the key using `pal_ECCheckKey`.                                                                               | PAL_SUCCESS |
00990  * | 1D | Initialize a new ECC key using `pal_ECKeyNew`.                                                                      | PAL_SUCCESS |
00991  * | 1E | Parse using `pal_parseECPublicKeyFromDER` and check the parsing status according to the test vector.                | PAL_SUCCESS |
00992  * | 1F | Check the key using `pal_ECCheckKey`.                                                                               | PAL_SUCCESS |
00993  * | 1G | Initialize the x509 certificate context using `pal_x509CSRInit`.                                                    | PAL_SUCCESS |
00994  * | 1H  | Set the cert subject using `pal_x509CSRSetSubject`.                                                                | PAL_SUCCESS |
00995  * | 1I  | Set the cert MD using `pal_x509CSRSetMD`.                                                                          | PAL_SUCCESS |
00996  * | 1J  | Set the cert keys using `pal_x509CSRSetKey`.                                                                       | PAL_SUCCESS |
00997  * | 1K  | Set the cert key usage using `pal_x509CSRSetKey`.                                                                  | PAL_SUCCESS |
00998  * | 1L  | Write the certificate to DER file using `pal_x509CSRWriteDER`.                                                     | PAL_SUCCESS |
00999  * | 1M  | Release the x509 ceritifcate context using `pal_x509CSRFree`.                                                      | PAL_SUCCESS |
01000  * | 1N  | Release the ECC key using `pal_ECKeyFree`.                                                                         | PAL_SUCCESS |
01001  * | 1O  | Release the ECC key using `pal_ECKeyFree`.                                                                         | PAL_SUCCESS |
01002  * | 2 | Release the EC curve using `pal_ECGroupFree`.                                                                        | PAL_SUCCESS |
01003  */
01004 TEST(pal_crypto, CSR)
01005 {
01006 
01007 #if (PAL_ENABLE_X509 == 1)
01008     palStatus_t result;
01009     palECKeyHandle_t prvKeyHandle = NULLPTR, pubKeyHandle = NULLPTR;
01010     unsigned char outDer[1000] = {0};
01011     size_t reqLen;
01012     palx509CSRHandle_t CSRHandle = NULLPTR;
01013 
01014     bool goodKey = false;
01015     palCurveHandle_t grp = NULLPTR;
01016     palGroupIndex_t index = PAL_ECP_DP_SECP256R1;
01017     /*#1*/
01018     result = pal_ECGroupInitAndLoad(&grp, index);
01019     TEST_ASSERT_NOT_EQUAL(grp, NULLPTR);
01020     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01021 
01022     for (uint32_t i = 0; i < sizeof(CsrTests) / sizeof(palX509CSRTestVector_t); ++i)
01023     {
01024         memset(outDer,0, sizeof(outDer));
01025 
01026         goodKey = false;
01027         /*#1A*/
01028         result = pal_ECKeyNew(&prvKeyHandle);
01029         TEST_ASSERT_NOT_EQUAL(prvKeyHandle, NULLPTR);
01030         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01031         /*#1B*/
01032         result = pal_parseECPrivateKeyFromDER(CsrTests[i].prvkey, CsrTests[i].prvkeyLen, prvKeyHandle);
01033         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01034         /*#1C*/
01035         result = pal_ECCheckKey(grp, prvKeyHandle, PAL_CHECK_PRIVATE_KEY, &goodKey);
01036         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01037         TEST_ASSERT_EQUAL(true, goodKey);
01038 
01039         goodKey = false;
01040         /*#1D*/
01041         result = pal_ECKeyNew(&pubKeyHandle);
01042         TEST_ASSERT_NOT_EQUAL(pubKeyHandle, NULLPTR);
01043         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01044         /*#1E*/
01045         result = pal_parseECPublicKeyFromDER(CsrTests[i].pubkey, CsrTests[i].pubkeyLen, pubKeyHandle);
01046         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01047         /*#1F*/
01048         result = pal_ECCheckKey(grp, pubKeyHandle, PAL_CHECK_PUBLIC_KEY, &goodKey);
01049         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01050         TEST_ASSERT_EQUAL(true, goodKey);
01051         /*#1G*/
01052         result = pal_x509CSRInit(&CSRHandle);
01053         TEST_ASSERT_NOT_EQUAL(CSRHandle, NULLPTR);
01054         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01055         /*#1H*/
01056         result = pal_x509CSRSetSubject(CSRHandle, CsrTests[i].subject_name);
01057         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01058         /*#1I*/
01059         result = pal_x509CSRSetMD(CSRHandle, CsrTests[i].mdType);
01060         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01061         /*#1J*/
01062         result = pal_x509CSRSetKey(CSRHandle, pubKeyHandle, prvKeyHandle);
01063         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01064         /*#1K*/
01065         result = pal_x509CSRSetKeyUsage(CSRHandle, CsrTests[i].keyUsage);
01066         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01067         /*#1L*/
01068         //pal_x509CSRSetExtension - need input from provisioning
01069         reqLen = 0;
01070         result = pal_x509CSRWriteDER(CSRHandle, outDer, sizeof(outDer), &reqLen);
01071         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01072 
01073         TEST_ASSERT_EQUAL(CsrTests[i].derOutLen, reqLen);
01074         TEST_ASSERT_EQUAL_MEMORY(CsrTests[i].derOut, outDer, reqLen);
01075         /*#1M*/
01076         result = pal_x509CSRFree(&CSRHandle);
01077         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01078         /*#1N*/
01079         result = pal_ECKeyFree(&prvKeyHandle);
01080         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01081         /*#1O*/
01082         result = pal_ECKeyFree(&pubKeyHandle);
01083         TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01084     }
01085     /*#2*/
01086     result = pal_ECGroupFree(&grp);
01087     TEST_ASSERT_EQUAL_HEX(PAL_SUCCESS, result);
01088 #endif
01089 }