Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
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
Generated on Tue Jul 12 2022 19:12:14 by 1.7.2