Jim Carver / Mbed OS mbed-cloud-workshop-connect
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 | 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 }