Mbed Cloud example program for workshop in W27 2018.

Dependencies:   MMA7660 LM75B

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_Crypto.c Source File

pal_plat_Crypto.c

00001 /*
00002 * Copyright (c) 2016 ARM Limited. All rights reserved.
00003 * SPDX-License-Identifier: Apache-2.0
00004 * Licensed under the Apache License, Version 2.0 (the License); you may
00005 * 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, WITHOUT
00012 * 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 #include "stdlib.h"
00017 #include "string.h"
00018 #include "time.h"
00019 #include "pal.h"
00020 #include "pal_plat_Crypto.h"
00021 #include "pal_plat_rtos.h"
00022 #include "mbedtls/aes.h"
00023 #include "mbedtls/x509_crt.h"
00024 #include "mbedtls/ctr_drbg.h"
00025 #include "mbedtls/sha256.h"
00026 #include "mbedtls/md.h"
00027 #include "mbedtls/ccm.h"
00028 #include "mbedtls/entropy.h"
00029 #include "mbedtls/cmac.h"
00030 #include "mbedtls/asn1.h"
00031 #include "mbedtls/ecp.h"
00032 #include "mbedtls/x509_csr.h"
00033 #include "mbedtls/ecdh.h"
00034 #include "mbedtls/oid.h"
00035 #include "mbedtls/platform_time.h"
00036 
00037 
00038 typedef mbedtls_ccm_context palCCM_t;
00039 typedef mbedtls_ecp_group palECGroup_t;
00040 typedef mbedtls_ecp_point palECPoint_t;
00041 typedef mbedtls_mpi palMP_t;
00042 typedef mbedtls_pk_context palECKey_t;
00043 typedef mbedtls_x509write_csr palx509CSR_t; 
00044 typedef mbedtls_cipher_context_t palCipherCtx_t;
00045 
00046 
00047 //! forward declaration
00048 //! This function is based on PAL random algorithm which uses CTR-DRBG algorithm
00049 PAL_PRIVATE int pal_plat_entropySource( void *data, unsigned char *output, size_t len);
00050 
00051 //! forward declarations
00052 //! This function access directly to the plarform entropy source
00053 //! it was added specialy for DRBG reseeding process
00054 PAL_PRIVATE int pal_plat_entropySourceDRBG( void *data, unsigned char *output, size_t len);
00055 
00056 
00057 typedef struct palSign{
00058     mbedtls_mpi r;
00059     mbedtls_mpi s;
00060 }palSignature_t;
00061 
00062 typedef struct palCtrDrbgCtx{
00063     mbedtls_entropy_context entropy;
00064     mbedtls_ctr_drbg_context ctrDrbgCtx;
00065 }palCtrDrbgCtx_t;
00066 
00067 typedef struct palAes{
00068     mbedtls_aes_context platCtx;
00069     unsigned char stream_block[PAL_CRYPT_BLOCK_SIZE];  //The saved stream-block for resuming. Is overwritten by the function.
00070     size_t nc_off;   //The offset in the current stream_block
00071 }palAes_t;
00072 
00073 typedef struct palX509Ctx{
00074     mbedtls_x509_crt crt;
00075 }palX509Ctx_t;
00076 
00077 
00078 typedef struct palMD{
00079      mbedtls_md_context_t md;
00080 }palMD_t;
00081 
00082 #define CRYPTO_PLAT_SUCCESS 0
00083 #define CRYPTO_PLAT_GENERIC_ERROR (-1)
00084 
00085 palStatus_t pal_plat_initCrypto ()
00086 {
00087     palStatus_t status = PAL_SUCCESS;
00088     return status;
00089 }
00090 
00091 palStatus_t pal_plat_cleanupCrypto ()
00092 {
00093     return PAL_SUCCESS;
00094 }
00095 
00096 palStatus_t pal_plat_initAes (palAesHandle_t *aes)
00097 {
00098     palStatus_t status = PAL_SUCCESS;
00099     palAes_t* localCtx = NULL;
00100 
00101     localCtx = (palAes_t*)malloc(sizeof(palAes_t));
00102     if (NULL == localCtx)
00103     {
00104         status = PAL_ERR_CREATION_FAILED ;
00105     }
00106     else
00107     {
00108         mbedtls_aes_init(&localCtx->platCtx);
00109         localCtx->nc_off = 0;
00110         memset(localCtx->stream_block, 0, 16);
00111 
00112         *aes = (palAesHandle_t)localCtx;
00113     }
00114     return status;
00115 }
00116 
00117 palStatus_t pal_plat_freeAes (palAesHandle_t *aes)
00118 {
00119     palStatus_t status = PAL_SUCCESS;
00120     palAes_t* localCtx = NULL;
00121     
00122     localCtx = (palAes_t*)*aes;
00123     
00124     mbedtls_aes_free(&localCtx->platCtx);
00125     free(localCtx);
00126     *aes = NULLPTR;
00127     return status;
00128 }
00129 
00130 palStatus_t pal_plat_setAesKey (palAesHandle_t aes, const unsigned char* key, uint32_t keybits, palAesKeyType_t keyTarget)
00131 {
00132     palStatus_t status = PAL_SUCCESS;
00133     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00134     palAes_t* localCtx = (palAes_t*)aes;
00135 
00136     if (PAL_KEY_TARGET_ENCRYPTION == keyTarget)
00137     {
00138         platStatus = mbedtls_aes_setkey_enc(&localCtx->platCtx, key, keybits);
00139     }
00140     else
00141     {
00142         platStatus = mbedtls_aes_setkey_dec(&localCtx->platCtx, key, keybits);
00143     }
00144 
00145     if (CRYPTO_PLAT_SUCCESS != platStatus)
00146     {
00147         status = PAL_ERR_AES_INVALID_KEY_LENGTH;
00148     }
00149 
00150     return status;    
00151 }
00152 
00153 palStatus_t pal_plat_aesCTR (palAesHandle_t aes, const unsigned char* input, unsigned char* output, size_t inLen, unsigned char iv[16], bool zeroOffset)
00154 {
00155     palStatus_t status = PAL_SUCCESS;
00156     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00157     palAes_t* localCtx = (palAes_t*)aes;
00158 
00159     if (true == zeroOffset)
00160     {
00161         localCtx->nc_off = 0;
00162         memset(localCtx->stream_block, 0, 16);
00163     }
00164 
00165     platStatus = mbedtls_aes_crypt_ctr(&localCtx->platCtx, inLen, &localCtx->nc_off, iv, localCtx->stream_block, input, output);
00166     if (CRYPTO_PLAT_SUCCESS != platStatus)
00167     {
00168         PAL_LOG(ERR, "Crypto aes ctr status %" PRId32 "", platStatus);
00169         status = PAL_ERR_GENERIC_FAILURE;
00170     }
00171     return status;
00172 }
00173 
00174 palStatus_t pal_plat_aesECB (palAesHandle_t aes, const unsigned char input[PAL_CRYPT_BLOCK_SIZE], unsigned char output[PAL_CRYPT_BLOCK_SIZE], palAesMode_t mode)
00175 {
00176     palStatus_t status = PAL_SUCCESS;
00177     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00178     palAes_t* localCtx = (palAes_t*)aes;
00179 
00180     platStatus = mbedtls_aes_crypt_ecb(&localCtx->platCtx, (PAL_AES_ENCRYPT == mode ? MBEDTLS_AES_ENCRYPT : MBEDTLS_AES_DECRYPT), input, output);
00181     if (CRYPTO_PLAT_SUCCESS != platStatus)
00182     {
00183         PAL_LOG(ERR, "Crypto aes ecb status  %" PRId32 "", platStatus);
00184         status = PAL_ERR_GENERIC_FAILURE;
00185     }
00186     return status;
00187 }
00188 
00189 palStatus_t pal_plat_sha256 (const unsigned char* input, size_t inLen, unsigned char* output)
00190 {    
00191     mbedtls_sha256(input, inLen, output, 0);
00192      
00193     return PAL_SUCCESS;
00194 }
00195 
00196 palStatus_t pal_plat_x509Initiate (palX509Handle_t* x509)
00197 {
00198     palStatus_t status = PAL_SUCCESS;
00199     palX509Ctx_t* localCtx = NULL;
00200 
00201     localCtx = (palX509Ctx_t*)malloc(sizeof(palX509Ctx_t));
00202     if (NULL == localCtx)
00203     {
00204         status = PAL_ERR_CREATION_FAILED ;
00205     }
00206     else
00207     {
00208         mbedtls_x509_crt_init(&localCtx->crt);
00209         *x509 = (uintptr_t)localCtx;
00210     }
00211 
00212     return status;
00213 }
00214 
00215 palStatus_t pal_plat_x509CertParse (palX509Handle_t x509, const unsigned char* input, size_t inLen)
00216 {
00217     palStatus_t status = PAL_SUCCESS;
00218     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00219     palX509Ctx_t* localCtx = (palX509Ctx_t*)x509;
00220 
00221      platStatus = mbedtls_x509_crt_parse_der(&localCtx->crt, input, inLen);
00222     if (platStatus < CRYPTO_PLAT_SUCCESS)
00223     {
00224         if (MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE == platStatus)
00225         {
00226             status = PAL_ERR_NOT_SUPPORTED_CURVE;
00227         }
00228         
00229         else if (-(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) == ((-platStatus) & 0xFF80))
00230         {
00231             status = PAL_ERR_INVALID_MD_TYPE;
00232         }
00233         
00234         else
00235         {
00236             status = PAL_ERR_CERT_PARSING_FAILED;
00237         }
00238     }
00239 
00240     return status;
00241 }
00242 
00243 PAL_PRIVATE palStatus_t pal_plat_X509GetField(palX509Ctx_t* x509Ctx, const char* fieldName, void* output, size_t outLenBytes, size_t* actualOutLenBytes)
00244 {
00245     palStatus_t status = PAL_SUCCESS;
00246     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00247     const char *shortName = NULL;
00248     size_t fieldNameLength = 0;
00249     mbedtls_x509_name *x509Name = &x509Ctx->crt.subject;
00250 
00251     if (NULL == fieldName) // other arguments already checked in service layer.
00252     {
00253         return PAL_ERR_INVALID_ARGUMENT ;
00254     }
00255 
00256     fieldNameLength = strlen(fieldName);
00257     while( x509Name ) 
00258     {
00259         platStatus = mbedtls_oid_get_attr_short_name(&x509Name->oid, &shortName);
00260         if (CRYPTO_PLAT_SUCCESS != platStatus)
00261         {
00262             status = PAL_ERR_INVALID_IOD; 
00263             break;  
00264         }
00265         if (strncmp(shortName, fieldName, fieldNameLength) == 0)
00266         {
00267             if (outLenBytes < (x509Name->val.len + 1))
00268             {
00269                 status = PAL_ERR_BUFFER_TOO_SMALL ;
00270                 *actualOutLenBytes = x509Name->val.len + 1;
00271                 break;
00272             }
00273             memcpy(output, x509Name->val.p, x509Name->val.len);
00274             ((char*)output)[x509Name->val.len] = '\0';
00275             *actualOutLenBytes = x509Name->val.len + 1;
00276             break;
00277         }
00278         x509Name = x509Name->next;
00279     }
00280     return status;
00281 }
00282 
00283 PAL_PRIVATE bool pal_isLeapYear(uint8_t year)
00284 {
00285     bool result = false;
00286     if (year % 4 != 0)
00287     {
00288         result = false;
00289     }
00290     else if ((year % 100) != 0)
00291     {
00292         result = true;
00293     } 
00294     else
00295     {
00296         result = ((year % 400) == 0);
00297     }
00298     return result;
00299 }
00300 
00301 PAL_PRIVATE palStatus_t pal_timegm( struct tm *tm, uint64_t* outTime) 
00302 {
00303     uint64_t epoc = 0;
00304     uint8_t palMonthDays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
00305 
00306     if (NULL == outTime || tm->tm_year < 1970)
00307     {
00308         return PAL_ERR_INVALID_ARGUMENT ;
00309     }
00310 
00311     for (uint16_t y = 1970; y < tm->tm_year; ++y)
00312     {
00313         if (pal_isLeapYear(y))
00314         {
00315             epoc += 366 * PAL_SECONDS_PER_DAY;
00316         }
00317         else
00318         {
00319             epoc += 365 * PAL_SECONDS_PER_DAY;
00320         }      
00321     }
00322     
00323     for (uint8_t m = 1; m < tm->tm_mon; ++m) 
00324     {
00325         epoc += palMonthDays[m - 1] * PAL_SECONDS_PER_DAY;
00326         if (m == PAL_FEB_MONTH && pal_isLeapYear(tm->tm_year))
00327         {
00328             epoc += PAL_SECONDS_PER_DAY;
00329         }
00330     }
00331 
00332     epoc += (tm->tm_mday - 1) * PAL_SECONDS_PER_DAY;
00333     epoc += tm->tm_hour * PAL_SECONDS_PER_HOUR;
00334     epoc += tm->tm_min * PAL_SECONDS_PER_MIN;
00335     epoc += tm->tm_sec;
00336     *outTime = epoc;
00337     return PAL_SUCCESS;
00338 }
00339 
00340 
00341 palStatus_t pal_plat_x509CertGetAttribute (palX509Handle_t x509Cert, palX509Attr_t attr, void* output, size_t outLenBytes, size_t* actualOutLenBytes)
00342 {
00343     palStatus_t status = PAL_SUCCESS;
00344     palX509Ctx_t* localCtx = (palX509Ctx_t*)x509Cert;
00345 
00346     switch(attr)
00347     {
00348         case PAL_X509_ISSUER_ATTR:
00349             if (localCtx->crt.issuer_raw.len <= outLenBytes)
00350             {
00351                 memcpy(output, localCtx->crt.issuer_raw.p, localCtx->crt.issuer_raw.len);
00352             }
00353             else
00354             {
00355                 status = PAL_ERR_BUFFER_TOO_SMALL ;
00356             }
00357             *actualOutLenBytes = localCtx->crt.issuer_raw.len;
00358             break;
00359 
00360         case PAL_X509_SUBJECT_ATTR:
00361             if (localCtx->crt.subject_raw.len <= outLenBytes)
00362             {
00363                 memcpy(output, localCtx->crt.subject_raw.p, localCtx->crt.subject_raw.len);
00364             }
00365             else
00366             {
00367                 status = PAL_ERR_BUFFER_TOO_SMALL ;
00368             }
00369             *actualOutLenBytes = localCtx->crt.subject_raw.len;
00370             break;
00371 
00372         case PAL_X509_VALID_FROM:
00373             if ( PAL_CRYPTO_CERT_DATE_LENGTH > outLenBytes)
00374             {
00375                 status = PAL_ERR_BUFFER_TOO_SMALL ;
00376             }
00377             else
00378             {
00379                 struct tm time;
00380                 uint64_t timeOfDay;
00381                 time.tm_year = localCtx->crt.valid_from.year;
00382                 time.tm_mon = localCtx->crt.valid_from.mon;
00383                 time.tm_mday = localCtx->crt.valid_from.day;
00384                 time.tm_hour = localCtx->crt.valid_from.hour;
00385                 time.tm_min = localCtx->crt.valid_from.min;
00386                 time.tm_sec = localCtx->crt.valid_from.sec;
00387                 time.tm_isdst = -1;                                   //unknown DST 
00388                 status = pal_timegm(&time, &timeOfDay);
00389                 if (PAL_SUCCESS != status)
00390                 {
00391                     status = PAL_ERR_TIME_TRANSLATE ;
00392                 }
00393                 else
00394                 {
00395                     memcpy(output, &timeOfDay, PAL_CRYPTO_CERT_DATE_LENGTH);
00396                 }
00397             }
00398             *actualOutLenBytes = PAL_CRYPTO_CERT_DATE_LENGTH;
00399             break;
00400         
00401         case PAL_X509_VALID_TO:
00402             if ( PAL_CRYPTO_CERT_DATE_LENGTH > outLenBytes)
00403             {
00404                 status = PAL_ERR_BUFFER_TOO_SMALL ;
00405             }
00406             else
00407             {
00408                 struct tm time;
00409                 uint64_t timeOfDay;
00410                 time.tm_year = localCtx->crt.valid_to.year;
00411                 time.tm_mon = localCtx->crt.valid_to.mon;
00412                 time.tm_mday = localCtx->crt.valid_to.day;
00413                 time.tm_hour = localCtx->crt.valid_to.hour;
00414                 time.tm_min = localCtx->crt.valid_to.min;
00415                 time.tm_sec = localCtx->crt.valid_to.sec;
00416                 time.tm_isdst = -1;                                 //unknown DST
00417                 status = pal_timegm(&time, &timeOfDay);
00418                 if (PAL_SUCCESS != status)
00419                 {
00420                     status = PAL_ERR_TIME_TRANSLATE ;
00421                 }
00422                 else
00423                 {
00424                     memcpy(output, &timeOfDay, PAL_CRYPTO_CERT_DATE_LENGTH);
00425                 }
00426             }
00427             *actualOutLenBytes = PAL_CRYPTO_CERT_DATE_LENGTH;
00428             break;
00429         
00430         case PAL_X509_CN_ATTR:
00431             status = pal_plat_X509GetField(localCtx, "CN", output, outLenBytes, actualOutLenBytes);
00432             break; 
00433 
00434         case PAL_X509_OU_ATTR:
00435             status = pal_plat_X509GetField(localCtx, "OU", output, outLenBytes, actualOutLenBytes);
00436             break; 
00437         default:
00438            status = PAL_ERR_INVALID_X509_ATTR;
00439     }
00440     return status;
00441 }
00442 
00443 PAL_PRIVATE const mbedtls_x509_crt_profile s_PALProfile =
00444 {
00445     MBEDTLS_X509_ID_FLAG( MBEDTLS_MD_SHA256 ),
00446     MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECKEY ) | MBEDTLS_X509_ID_FLAG( MBEDTLS_PK_ECDSA ),
00447     MBEDTLS_X509_ID_FLAG( MBEDTLS_ECP_DP_SECP256R1 ),
00448     0x7FFFFFFF // RSA not allowed
00449 };
00450 
00451 
00452 palStatus_t pal_plat_x509CertVerify (palX509Handle_t x509Cert, palX509Handle_t x509CertChain)
00453 {
00454     palStatus_t status = PAL_SUCCESS;
00455     palX509Ctx_t* localCert = (palX509Ctx_t*)x509Cert;
00456     palX509Ctx_t* localCAChain = (palX509Ctx_t*)x509CertChain;
00457     //mbedtls_x509_crt_profile profiles = {1,1,1,1};
00458     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00459     uint32_t flags = 0;
00460 
00461     if (NULL == localCAChain)
00462     {
00463         //platStatus = mbedtls_x509_crt_verify(&localCert->crt, NULL, NULL, NULL, &flags, NULL, NULL);
00464         platStatus = mbedtls_x509_crt_verify_with_profile(&localCert->crt, NULL, NULL, &s_PALProfile, NULL, &flags, NULL, NULL);
00465     }
00466     else
00467     {
00468         //platStatus = mbedtls_x509_crt_verify(&localCert->crt, &localCAChain->crt, NULL, NULL, &flags, NULL, NULL);
00469         platStatus = mbedtls_x509_crt_verify_with_profile(&localCert->crt, &localCAChain->crt, NULL, &s_PALProfile, NULL, &flags, NULL, NULL);
00470     }
00471 
00472     if (CRYPTO_PLAT_SUCCESS != platStatus)
00473     {
00474         //! please DO NOT change errors order
00475         if (MBEDTLS_X509_BADCERT_EXPIRED & flags)
00476         {
00477             status = PAL_ERR_X509_BADCERT_EXPIRED;
00478             goto finish;
00479         }
00480         if (MBEDTLS_X509_BADCERT_FUTURE & flags)
00481         {
00482             status = PAL_ERR_X509_BADCERT_FUTURE;
00483             goto finish;
00484         }
00485         if (MBEDTLS_X509_BADCERT_BAD_MD & flags)
00486         {
00487             status = PAL_ERR_X509_BADCERT_BAD_MD;
00488             goto finish;
00489         }
00490         if (MBEDTLS_X509_BADCERT_BAD_PK & flags)
00491         {
00492             status = PAL_ERR_X509_BADCERT_BAD_PK;
00493             goto finish;
00494         }
00495         if (MBEDTLS_X509_BADCERT_BAD_KEY & flags)
00496         {
00497             status = PAL_ERR_X509_BADCERT_BAD_KEY;
00498             goto finish;
00499         }
00500         if (MBEDTLS_X509_BADCERT_NOT_TRUSTED & flags)
00501         {
00502             status = PAL_ERR_X509_BADCERT_NOT_TRUSTED;
00503             goto finish;
00504         }
00505     }
00506 finish:
00507     return status;
00508 }
00509 
00510 palStatus_t pal_plat_x509Free (palX509Handle_t* x509)
00511 {
00512     palStatus_t status = PAL_SUCCESS;
00513     palX509Ctx_t* localCtx = NULL;
00514 
00515     localCtx = (palX509Ctx_t*)*x509;
00516     mbedtls_x509_crt_free(&localCtx->crt);
00517     free(localCtx);
00518     *x509 = NULLPTR;
00519     return status;
00520 }
00521 
00522 palStatus_t pal_plat_mdInit (palMDHandle_t* md, palMDType_t mdType)
00523 {
00524     palStatus_t status = PAL_SUCCESS;
00525     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00526     palMD_t* localCtx = NULL;
00527     const mbedtls_md_info_t* mdInfo = NULL;
00528     mbedtls_md_type_t mdAlg = MBEDTLS_MD_NONE;
00529 
00530     localCtx = (palMD_t*)malloc(sizeof(palMD_t));
00531     if (NULL == localCtx)
00532     {
00533         status = PAL_ERR_CREATION_FAILED ;
00534         goto finish;
00535     }
00536 
00537     
00538     mbedtls_md_init(&localCtx->md);
00539     
00540     switch (mdType)
00541     {
00542         case PAL_SHA256:
00543             mdAlg = MBEDTLS_MD_SHA256;
00544             break;
00545         default:
00546             status = PAL_ERR_INVALID_MD_TYPE;
00547             goto finish;
00548     }
00549 
00550     mdInfo = mbedtls_md_info_from_type(mdAlg);
00551     if (NULL == mdInfo)
00552     {
00553         status = PAL_ERR_INVALID_MD_TYPE;
00554         goto finish;
00555     }
00556 
00557     platStatus = mbedtls_md_setup(&localCtx->md, mdInfo, 0); // 0 because we don't want to use HMAC in mbedTLS to save memory
00558     switch(platStatus)
00559     {
00560         case CRYPTO_PLAT_SUCCESS:
00561             break;
00562         case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
00563             {
00564                 status = PAL_ERR_MD_BAD_INPUT_DATA;
00565                 goto finish;
00566             }
00567         case MBEDTLS_ERR_MD_ALLOC_FAILED:
00568             {
00569                 status = PAL_ERR_CREATION_FAILED ;
00570                 goto finish;
00571             }
00572         default: 
00573             {
00574                 PAL_LOG(ERR, "Crypto md start setup  %" PRId32 "", platStatus);
00575                 status = PAL_ERR_GENERIC_FAILURE;
00576                 goto finish;
00577             }
00578     }
00579     
00580     platStatus = mbedtls_md_starts(&localCtx->md);
00581     switch(platStatus)
00582     {
00583         case CRYPTO_PLAT_SUCCESS:
00584             break;
00585         case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
00586             {
00587                 status = PAL_ERR_MD_BAD_INPUT_DATA;
00588                 goto finish;
00589             }
00590         default: 
00591             {
00592                 PAL_LOG(ERR, "Crypto md start status  %" PRId32 "", platStatus);
00593                 status = PAL_ERR_GENERIC_FAILURE;
00594                 goto finish;
00595             }
00596     }
00597 
00598     *md = (uintptr_t)localCtx;
00599 finish:
00600     if (PAL_SUCCESS != status && NULL != localCtx)
00601     {
00602         free(localCtx);
00603     }
00604     return status;
00605 }
00606 
00607 palStatus_t pal_plat_mdUpdate (palMDHandle_t md, const unsigned char* input, size_t inLen)
00608 {
00609     palStatus_t status = PAL_SUCCESS;
00610     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00611     palMD_t* localCtx = (palMD_t*)md;
00612 
00613     platStatus =  mbedtls_md_update(&localCtx->md, input, inLen);
00614     switch(platStatus)
00615     {
00616         case CRYPTO_PLAT_SUCCESS:
00617             break;
00618         case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
00619             status = PAL_ERR_MD_BAD_INPUT_DATA;
00620             break;
00621         default: 
00622             {
00623                 PAL_LOG(ERR, "Crypto md update status %" PRId32 "", platStatus);
00624                 status = PAL_ERR_GENERIC_FAILURE;
00625             }
00626     }
00627     return status;
00628 }
00629 
00630 palStatus_t pal_plat_mdGetOutputSize (palMDHandle_t md, size_t* bufferSize)
00631 {
00632     palStatus_t status = PAL_SUCCESS;
00633     palMD_t* localCtx = (palMD_t*)md;
00634 
00635     if (NULL != localCtx->md.md_info)
00636     {
00637         *bufferSize = (size_t)mbedtls_md_get_size(localCtx->md.md_info);
00638     }
00639     else
00640     {
00641         PAL_LOG(ERR, "Crypto md get size error");
00642         status = PAL_ERR_GENERIC_FAILURE;
00643     }
00644     
00645     return status;
00646 }
00647 
00648 palStatus_t pal_plat_mdFinal (palMDHandle_t md, unsigned char* output)
00649 {
00650     palStatus_t status = PAL_SUCCESS;
00651     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00652     palMD_t* localCtx = (palMD_t*)md;
00653 
00654     platStatus =  mbedtls_md_finish(&localCtx->md, output);
00655     switch(platStatus)
00656     {
00657         case CRYPTO_PLAT_SUCCESS:
00658             break;
00659         case MBEDTLS_ERR_MD_BAD_INPUT_DATA:
00660             status = PAL_ERR_MD_BAD_INPUT_DATA;
00661             break;
00662         default: 
00663             {
00664                 PAL_LOG(ERR, "Crypto md finish status %" PRId32 "", platStatus);
00665                 status = PAL_ERR_GENERIC_FAILURE;
00666             }
00667     } 
00668     return status;
00669 }
00670 
00671 palStatus_t pal_plat_mdFree (palMDHandle_t* md)
00672 {
00673     palStatus_t status = PAL_SUCCESS;
00674     palMD_t* localCtx = NULL;
00675 
00676     localCtx = (palMD_t*)*md;
00677     mbedtls_md_free(&localCtx->md);
00678     free(localCtx);
00679     *md = NULLPTR;
00680     return status;
00681 }
00682 
00683 palStatus_t pal_plat_verifySignature (palX509Handle_t x509, palMDType_t mdType, const unsigned char *hash, size_t hashLen, const unsigned char *sig, size_t sigLen)
00684 {
00685     palStatus_t status = PAL_SUCCESS;
00686     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00687     mbedtls_md_type_t mdAlg = MBEDTLS_MD_NONE;
00688     palX509Ctx_t* localCtx = (palX509Ctx_t*)x509;
00689 
00690     switch (mdType)
00691     {
00692         case PAL_SHA256:
00693             mdAlg = MBEDTLS_MD_SHA256;
00694             break;
00695         default:
00696             status = PAL_ERR_INVALID_MD_TYPE;
00697             goto finish;
00698     }
00699 
00700     platStatus = mbedtls_pk_verify(&localCtx->crt.pk, mdAlg, hash, hashLen, sig, sigLen);
00701     if (platStatus < CRYPTO_PLAT_SUCCESS)
00702     {
00703         status = PAL_ERR_PK_SIG_VERIFY_FAILED;
00704     }
00705 finish:
00706     return status;
00707 }
00708 
00709 palStatus_t pal_plat_ASN1GetTag (unsigned char **position, const unsigned char *end, size_t *len, uint8_t tag )
00710 {
00711     palStatus_t status = PAL_SUCCESS;
00712     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00713     int platTag = 0;
00714 
00715     switch (tag & PAL_ASN1_CLASS_BITS) 
00716     {
00717         case 0x00:
00718             //MBEDTLS_ASN1_PRIMITIVE
00719             break;
00720         case PAL_ASN1_CONTEXT_SPECIFIC:
00721             platTag |= MBEDTLS_ASN1_CONTEXT_SPECIFIC;
00722             break;
00723         default:
00724             status = PAL_ERR_NOT_SUPPORTED_ASN_TAG;
00725             goto finish;
00726     }
00727 
00728     if (tag & PAL_ASN1_CONSTRUCTED)
00729     {
00730         platTag |= MBEDTLS_ASN1_CONSTRUCTED;
00731     }
00732 
00733 
00734     switch(tag & PAL_ASN1_TAG_BITS)
00735     {
00736     case PAL_ASN1_BOOLEAN:
00737         platTag |= MBEDTLS_ASN1_BOOLEAN;
00738         break;
00739     case PAL_ASN1_INTEGER:
00740         platTag |= MBEDTLS_ASN1_INTEGER;
00741             break;
00742     case PAL_ASN1_BIT_STRING:
00743         platTag |= MBEDTLS_ASN1_BIT_STRING;
00744             break;
00745     case PAL_ASN1_OCTET_STRING:
00746         platTag |= MBEDTLS_ASN1_OCTET_STRING;
00747                 break;
00748     case PAL_ASN1_NULL:
00749         platTag |= MBEDTLS_ASN1_NULL;
00750                 break;
00751     case PAL_ASN1_OID:
00752         platTag |= MBEDTLS_ASN1_OID;
00753                 break;
00754     case PAL_ASN1_UTF8_STRING:
00755         platTag |= MBEDTLS_ASN1_UTF8_STRING;
00756                 break;
00757     case PAL_ASN1_SEQUENCE:
00758         platTag |= MBEDTLS_ASN1_SEQUENCE;
00759                 break;
00760     case PAL_ASN1_SET:
00761         platTag |= MBEDTLS_ASN1_SET;
00762                 break;
00763     case PAL_ASN1_PRINTABLE_STRING:
00764         platTag |= MBEDTLS_ASN1_PRINTABLE_STRING;
00765                 break;
00766     case PAL_ASN1_T61_STRING:
00767         platTag |= MBEDTLS_ASN1_T61_STRING;
00768                 break;
00769     case PAL_ASN1_IA5_STRING:
00770         platTag |= MBEDTLS_ASN1_IA5_STRING;
00771                 break;
00772     case PAL_ASN1_UTC_TIME:
00773         platTag |= MBEDTLS_ASN1_UTC_TIME;
00774                 break;
00775     case PAL_ASN1_GENERALIZED_TIME:
00776         platTag |= MBEDTLS_ASN1_GENERALIZED_TIME;
00777                 break;
00778     case PAL_ASN1_UNIVERSAL_STRING:
00779         platTag |= MBEDTLS_ASN1_UNIVERSAL_STRING;
00780                 break;
00781     case PAL_ASN1_BMP_STRING:
00782         platTag |= MBEDTLS_ASN1_BMP_STRING;
00783                 break;
00784     default:
00785         status = PAL_ERR_NOT_SUPPORTED_ASN_TAG;
00786         goto finish;
00787     }
00788 
00789     platStatus =  mbedtls_asn1_get_tag(position, end, len, platTag);
00790     if (platStatus < CRYPTO_PLAT_SUCCESS)
00791     {
00792         status = PAL_ERR_ASN1_UNEXPECTED_TAG;
00793     }
00794 finish:
00795     return status;
00796 }
00797 
00798 palStatus_t pal_plat_CCMInit (palCCMHandle_t* ctx)
00799 {
00800     palStatus_t status = PAL_SUCCESS;
00801     palCCM_t* ccmCtx = NULL;
00802 
00803     ccmCtx = (palCCM_t*)malloc(sizeof(palCCM_t));
00804     if (NULL == ccmCtx)
00805     {
00806         status = PAL_ERR_NO_MEMORY ;
00807     }
00808     else
00809     {
00810         mbedtls_ccm_init(ccmCtx);
00811         *ctx = (palCCMHandle_t)ccmCtx;
00812     }
00813 
00814     return status;
00815 }
00816 
00817 palStatus_t pal_plat_CCMFree (palCCMHandle_t* ctx)
00818 {
00819     palStatus_t status = PAL_SUCCESS;
00820     palCCM_t* ccmCtx = (palCCM_t*)*ctx;
00821 
00822     mbedtls_ccm_free(ccmCtx);
00823     free(ccmCtx);
00824     *ctx = NULLPTR;
00825     return status;
00826 }
00827 
00828 palStatus_t pal_plat_CCMSetKey (palCCMHandle_t ctx, palCipherID_t id, const unsigned char *key, unsigned int keybits)
00829 {
00830     palStatus_t status = PAL_SUCCESS;
00831     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00832     palCCM_t* ccmCtx = (palCCM_t*)ctx;
00833     mbedtls_cipher_id_t mbedtls_cipher_id;
00834 
00835     switch (id) 
00836     {
00837         case PAL_CIPHER_ID_AES:
00838             mbedtls_cipher_id = MBEDTLS_CIPHER_ID_AES;
00839             break;
00840         default:
00841             return PAL_ERR_INVALID_ARGUMENT ;
00842     }
00843 
00844     platStatus = mbedtls_ccm_setkey(ccmCtx, mbedtls_cipher_id, key, keybits);
00845 
00846     switch(platStatus)
00847     {
00848     case CRYPTO_PLAT_SUCCESS:
00849         status = PAL_SUCCESS;
00850         break;
00851     default:
00852         {
00853             PAL_LOG(ERR, "Crypto ccm setkey status %" PRId32 "", platStatus);
00854             status = PAL_ERR_GENERIC_FAILURE;
00855         }
00856     }
00857     return status;
00858 }
00859 
00860 palStatus_t pal_plat_CCMDecrypt (palCCMHandle_t ctx, unsigned char* input, size_t inLen, unsigned char* iv, size_t ivLen, unsigned char* add, size_t addLen, unsigned char* tag, size_t tagLen, unsigned char* output)
00861 {
00862     palStatus_t status = PAL_SUCCESS;
00863     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00864     palCCM_t* ccmCtx = (palCCM_t*)ctx;
00865 
00866     platStatus = mbedtls_ccm_auth_decrypt(ccmCtx, inLen, iv, ivLen, add, addLen, input, output, tag, tagLen);
00867     if (CRYPTO_PLAT_SUCCESS != platStatus)
00868     {
00869         switch(platStatus)
00870         {
00871         default:
00872             {
00873                 PAL_LOG(ERR, "Crypto ccm decrypt status %" PRId32 "", platStatus);
00874                 status = PAL_ERR_GENERIC_FAILURE;
00875             }
00876         }
00877     }
00878     return status;
00879 }
00880 
00881 palStatus_t pal_plat_CCMEncrypt (palCCMHandle_t ctx, unsigned char* input, size_t inLen, unsigned char* iv, size_t ivLen, unsigned char* add, size_t addLen, unsigned char* output, unsigned char* tag, size_t tagLen)
00882 {
00883     palStatus_t status = PAL_SUCCESS;
00884     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00885     palCCM_t* ccmCtx = (palCCM_t*)ctx;
00886 
00887     platStatus = mbedtls_ccm_encrypt_and_tag(ccmCtx, inLen, iv, ivLen, add, addLen, input, output, tag, tagLen);
00888     if (CRYPTO_PLAT_SUCCESS != platStatus)
00889     {
00890         switch(platStatus)
00891         {
00892         default:
00893             {
00894                 PAL_LOG(ERR, "Crypto ccm encrypt status %" PRId32 "", platStatus);
00895                 status = PAL_ERR_GENERIC_FAILURE;
00896             }
00897         }
00898     }
00899     return status;
00900 }
00901 
00902 palStatus_t pal_plat_CtrDRBGInit (palCtrDrbgCtxHandle_t* ctx)
00903 {
00904     palStatus_t status = PAL_SUCCESS;
00905     palCtrDrbgCtx_t* palCtrDrbgCtx = NULL;
00906 
00907     palCtrDrbgCtx = (palCtrDrbgCtx_t*)malloc(sizeof(palCtrDrbgCtx_t));
00908     if (NULL == palCtrDrbgCtx)
00909     {
00910         status = PAL_ERR_NO_MEMORY ;
00911     }
00912     else
00913     {
00914         mbedtls_ctr_drbg_init(&palCtrDrbgCtx->ctrDrbgCtx);
00915         mbedtls_entropy_init(&palCtrDrbgCtx->entropy);
00916         *ctx = (palCtrDrbgCtxHandle_t)palCtrDrbgCtx;
00917     }
00918 
00919     return status;
00920 }
00921 
00922 palStatus_t pal_plat_CtrDRBGFree (palCtrDrbgCtxHandle_t* ctx)
00923 {
00924     palStatus_t status = PAL_SUCCESS;
00925     palCtrDrbgCtx_t* palCtrDrbgCtx = NULL;
00926 
00927     palCtrDrbgCtx = (palCtrDrbgCtx_t*)*ctx;
00928     if (NULL == palCtrDrbgCtx)
00929     {
00930         return PAL_ERR_INVALID_ARGUMENT ;
00931     }
00932     mbedtls_ctr_drbg_free(&palCtrDrbgCtx->ctrDrbgCtx);
00933     mbedtls_entropy_free(&palCtrDrbgCtx->entropy);
00934     free(palCtrDrbgCtx);
00935     *ctx = NULLPTR;
00936 
00937     return status;
00938 }
00939 
00940 palStatus_t pal_plat_CtrDRBGSeed (palCtrDrbgCtxHandle_t ctx, const void* seed, size_t len)
00941 {
00942     palStatus_t status = PAL_SUCCESS;
00943     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00944     palCtrDrbgCtx_t* palCtrDrbgCtx = (palCtrDrbgCtx_t*)ctx;
00945 
00946     if (NULL == palCtrDrbgCtx)
00947     {
00948         return PAL_ERR_INVALID_ARGUMENT ;
00949     }
00950 
00951     platStatus = mbedtls_ctr_drbg_seed(&palCtrDrbgCtx->ctrDrbgCtx, pal_plat_entropySourceDRBG, &palCtrDrbgCtx->entropy, seed, len);
00952     if (CRYPTO_PLAT_SUCCESS != platStatus)
00953     {
00954         switch(platStatus)
00955         {
00956             case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
00957                 status = PAL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
00958                 break;
00959             default:
00960                 {
00961                     PAL_LOG(ERR, "Crypto ctrdrbg seed status %" PRId32 "", platStatus);
00962                     status = PAL_ERR_GENERIC_FAILURE;
00963                 }
00964         }
00965     }
00966     return status;
00967 }
00968 
00969 palStatus_t pal_plat_CtrDRBGGenerate (palCtrDrbgCtxHandle_t ctx, unsigned char* out, size_t len)
00970 {
00971     palStatus_t status = PAL_SUCCESS;
00972     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
00973     palCtrDrbgCtx_t* palCtrDrbgCtx = (palCtrDrbgCtx_t*)ctx;
00974 
00975     platStatus = mbedtls_ctr_drbg_random(&palCtrDrbgCtx->ctrDrbgCtx, out, len);
00976     if (CRYPTO_PLAT_SUCCESS != platStatus)
00977     {
00978         switch(platStatus)
00979         {
00980             case MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED:
00981                 status = PAL_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED;
00982                 break;
00983             case MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG:
00984                 status = PAL_ERR_CTR_DRBG_REQUEST_TOO_BIG;
00985                 break;
00986             default:
00987                 {
00988                     PAL_LOG(ERR, "Crypto ctrdrbg generate status %" PRId32 "", platStatus);
00989                     status = PAL_ERR_GENERIC_FAILURE;
00990                 }
00991         }
00992     }
00993     return status;
00994 }
00995 
00996 palStatus_t pal_plat_cipherCMAC (const unsigned char *key, size_t keyLenInBits, const unsigned char *input, size_t inputLenInBytes, unsigned char *output)
00997 {
00998     palStatus_t status = PAL_SUCCESS;
00999     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01000     const mbedtls_cipher_info_t *cipherInfo;
01001 
01002     cipherInfo = mbedtls_cipher_info_from_values(MBEDTLS_CIPHER_ID_AES, keyLenInBits, MBEDTLS_MODE_ECB);
01003     if (NULL == cipherInfo)
01004     {
01005         PAL_LOG(ERR, "Crypto cipher cmac error");
01006         status = PAL_ERR_CMAC_GENERIC_FAILURE;
01007         goto finish;
01008     }
01009 
01010     platStatus = mbedtls_cipher_cmac( cipherInfo, key, keyLenInBits, input, inputLenInBytes, output);
01011     if (CRYPTO_PLAT_SUCCESS != platStatus)
01012     {
01013         PAL_LOG(ERR, "Crypto cipher cmac status %" PRId32 "", platStatus);
01014         status = PAL_ERR_CMAC_GENERIC_FAILURE;
01015     }
01016 finish:
01017     return status;
01018 }
01019 
01020 palStatus_t pal_plat_CMACStart (palCMACHandle_t *ctx, const unsigned char *key, size_t keyLenBits, palCipherID_t cipherID)
01021 {
01022     palStatus_t status = PAL_SUCCESS;
01023     palCipherCtx_t* localCipher = NULL;
01024     const mbedtls_cipher_info_t* cipherInfo = NULL;
01025     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01026     mbedtls_cipher_type_t platType = MBEDTLS_CIPHER_NONE;
01027 
01028     switch(cipherID)
01029     {
01030         case PAL_CIPHER_ID_AES:
01031             platType = MBEDTLS_CIPHER_AES_128_ECB;
01032             break;
01033         default:
01034             status = PAL_ERR_INVALID_CIPHER_ID;
01035             goto finish;
01036     }
01037 
01038     cipherInfo = mbedtls_cipher_info_from_type(platType);
01039     if (NULL == cipherInfo)
01040     {
01041         PAL_LOG(ERR, "Crypto cmac cipher info error");
01042         status = PAL_ERR_CMAC_GENERIC_FAILURE;
01043         goto finish;
01044     }
01045 
01046     localCipher = (palCipherCtx_t*)malloc(sizeof(palCipherCtx_t));
01047     if (NULL == localCipher)
01048     {
01049         status = PAL_ERR_NO_MEMORY ;
01050         goto finish;
01051     }
01052 
01053     mbedtls_cipher_init(localCipher);
01054     platStatus = mbedtls_cipher_setup(localCipher, cipherInfo);
01055     if (CRYPTO_PLAT_SUCCESS != platStatus)
01056     {
01057         PAL_LOG(ERR, "Crypto cmac cipher setup status %" PRId32 ".", platStatus);
01058         status = PAL_ERR_CMAC_GENERIC_FAILURE;
01059         goto finish;
01060     }
01061 
01062     platStatus = mbedtls_cipher_cmac_starts(localCipher, key, keyLenBits);
01063     if (CRYPTO_PLAT_SUCCESS != platStatus)
01064     {
01065         status = PAL_ERR_CMAC_START_FAILED;
01066         goto finish;
01067     }
01068 
01069     *ctx = (palCMACHandle_t)localCipher;
01070 finish:
01071     if (PAL_SUCCESS != status && NULL != localCipher)
01072     {
01073         free(localCipher);
01074     }
01075     return status;
01076 }
01077 
01078 palStatus_t pal_plat_CMACUpdate (palCMACHandle_t ctx, const unsigned char *input, size_t inLen)
01079 {
01080     palStatus_t status = PAL_SUCCESS;
01081     palCipherCtx_t* localCipher = (palCipherCtx_t*)ctx;
01082     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01083 
01084     platStatus = mbedtls_cipher_cmac_update(localCipher, input, inLen);
01085     if (CRYPTO_PLAT_SUCCESS != platStatus)
01086     {
01087         status = PAL_ERR_CMAC_UPDATE_FAILED;
01088     }
01089 
01090     return status;
01091 }
01092 
01093 palStatus_t pal_plat_CMACFinish (palCMACHandle_t *ctx, unsigned char *output, size_t* outLen)
01094 {
01095     palStatus_t status = PAL_SUCCESS;
01096     palCipherCtx_t* localCipher = NULL;
01097     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01098 
01099     localCipher = (palCipherCtx_t*)*ctx;
01100     if (NULL == localCipher->cipher_info)
01101     {
01102         return PAL_ERR_INVALID_ARGUMENT ;
01103     }
01104 
01105     platStatus = mbedtls_cipher_cmac_finish(localCipher, output);
01106     if (CRYPTO_PLAT_SUCCESS != platStatus)
01107     {
01108         status = PAL_ERR_CMAC_FINISH_FAILED;
01109     }
01110     else
01111     {
01112         *outLen = localCipher->cipher_info->block_size;
01113     }
01114 
01115     
01116 
01117     mbedtls_cipher_free(localCipher);
01118     free(localCipher);
01119     *ctx = NULLPTR;
01120     return status;
01121 }
01122 
01123 palStatus_t pal_plat_mdHmacSha256 (const unsigned char *key, size_t keyLenInBytes, const unsigned char *input, size_t inputLenInBytes, unsigned char *output, size_t* outputLenInBytes)
01124 {
01125     const mbedtls_md_info_t *md_info = NULL;
01126     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01127     palStatus_t status = PAL_SUCCESS;
01128 
01129     md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256);
01130     if (NULL == md_info)
01131     {
01132         PAL_LOG(ERR, "Crypto hmac sha256 md info error");
01133         status = PAL_ERR_HMAC_GENERIC_FAILURE;
01134     }
01135 
01136     if (PAL_SUCCESS == status)
01137     {
01138         platStatus = mbedtls_md_hmac(md_info, key, keyLenInBytes, input, inputLenInBytes, output);
01139         if (platStatus != CRYPTO_PLAT_SUCCESS)
01140         {
01141             if (platStatus == MBEDTLS_ERR_MD_BAD_INPUT_DATA)
01142             {
01143                 status = PAL_ERR_MD_BAD_INPUT_DATA;
01144             }
01145             else
01146             {
01147                 PAL_LOG(ERR, "Crypto hmac status %" PRId32 "", platStatus);
01148                 status = PAL_ERR_HMAC_GENERIC_FAILURE;
01149             }
01150         }
01151     }
01152 
01153     if ((NULL != outputLenInBytes) && (PAL_SUCCESS == status))
01154     {
01155         *outputLenInBytes = (size_t)mbedtls_md_get_size(md_info);
01156     }
01157 
01158     return status;
01159 }
01160 
01161 //! Check EC private key function. 
01162 PAL_PRIVATE palStatus_t pal_plat_ECCheckPrivateKey(palECGroup_t* ecpGroup, palECKeyHandle_t key, bool *verified)
01163 {
01164     palStatus_t status = PAL_SUCCESS;
01165     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01166     palECKey_t* privateKey = (palECKey_t*)key;
01167     mbedtls_mpi* prvMP = NULL;
01168 
01169     if (NULL == ecpGroup || NULL == privateKey || NULL == verified || NULL == (mbedtls_ecp_keypair*)privateKey->pk_ctx)
01170     {
01171         return PAL_ERR_INVALID_ARGUMENT ;
01172     }
01173 
01174     prvMP = &((mbedtls_ecp_keypair*)privateKey->pk_ctx)->d;
01175 
01176     platStatus =  mbedtls_ecp_check_privkey(ecpGroup, prvMP);
01177     if (CRYPTO_PLAT_SUCCESS != platStatus)
01178     {
01179         status = PAL_ERR_PRIVATE_KEY_VARIFICATION_FAILED;
01180     }
01181     else
01182     {
01183         *verified = true;
01184     }
01185     
01186     return status;
01187 }
01188 
01189 //! Check EC public key function.
01190 PAL_PRIVATE palStatus_t pal_plat_ECCheckPublicKey(palECGroup_t* ecpGroup, palECKeyHandle_t key, bool *verified)
01191 {
01192     palStatus_t status = PAL_SUCCESS;
01193     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01194     palECKey_t* publicKey = (palECKey_t*)key;
01195     mbedtls_ecp_point* pubPoint = NULL;
01196 
01197     if (NULL == ecpGroup || NULL == publicKey || NULL == verified || NULL == (mbedtls_ecp_keypair*)publicKey->pk_ctx)
01198     {
01199         return PAL_ERR_INVALID_ARGUMENT ;
01200     }
01201 
01202     pubPoint = &((mbedtls_ecp_keypair*)publicKey->pk_ctx)->Q;
01203 
01204     platStatus =  mbedtls_ecp_check_pubkey(ecpGroup, pubPoint);
01205     if (CRYPTO_PLAT_SUCCESS != platStatus)
01206     {
01207         status = PAL_ERR_PUBLIC_KEY_VARIFICATION_FAILED;
01208     }
01209     else
01210     {
01211         *verified = true;
01212     }
01213     
01214     return status;
01215 }
01216 
01217 palStatus_t pal_plat_ECCheckKey (palCurveHandle_t grp, palECKeyHandle_t key, uint32_t type, bool *verified)
01218 {
01219     palStatus_t status = PAL_SUCCESS;
01220     palECGroup_t* ecpGroup = (palECGroup_t*)grp;
01221 
01222     *verified = false;
01223 
01224     if ((PAL_CHECK_PRIVATE_KEY & type) != 0)
01225     {
01226         status = pal_plat_ECCheckPrivateKey(ecpGroup, key, verified);
01227     }
01228 
01229     if ((PAL_SUCCESS == status) && ((PAL_CHECK_PUBLIC_KEY & type) != 0))
01230     {
01231         status = pal_plat_ECCheckPublicKey(ecpGroup, key, verified);
01232     }
01233 
01234     return status;
01235 }
01236 
01237 
01238 palStatus_t pal_plat_ECKeyNew (palECKeyHandle_t* key)
01239 {
01240     palStatus_t status = PAL_SUCCESS;
01241     palECKey_t* localECKey = NULL;
01242 
01243     localECKey = (palECKey_t*)malloc(sizeof(palECKey_t));
01244     if (NULL == localECKey)
01245     {
01246         status = PAL_ERR_NO_MEMORY ;
01247     }
01248     else
01249     {
01250         mbedtls_pk_init(localECKey);
01251         *key = (palECKeyHandle_t)localECKey;
01252     }
01253     
01254     return status;
01255 }
01256 
01257 palStatus_t pal_plat_ECKeyFree (palECKeyHandle_t* key)
01258 {
01259     palECKey_t* localECKey = NULL;
01260 
01261     localECKey = (palECKey_t*)*key;
01262     mbedtls_pk_free(localECKey);
01263     free(localECKey);
01264     *key = NULLPTR;
01265     return PAL_SUCCESS;
01266 }
01267 
01268 //! Check if the given data is a valid PEM format or not by checking the
01269 //! the header and the footer of the data.
01270 PAL_PRIVATE bool pal_plat_isPEM(const unsigned char* key, size_t keyLen)
01271 {
01272     bool result = false;
01273     const unsigned char *s1 = NULL;
01274     const unsigned char *s2 = NULL;
01275 
01276     s1 = (unsigned char *) strstr( (const char *) key, "-----BEGIN ");
01277     if (NULL != s1)
01278     {
01279         result = true;
01280     }
01281     else
01282     {
01283         s2 = (unsigned char *) strstr( (const char *) key, "-----END " );
01284         if (NULL != s2)
01285         {
01286             result = true;
01287         }
01288     }
01289 
01290     return result;
01291 }
01292 
01293 palStatus_t pal_plat_parseECPrivateKeyFromDER (const unsigned char* prvDERKey, size_t keyLen, palECKeyHandle_t key)
01294 {
01295     palStatus_t status = PAL_SUCCESS;
01296     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01297     palECKey_t* localECKey = (palECKey_t*)key;
01298 
01299     if (pal_plat_isPEM(prvDERKey, keyLen))
01300     {
01301         return PAL_ERR_INVALID_ARGUMENT ;
01302     }
01303 
01304     platStatus = mbedtls_pk_parse_key(localECKey, prvDERKey, keyLen, NULL, 0);
01305     switch(platStatus)
01306     {
01307         case CRYPTO_PLAT_SUCCESS:
01308             break;
01309         case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
01310             status = PAL_ERR_PK_UNKNOWN_PK_ALG;
01311             break;
01312         case MBEDTLS_ERR_PK_KEY_INVALID_VERSION:
01313             status = PAL_ERR_PK_KEY_INVALID_VERSION;
01314             break;
01315         case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
01316             status = PAL_ERR_PK_KEY_INVALID_FORMAT;
01317             break;
01318         case MBEDTLS_ERR_PK_PASSWORD_REQUIRED:
01319             status = PAL_ERR_PK_PASSWORD_REQUIRED;
01320             break;
01321         default:
01322             status = PAL_ERR_PARSING_PRIVATE_KEY;
01323     }
01324 
01325     return status;
01326 }
01327 
01328 palStatus_t pal_plat_parseECPublicKeyFromDER (const unsigned char* pubDERKey, size_t keyLen, palECKeyHandle_t key)
01329 {
01330     palStatus_t status = PAL_SUCCESS;
01331     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01332     palECKey_t* localECKey = (palECKey_t*)key;
01333 
01334     if (pal_plat_isPEM(pubDERKey, keyLen))
01335     {
01336         return PAL_ERR_INVALID_ARGUMENT ;
01337     }
01338 
01339     platStatus = mbedtls_pk_parse_public_key(localECKey, pubDERKey, keyLen);
01340     switch(platStatus)
01341     {
01342         case CRYPTO_PLAT_SUCCESS:
01343             break;
01344         case MBEDTLS_ERR_PK_UNKNOWN_PK_ALG:
01345             status = PAL_ERR_PK_UNKNOWN_PK_ALG;
01346             break;
01347         case MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE:
01348             status = PAL_ERR_NOT_SUPPORTED_CURVE;
01349             break;
01350         case MBEDTLS_ERR_PK_KEY_INVALID_FORMAT:
01351             status = PAL_ERR_PK_KEY_INVALID_FORMAT;
01352             break;
01353         case MBEDTLS_ERR_PK_INVALID_PUBKEY + MBEDTLS_ERR_ASN1_LENGTH_MISMATCH: //This is how mbedTLS returns erros for this function
01354             status = PAL_ERR_PK_INVALID_PUBKEY_AND_ASN1_LEN_MISMATCH;
01355             break;
01356         case MBEDTLS_ERR_ECP_INVALID_KEY:
01357             status = PAL_ERR_ECP_INVALID_KEY;
01358             break;
01359         default:
01360             status = PAL_ERR_PARSING_PUBLIC_KEY;
01361     }
01362 
01363     return status;
01364 }
01365 
01366 //! Move data from the end of the buffer to the begining, this function is needed since mbedTLS
01367 //! write functions write the data at the end of the buffers.
01368 PAL_PRIVATE void moveDataToBufferStart(unsigned char* buffer, size_t bufferSize, size_t actualSize)
01369 {
01370     size_t j = 0;
01371     size_t i = bufferSize - actualSize;
01372     if (bufferSize == actualSize)
01373     {
01374         return;
01375     }
01376 
01377     for( ; j < actualSize ; ++i , ++j)
01378     {
01379         buffer[j] = buffer[i];
01380         buffer[i] = (unsigned char)0;
01381     }
01382 }
01383 
01384 palStatus_t pal_plat_writePrivateKeyToDer (palECKeyHandle_t key, unsigned char* derBuffer, size_t bufferSize, size_t* actualSize)
01385 {
01386     palStatus_t status = PAL_SUCCESS;
01387     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01388     palECKey_t* localECKey = (palECKey_t*)key;
01389 
01390     platStatus = mbedtls_pk_write_key_der(localECKey, derBuffer, bufferSize);
01391     if (CRYPTO_PLAT_SUCCESS < platStatus)
01392     {
01393         *actualSize = platStatus;
01394         moveDataToBufferStart(derBuffer, bufferSize, *actualSize);
01395     }
01396     else
01397     {
01398         status = PAL_ERR_FAILED_TO_WRITE_PRIVATE_KEY;
01399     }
01400 
01401     return status;
01402 }
01403 
01404 palStatus_t pal_plat_writePublicKeyToDer (palECKeyHandle_t key, unsigned char* derBuffer, size_t bufferSize, size_t* actualSize)
01405 {
01406     palStatus_t status = PAL_SUCCESS;
01407     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01408     palECKey_t* localECKey = (palECKey_t*)key;
01409 
01410     platStatus = mbedtls_pk_write_pubkey_der(localECKey, derBuffer, bufferSize);
01411     if (CRYPTO_PLAT_SUCCESS < platStatus)
01412     {
01413         *actualSize = platStatus;
01414         moveDataToBufferStart(derBuffer, bufferSize, *actualSize);
01415     }
01416     else
01417     {
01418         status = PAL_ERR_FAILED_TO_WRITE_PUBLIC_KEY;
01419     }
01420 
01421     return status;
01422 }
01423 
01424 palStatus_t pal_plat_ECKeyGenerateKey (palGroupIndex_t grpID, palECKeyHandle_t key)
01425 {
01426     palStatus_t status = PAL_SUCCESS;
01427     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01428     mbedtls_ecp_group_id platCurve = MBEDTLS_ECP_DP_NONE;
01429     palECKey_t* localECKey = (palECKey_t*)key;
01430     mbedtls_ecp_keypair* keyPair = NULL;
01431 
01432     keyPair = (mbedtls_ecp_keypair*)localECKey->pk_ctx;
01433 
01434     switch(grpID)
01435     {
01436         case PAL_ECP_DP_SECP256R1:
01437             platCurve = MBEDTLS_ECP_DP_SECP256R1;
01438             break;
01439         default: 
01440             status = PAL_ERR_NOT_SUPPORTED_CURVE;
01441             goto finish;
01442     }
01443 
01444     platStatus = mbedtls_ecp_gen_key(platCurve, keyPair, pal_plat_entropySource, NULL);
01445     if (CRYPTO_PLAT_SUCCESS != platStatus)
01446     {
01447         status = PAL_ERR_KEYPAIR_GEN_FAIL;
01448     }
01449 
01450 finish:
01451     return status;
01452 }
01453 
01454 palStatus_t pal_plat_ECKeyGetCurve (palECKeyHandle_t key, palGroupIndex_t* grpID)
01455 {
01456     palStatus_t status = PAL_SUCCESS;
01457     palECKey_t* localECKey = (palECKey_t*)key;
01458     mbedtls_ecp_keypair* keyPair = NULL;
01459 
01460     if (NULL == (mbedtls_ecp_keypair*)localECKey->pk_ctx)
01461     {
01462         return PAL_ERR_INVALID_ARGUMENT ;
01463     }
01464 
01465     keyPair = (mbedtls_ecp_keypair*)localECKey->pk_ctx;
01466 
01467     switch(keyPair->grp.id)
01468     {
01469         case MBEDTLS_ECP_DP_SECP256R1:
01470             *grpID = PAL_ECP_DP_SECP256R1;
01471             break;
01472         default:
01473             *grpID = PAL_ECP_DP_NONE;
01474             status = PAL_ERR_NOT_SUPPORTED_CURVE;
01475     }
01476     return status;
01477 }
01478 
01479 palStatus_t pal_plat_ECGroupFree (palCurveHandle_t* grp)
01480 {
01481     palStatus_t status = PAL_SUCCESS;
01482     palECGroup_t* localGroup = NULL;
01483 
01484     localGroup = (palECGroup_t*)*grp;
01485     mbedtls_ecp_group_free(localGroup);
01486     free(localGroup);
01487     *grp = NULLPTR;
01488     return status;
01489 }
01490 
01491 palStatus_t pal_plat_ECGroupInitAndLoad (palCurveHandle_t* grp, palGroupIndex_t index)
01492 {
01493     palStatus_t status = PAL_SUCCESS;
01494     mbedtls_ecp_group_id platCurve = MBEDTLS_ECP_DP_NONE;
01495     palECGroup_t* localGroup = NULL;
01496     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01497 
01498     localGroup = (palECGroup_t*)malloc(sizeof(palECGroup_t));
01499     if (NULL == localGroup)
01500     {
01501         status = PAL_ERR_NO_MEMORY ;
01502         goto finish;
01503     }
01504 
01505     mbedtls_ecp_group_init(localGroup);
01506     switch(index)
01507     {
01508         case PAL_ECP_DP_SECP256R1:
01509             platCurve = MBEDTLS_ECP_DP_SECP256R1;
01510             break;
01511         default: 
01512             status = PAL_ERR_NOT_SUPPORTED_CURVE;
01513             goto finish;
01514     }
01515 
01516     platStatus = mbedtls_ecp_group_load(localGroup ,platCurve);
01517     if (CRYPTO_PLAT_SUCCESS != platStatus)
01518     {
01519         status = PAL_ERR_GROUP_LOAD_FAILED;
01520     }
01521     else
01522     {
01523         *grp = (palCurveHandle_t)localGroup;
01524     }
01525     
01526 finish:
01527     if (PAL_SUCCESS != status && localGroup != NULL)
01528     {
01529         free(localGroup);
01530     }
01531 
01532     return status;
01533 }
01534 
01535 
01536 palStatus_t pal_plat_ECDHComputeKey (const palCurveHandle_t grp, const palECKeyHandle_t peerPublicKey, const palECKeyHandle_t privateKey, palECKeyHandle_t outKey)
01537 {
01538     palStatus_t status = PAL_SUCCESS;
01539     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01540     palECGroup_t* ecpGroup = (palECGroup_t*)grp;
01541     mbedtls_ecp_keypair* pubKeyPair = NULL;
01542     mbedtls_ecp_keypair* prvKeyPair = NULL;
01543     mbedtls_ecp_keypair* outKeyPair = NULL;
01544     mbedtls_ctr_drbg_context ctrDrbgCtx;
01545 
01546     mbedtls_ctr_drbg_init(&ctrDrbgCtx);
01547 
01548     pubKeyPair = (mbedtls_ecp_keypair*)((palECKey_t*)peerPublicKey)->pk_ctx;
01549     prvKeyPair = (mbedtls_ecp_keypair*)((palECKey_t*)privateKey)->pk_ctx;
01550     outKeyPair = (mbedtls_ecp_keypair*)((palECKey_t*)outKey)->pk_ctx;
01551 
01552     if (NULL != pubKeyPair && NULL != prvKeyPair && NULL != outKeyPair)
01553     {
01554         platStatus = mbedtls_ecdh_compute_shared(ecpGroup, &outKeyPair->d, &pubKeyPair->Q, &prvKeyPair->d, mbedtls_ctr_drbg_random, (void*)&ctrDrbgCtx);
01555         if (CRYPTO_PLAT_SUCCESS != platStatus)
01556         {
01557             status = PAL_ERR_FAILED_TO_COMPUTE_SHRED_KEY;
01558         }
01559     }
01560     else 
01561     {
01562         status = PAL_ERR_INVALID_ARGUMENT ;
01563     }
01564 
01565 
01566     mbedtls_ctr_drbg_free(&ctrDrbgCtx);
01567 
01568     return status;
01569 }
01570 
01571 
01572 palStatus_t pal_plat_ECDSASign (palCurveHandle_t grp, palMDType_t mdType, palECKeyHandle_t prvKey, unsigned char* dgst, uint32_t dgstLen, unsigned char* sig, size_t* sigLen)
01573 {
01574     palStatus_t status = PAL_SUCCESS;
01575     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01576     palECKey_t* localECKey = (palECKey_t*)prvKey;
01577     mbedtls_ecp_keypair* keyPair = NULL;
01578     mbedtls_ecdsa_context localECDSA;
01579     palECGroup_t* localGroup = (palECGroup_t*)grp;
01580     mbedtls_md_type_t mdAlg = MBEDTLS_MD_NONE;
01581 
01582     keyPair = (mbedtls_ecp_keypair*)localECKey->pk_ctx;
01583 
01584     mbedtls_ecdsa_init(&localECDSA);
01585     platStatus = mbedtls_ecdsa_from_keypair(&localECDSA, keyPair);
01586     if (CRYPTO_PLAT_SUCCESS != platStatus)
01587     {
01588         status = PAL_ERR_FAILED_TO_COPY_KEYPAIR;
01589         goto finish;
01590     }
01591 
01592     platStatus = mbedtls_ecp_group_copy(&localECDSA.grp, localGroup);
01593     if (CRYPTO_PLAT_SUCCESS != platStatus)
01594     {
01595         status = PAL_ERR_FAILED_TO_COPY_GROUP;
01596         goto finish;
01597     }
01598 
01599     switch (mdType)
01600     {
01601         case PAL_SHA256:
01602             mdAlg = MBEDTLS_MD_SHA256;
01603             break;
01604         default:
01605             status = PAL_ERR_INVALID_MD_TYPE;
01606             goto finish;
01607     }
01608 
01609     platStatus = mbedtls_ecdsa_write_signature(&localECDSA, mdAlg, dgst, dgstLen, sig, sigLen, NULL, NULL);
01610     if (CRYPTO_PLAT_SUCCESS != platStatus)
01611     {
01612         status = PAL_ERR_FAILED_TO_WRITE_SIGNATURE;
01613     }
01614 
01615 finish:
01616     mbedtls_ecdsa_free(&localECDSA);
01617     return status;
01618 }
01619 
01620 palStatus_t pal_plat_ECDSAVerify (palECKeyHandle_t pubKey, unsigned char* dgst, uint32_t dgstLen, unsigned char* sig, size_t sigLen, bool* verified)
01621 {
01622     palStatus_t status = PAL_SUCCESS;
01623     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01624     palECKey_t* localECKey = (palECKey_t*)pubKey;
01625     mbedtls_ecp_keypair* keyPair = NULL;
01626     mbedtls_ecdsa_context localECDSA;
01627 
01628     keyPair = (mbedtls_ecp_keypair*)localECKey->pk_ctx;
01629 
01630     mbedtls_ecdsa_init(&localECDSA);
01631     platStatus = mbedtls_ecdsa_from_keypair(&localECDSA, keyPair);
01632     if (CRYPTO_PLAT_SUCCESS != platStatus)
01633     {
01634         status = PAL_ERR_FAILED_TO_COPY_KEYPAIR;
01635         goto finish;
01636     }
01637 
01638     platStatus = mbedtls_ecdsa_read_signature(&localECDSA, dgst, dgstLen, sig, sigLen);
01639     if (CRYPTO_PLAT_SUCCESS != platStatus)
01640     {
01641         status = PAL_ERR_FAILED_TO_VERIFY_SIGNATURE;
01642         *verified = false;
01643     }
01644     else
01645     {
01646         *verified = true;
01647     }
01648 finish:
01649     mbedtls_ecdsa_free(&localECDSA);
01650     return status;
01651 }
01652 
01653 palStatus_t pal_plat_x509CSRInit (palx509CSRHandle_t *x509CSR)
01654 {
01655     palStatus_t status = PAL_SUCCESS;
01656     palx509CSR_t *localCSR = NULL;
01657 
01658     localCSR = (palx509CSR_t*)malloc(sizeof(palx509CSR_t));
01659     if (NULL == localCSR)
01660     {
01661         status = PAL_ERR_NO_MEMORY ;
01662     }
01663     else
01664     {
01665         mbedtls_x509write_csr_init(localCSR);
01666         *x509CSR = (palx509CSRHandle_t)localCSR;
01667     }
01668     return status;
01669 }
01670 
01671 palStatus_t pal_plat_x509CSRSetSubject (palx509CSRHandle_t x509CSR, const char* subjectName)
01672 {
01673     palStatus_t status = PAL_SUCCESS;
01674     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01675     palx509CSR_t *localCSR = (palx509CSR_t*)x509CSR;
01676 
01677     platStatus = mbedtls_x509write_csr_set_subject_name(localCSR, subjectName);
01678     switch (platStatus)
01679     {
01680         case CRYPTO_PLAT_SUCCESS:
01681             status = PAL_SUCCESS;
01682             break;
01683         case MBEDTLS_ERR_X509_UNKNOWN_OID:
01684             status = PAL_ERR_X509_UNKNOWN_OID;
01685             break;
01686         case MBEDTLS_ERR_X509_INVALID_NAME:
01687             status = PAL_ERR_X509_INVALID_NAME;
01688             break;
01689         default:
01690             {
01691                 PAL_LOG(ERR, "Crypto x509 CSR set subject status %" PRId32 ".", platStatus);
01692                 status = PAL_ERR_GENERIC_FAILURE;
01693             }
01694     }
01695 
01696     return status;
01697 }
01698 
01699 palStatus_t pal_plat_x509CSRSetKey (palx509CSRHandle_t x509CSR, palECKeyHandle_t pubKey, palECKeyHandle_t prvKey)
01700 {
01701     palStatus_t status = PAL_SUCCESS;
01702     palx509CSR_t *localCSR = (palx509CSR_t*)x509CSR;
01703     palECKey_t* localPubKey = (palECKey_t*)pubKey;
01704     palECKey_t* localPrvKey = (palECKey_t*)prvKey;
01705 
01706     if (NULL != localPrvKey)
01707     {
01708         int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01709         mbedtls_ecp_keypair* pubKeyPair = NULL;
01710         mbedtls_ecp_keypair* prvKeyPair = NULL;
01711 
01712         pubKeyPair = (mbedtls_ecp_keypair*)localPubKey->pk_ctx;
01713         prvKeyPair = (mbedtls_ecp_keypair*)localPrvKey->pk_ctx;
01714 
01715         if (NULL != pubKeyPair && NULL != prvKeyPair)
01716         {
01717             platStatus = mbedtls_mpi_copy(&(pubKeyPair->d), &(prvKeyPair->d));
01718             if (CRYPTO_PLAT_SUCCESS != platStatus)
01719             {
01720                 status = PAL_ERR_FAILED_TO_COPY_KEYPAIR;
01721             }
01722         }
01723         else
01724         {
01725             status = PAL_ERR_INVALID_ARGUMENT ;
01726         }
01727     }
01728     
01729     if (PAL_SUCCESS == status)
01730     {
01731         mbedtls_x509write_csr_set_key(localCSR, localPubKey);
01732     }
01733     
01734     return status;
01735 }
01736     
01737 palStatus_t pal_plat_x509CSRSetMD (palx509CSRHandle_t x509CSR, palMDType_t mdType)
01738 {
01739     palStatus_t status = PAL_SUCCESS;
01740     palx509CSR_t *localCSR = (palx509CSR_t*)x509CSR;
01741     mbedtls_md_type_t mdAlg = MBEDTLS_MD_NONE;
01742 
01743     switch (mdType)
01744     {
01745         case PAL_SHA256:
01746             mdAlg = MBEDTLS_MD_SHA256;
01747             break;
01748         default:
01749             status = PAL_ERR_INVALID_MD_TYPE;
01750             goto finish;
01751     }
01752 
01753     mbedtls_x509write_csr_set_md_alg(localCSR, mdAlg);
01754 
01755 finish:
01756     return status;
01757 }
01758 
01759 palStatus_t pal_plat_x509CSRSetKeyUsage (palx509CSRHandle_t x509CSR, uint32_t keyUsage)
01760 {
01761     palStatus_t status = PAL_SUCCESS;
01762     palx509CSR_t *localCSR = (palx509CSR_t*)x509CSR;
01763     uint8_t localKeyUsage = 0;
01764     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01765 
01766     if (PAL_X509_KU_DIGITAL_SIGNATURE & keyUsage)
01767     {
01768         localKeyUsage |= MBEDTLS_X509_KU_DIGITAL_SIGNATURE;
01769     }
01770     if (PAL_X509_KU_KEY_CERT_SIGN & keyUsage)
01771     {
01772         localKeyUsage |= MBEDTLS_X509_KU_KEY_CERT_SIGN;
01773     }
01774     if (PAL_X509_KU_NON_REPUDIATION & keyUsage)
01775     {
01776         localKeyUsage |= MBEDTLS_X509_KU_NON_REPUDIATION;
01777     }
01778 
01779     if (0 == localKeyUsage)
01780     {
01781         status = PAL_ERR_INVALID_KEY_USAGE;
01782     }
01783     else
01784     {
01785         platStatus = mbedtls_x509write_csr_set_key_usage(localCSR, localKeyUsage);
01786         if (CRYPTO_PLAT_SUCCESS != platStatus)
01787         {
01788             status = PAL_ERR_FAILED_TO_SET_KEY_USAGE;
01789         }
01790     }
01791     return status;
01792 }
01793 
01794 palStatus_t pal_plat_x509CSRSetExtension (palx509CSRHandle_t x509CSR,const char* oid, size_t oidLen, const unsigned char* value, size_t valueLen)
01795 {
01796     palStatus_t status = PAL_SUCCESS;
01797     palx509CSR_t *localCSR = (palx509CSR_t*)x509CSR;
01798     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01799 
01800     platStatus = mbedtls_x509write_csr_set_extension(localCSR, oid, oidLen, value, valueLen);
01801     if (CRYPTO_PLAT_SUCCESS != platStatus)
01802     {
01803         status = PAL_ERR_SET_EXTENTION_FAILED;
01804     }
01805     return status;
01806 }
01807 
01808 palStatus_t pal_plat_x509CSRWriteDER (palx509CSRHandle_t x509CSR, unsigned char* derBuf, size_t derBufLen, size_t* actualDerLen)
01809 {
01810     palStatus_t status = PAL_SUCCESS;
01811     palx509CSR_t *localCSR = (palx509CSR_t*)x509CSR;
01812     int32_t platStatus = CRYPTO_PLAT_SUCCESS;
01813 
01814     platStatus = mbedtls_x509write_csr_der(localCSR, derBuf, derBufLen, pal_plat_entropySource, NULL);
01815     if (CRYPTO_PLAT_SUCCESS >= platStatus) //! mbedtls_x509write_csr_der() returns the size of the written CSR
01816     {                                      //! we need to check if the length larger than zero
01817         status = PAL_ERR_CSR_WRITE_DER_FAILED;
01818         goto finish;
01819     }
01820 
01821     moveDataToBufferStart(derBuf, derBufLen, platStatus);
01822     if (actualDerLen)
01823     {
01824         *actualDerLen = platStatus;
01825     }
01826  finish:
01827     return status;
01828 }
01829 
01830 palStatus_t pal_plat_x509CSRFree (palx509CSRHandle_t *x509CSR)
01831 {
01832     palStatus_t status = PAL_SUCCESS;
01833     palx509CSR_t* localCSR = (palx509CSR_t*)*x509CSR;
01834 
01835     mbedtls_x509write_csr_free(localCSR);
01836     free(localCSR);
01837     *x509CSR = NULLPTR;
01838     return status;
01839 }
01840 
01841 PAL_PRIVATE int pal_plat_entropySourceDRBG( void *data, unsigned char *output, size_t len)
01842 {
01843     palStatus_t status = PAL_SUCCESS;
01844     (void)data;
01845     
01846     //! We need to call platform layer function, in order to prevent two things:
01847     //! 1. adding new service layer function for this purpose (only for DRBG seeding for mbedTLS, not sure other Crypto libraries will need it)
01848     //! 2. prevent endless recursive (random->drbg->random) - reseeding scenario.
01849     status = pal_plat_osRandomBuffer ((uint8_t*) output, len);
01850     if (PAL_SUCCESS == status)
01851     {
01852         return CRYPTO_PLAT_SUCCESS;
01853     }
01854     else
01855     {
01856         return CRYPTO_PLAT_GENERIC_ERROR;
01857     }
01858 }
01859 
01860 PAL_PRIVATE int pal_plat_entropySource( void *data, unsigned char *output, size_t len)
01861 {
01862     palStatus_t status = PAL_SUCCESS;
01863     (void)data;
01864     
01865     status = pal_osRandomBuffer((uint8_t*) output, len);
01866     if (PAL_SUCCESS == status)
01867     {
01868         return CRYPTO_PLAT_SUCCESS;
01869     }
01870     else
01871     {
01872         return CRYPTO_PLAT_GENERIC_ERROR;
01873     }
01874 }
01875 
01876 
01877 #ifdef __arm__ // we are compiling using the ARM compiler
01878 /* This function is provided for ARM-CC compiler, since mbedTLS uses it and it returns NULL
01879  * in ARM-CC, we need to provide replacement function to keep correct functionality
01880  * mbedTLS will change the internal implementation which uses gmtime()
01881  */ 
01882 struct tm *gmtime(const time_t *timep)
01883 {
01884     return localtime(timep);
01885 }
01886 
01887 #endif
01888