Mayank Gupta / Mbed OS pelion-example-frdm

Dependencies:   FXAS21002 FXOS8700Q

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