Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
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
Generated on Tue Jul 12 2022 20:21:01 by
