Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

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