Toyomasa Watarai / simple-mbed-cloud-client

Dependents:  

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_Crypto.c Source File

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