Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
pal_plat_TLS.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_TLS.h" 00018 #include "mbedtls/ssl.h" 00019 #include "mbedtls/entropy.h" 00020 #include "mbedtls/ctr_drbg.h" 00021 #include "mbedtls/ssl_internal.h" 00022 #include "stdlib.h" 00023 #include "string.h" 00024 #include "sotp.h" 00025 00026 00027 #define SSL_LIB_SUCCESS 0 00028 00029 #if PAL_USE_SECURE_TIME 00030 #include "platform_time.h" 00031 PAL_PRIVATE mbedtls_time_t g_timeFromHS = 0; 00032 PAL_PRIVATE palMutexID_t g_palTLSTimeMutex = NULLPTR; 00033 #ifdef MBEDTLS_PLATFORM_TIME_ALT 00034 PAL_PRIVATE mbedtls_time_t pal_mbedtlsTimeCB(mbedtls_time_t* timer); 00035 #endif 00036 #endif //PAL_USE_SECURE_TIME 00037 00038 #if defined(MBEDTLS_DEBUG_C) 00039 //! Add forward declaration for the function from mbedTLS 00040 void mbedtls_debug_set_threshold( int threshold ); 00041 #endif 00042 00043 00044 typedef mbedtls_ssl_context platTlsContext; 00045 typedef mbedtls_ssl_config platTlsConfiguraionContext; 00046 00047 PAL_PRIVATE mbedtls_entropy_context *g_entropy = NULL; 00048 PAL_PRIVATE bool g_entropyInitiated = false; 00049 00050 typedef struct palTimingDelayContext 00051 { 00052 uint64_t start_ticks; 00053 uint32_t int_ms; 00054 uint32_t fin_ms; 00055 } palTimingDelayContext_t; 00056 00057 00058 //! the full structures will be defined later in the implemetation. 00059 typedef struct palTLS { 00060 platTlsContext tlsCtx; 00061 bool tlsInit; 00062 char* psk; //NULL terminated 00063 char* identity; //NULL terminated 00064 bool wantReadOrWrite; 00065 }palTLS_t; 00066 00067 00068 //! the full structures will be defined later in the implemetation. 00069 typedef struct palTLSConf { 00070 platTlsConfiguraionContext* confCtx; 00071 palTLSSocketHandle_t palIOCtx; // which will be used as bio context for mbedTLS 00072 palTLS_t* tlsContext; // to help us to get the index of the containing palTLS_t in the array. will be updated in the init 00073 // maybe we need to make this an array, since index can be shared for more than one TLS context 00074 mbedtls_ctr_drbg_context ctrDrbg; 00075 palTimingDelayContext_t timerCtx; 00076 #if (PAL_ENABLE_X509 == 1) 00077 mbedtls_x509_crt owncert; 00078 mbedtls_x509_crt cacert; 00079 #endif 00080 mbedtls_pk_context pkey; 00081 bool hasKeys; 00082 bool hasChain; 00083 int cipherSuites[PAL_MAX_ALLOWED_CIPHER_SUITES + 1]; // The +1 is for the Zero Termination required by mbedTLS 00084 }palTLSConf_t; 00085 00086 00087 00088 00089 00090 00091 PAL_PRIVATE palStatus_t translateTLSErrToPALError(int32_t error) 00092 { 00093 palStatus_t status; 00094 switch(error) 00095 { 00096 case SSL_LIB_SUCCESS: 00097 status = PAL_ERR_END_OF_FILE ; 00098 break; 00099 case MBEDTLS_ERR_SSL_WANT_READ: 00100 status = PAL_ERR_TLS_WANT_READ; 00101 break; 00102 case MBEDTLS_ERR_SSL_WANT_WRITE: 00103 status = PAL_ERR_TLS_WANT_WRITE; 00104 break; 00105 case MBEDTLS_ERR_SSL_TIMEOUT: 00106 status = PAL_ERR_TIMEOUT_EXPIRED ; 00107 break; 00108 case MBEDTLS_ERR_SSL_BAD_INPUT_DATA: 00109 status = PAL_ERR_TLS_BAD_INPUT_DATA; 00110 break; 00111 case MBEDTLS_ERR_SSL_CLIENT_RECONNECT: 00112 status = PAL_ERR_TLS_CLIENT_RECONNECT; 00113 break; 00114 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 00115 status = PAL_ERR_TLS_PEER_CLOSE_NOTIFY; 00116 break; 00117 #if (PAL_ENABLE_X509 == 1) 00118 case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED: 00119 status = PAL_ERR_X509_CERT_VERIFY_FAILED; 00120 break; 00121 #endif 00122 default: 00123 { 00124 status = PAL_ERR_GENERIC_FAILURE; 00125 } 00126 }; 00127 return status; 00128 00129 } 00130 00131 00132 PAL_PRIVATE palStatus_t translateTLSHandShakeErrToPALError(palTLS_t* tlsCtx, int32_t error) 00133 { 00134 palStatus_t status; 00135 switch(error) 00136 { 00137 case SSL_LIB_SUCCESS: 00138 status = PAL_SUCCESS; 00139 tlsCtx->wantReadOrWrite = false; 00140 break; 00141 case MBEDTLS_ERR_SSL_WANT_READ: 00142 status = PAL_ERR_TLS_WANT_READ; 00143 tlsCtx->wantReadOrWrite = true; 00144 break; 00145 case MBEDTLS_ERR_SSL_WANT_WRITE: 00146 status = PAL_ERR_TLS_WANT_WRITE; 00147 tlsCtx->wantReadOrWrite = true; 00148 break; 00149 case MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED: 00150 status = PAL_ERR_TLS_HELLO_VERIFY_REQUIRED; 00151 break; 00152 case MBEDTLS_ERR_SSL_TIMEOUT: 00153 status = PAL_ERR_TIMEOUT_EXPIRED ; 00154 break; 00155 case MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY: 00156 status = PAL_ERR_TLS_PEER_CLOSE_NOTIFY; 00157 break; 00158 #if (PAL_ENABLE_X509 == 1) 00159 case MBEDTLS_ERR_X509_CERT_VERIFY_FAILED: 00160 status = PAL_ERR_X509_CERT_VERIFY_FAILED; 00161 break; 00162 #endif 00163 default: 00164 { 00165 PAL_LOG(ERR, "SSL handshake return code 0x%" PRIx32 ".", -error); 00166 status = PAL_ERR_GENERIC_FAILURE; 00167 } 00168 }; 00169 return status; 00170 } 00171 00172 //! Forward declaration 00173 PAL_PRIVATE int palBIORecv_timeout(palTLSSocketHandle_t socket, unsigned char *buf, size_t len, uint32_t timeout); 00174 PAL_PRIVATE int palBIORecv(palTLSSocketHandle_t socket, unsigned char *buf, size_t len); 00175 PAL_PRIVATE int palBIOSend(palTLSSocketHandle_t socket, const unsigned char *buf, size_t len); 00176 PAL_PRIVATE void palDebug(void *ctx, int debugLevel, const char *fileName, int line, const char *message); 00177 int pal_plat_entropySourceTLS( void *data, unsigned char *output, size_t len, size_t *olen ); 00178 PAL_PRIVATE int palTimingGetDelay( void *data ); 00179 PAL_PRIVATE void palTimingSetDelay( void *data, uint32_t intMs, uint32_t finMs ); 00180 00181 palStatus_t pal_plat_initTLSLibrary (void) 00182 { 00183 palStatus_t status = PAL_SUCCESS; 00184 00185 g_entropy = (mbedtls_entropy_context*)malloc(sizeof(mbedtls_entropy_context)); 00186 if (NULL == g_entropy) 00187 { 00188 status = PAL_ERR_NO_MEMORY ; 00189 goto finish; 00190 } 00191 else 00192 { 00193 mbedtls_entropy_init(g_entropy); 00194 g_entropyInitiated = false; 00195 } 00196 00197 #if PAL_USE_SECURE_TIME 00198 #ifdef MBEDTLS_PLATFORM_TIME_ALT 00199 // this scope is here to keep warnings away from gotos which skip over variable initialization 00200 { 00201 int32_t platStatus = SSL_LIB_SUCCESS; 00202 platStatus = mbedtls_platform_set_time(pal_mbedtlsTimeCB); 00203 if (SSL_LIB_SUCCESS != platStatus) 00204 { 00205 status = PAL_ERR_FAILED_SET_TIME_CB; 00206 goto finish; 00207 } 00208 } 00209 #endif //MBEDTLS_PLATFORM_TIME_ALT 00210 status = pal_osMutexCreate(&g_palTLSTimeMutex); 00211 if(PAL_SUCCESS != status) 00212 { 00213 PAL_LOG(ERR, "Failed to Create TLS time Mutex error: %" PRId32 ".", status); 00214 } 00215 #endif //PAL_USE_SECURE_TIME 00216 finish: 00217 return status; 00218 } 00219 00220 00221 palStatus_t pal_plat_cleanupTLS (void) 00222 { 00223 palStatus_t status = PAL_SUCCESS; 00224 if(g_entropy != NULL) 00225 { 00226 mbedtls_entropy_free(g_entropy); 00227 } 00228 g_entropyInitiated = false; 00229 free(g_entropy); 00230 g_entropy = NULL; 00231 00232 #if PAL_USE_SECURE_TIME 00233 //! Try to catch the Mutex in order to prevent situation of deleteing under use mutex 00234 status = pal_osMutexWait(g_palTLSTimeMutex, PAL_RTOS_WAIT_FOREVER); 00235 if (PAL_SUCCESS != status) 00236 { 00237 PAL_LOG(ERR, "Failed to get TLS time Mutex error: %" PRId32 ".", status); 00238 } 00239 00240 status = pal_osMutexRelease(g_palTLSTimeMutex); 00241 if (PAL_SUCCESS != status) 00242 { 00243 PAL_LOG(ERR, "Failed to release TLS time Mutex error: %" PRId32 ".", status); 00244 } 00245 00246 status = pal_osMutexDelete(&g_palTLSTimeMutex); 00247 if(PAL_SUCCESS != status) 00248 { 00249 PAL_LOG(ERR, "Failed to Delete TLS time Mutex"); 00250 } 00251 #endif //PAL_USE_SECURE_TIME 00252 return status; 00253 } 00254 00255 00256 palStatus_t pal_plat_addEntropySource (palEntropySource_f entropyCallback) 00257 { 00258 palStatus_t status = PAL_SUCCESS; 00259 int32_t platStatus = SSL_LIB_SUCCESS; 00260 00261 if (NULL == entropyCallback) 00262 { 00263 return PAL_ERR_INVALID_ARGUMENT ; 00264 } 00265 00266 if (!g_entropyInitiated) 00267 { 00268 platStatus = mbedtls_entropy_add_source(g_entropy, entropyCallback, NULL, PAL_INITIAL_RANDOM_SIZE, MBEDTLS_ENTROPY_SOURCE_STRONG ); 00269 if (SSL_LIB_SUCCESS != platStatus) 00270 { 00271 status = PAL_ERR_TLS_CONFIG_INIT; 00272 } 00273 else 00274 { 00275 g_entropyInitiated = true; 00276 } 00277 00278 } 00279 00280 return status; 00281 } 00282 00283 00284 palStatus_t pal_plat_initTLSConf (palTLSConfHandle_t* palConfCtx, palTLSTransportMode_t transportVersion, palDTLSSide_t methodType) 00285 { 00286 palStatus_t status = PAL_SUCCESS; 00287 palTLSConf_t* localConfigCtx = NULL; 00288 int32_t platStatus = SSL_LIB_SUCCESS; 00289 int32_t endpoint = 0; 00290 int32_t transport = 0; 00291 00292 if (NULLPTR == palConfCtx) 00293 { 00294 return PAL_ERR_INVALID_ARGUMENT ; 00295 } 00296 00297 localConfigCtx = (palTLSConf_t*)malloc(sizeof(palTLSConf_t)); 00298 if (NULL == localConfigCtx) 00299 { 00300 status = PAL_ERR_NO_MEMORY ; 00301 goto finish; 00302 } 00303 00304 localConfigCtx->confCtx = (platTlsConfiguraionContext*)malloc(sizeof(platTlsConfiguraionContext)); 00305 if (NULL == localConfigCtx->confCtx) 00306 { 00307 status = PAL_ERR_NO_MEMORY ; 00308 goto finish; 00309 } 00310 localConfigCtx->tlsContext = NULL; 00311 localConfigCtx->hasKeys = false; 00312 localConfigCtx->hasChain = false; 00313 memset(localConfigCtx->cipherSuites, 0,(sizeof(int)* (PAL_MAX_ALLOWED_CIPHER_SUITES+1)) ); 00314 mbedtls_ssl_config_init(localConfigCtx->confCtx); 00315 00316 #if (PAL_ENABLE_X509 == 1) 00317 mbedtls_x509_crt_init(&localConfigCtx->owncert); 00318 mbedtls_x509_crt_init(&localConfigCtx->cacert); 00319 #endif 00320 00321 if (PAL_TLS_IS_CLIENT == methodType) 00322 { 00323 endpoint = MBEDTLS_SSL_IS_CLIENT; 00324 } 00325 else 00326 { 00327 endpoint = MBEDTLS_SSL_IS_SERVER; 00328 } 00329 00330 if (PAL_TLS_MODE == transportVersion) 00331 { 00332 transport = MBEDTLS_SSL_TRANSPORT_STREAM; 00333 } 00334 else 00335 { 00336 transport = MBEDTLS_SSL_TRANSPORT_DATAGRAM; 00337 } 00338 platStatus = mbedtls_ssl_config_defaults(localConfigCtx->confCtx, endpoint, transport, MBEDTLS_SSL_PRESET_DEFAULT); 00339 if (SSL_LIB_SUCCESS != platStatus) 00340 { 00341 PAL_LOG(ERR, "TLS Init conf status %" PRId32 ".", platStatus); 00342 status = PAL_ERR_TLS_CONFIG_INIT; 00343 goto finish; 00344 } 00345 00346 mbedtls_ctr_drbg_init(&localConfigCtx->ctrDrbg); 00347 status = pal_plat_addEntropySource (pal_plat_entropySourceTLS); 00348 if (PAL_SUCCESS != status) 00349 { 00350 goto finish; 00351 } 00352 00353 platStatus = mbedtls_ctr_drbg_seed(&localConfigCtx->ctrDrbg, mbedtls_entropy_func, g_entropy, NULL, 0); //Custom data can be defined in 00354 //pal_TLS.h header and to be defined by 00355 //Service code. But we need to check if other platform support this 00356 //input! 00357 if (SSL_LIB_SUCCESS != platStatus) 00358 { 00359 status = PAL_ERR_TLS_CONFIG_INIT; 00360 goto finish; 00361 } 00362 00363 mbedtls_ssl_conf_rng(localConfigCtx->confCtx, mbedtls_ctr_drbg_random, &localConfigCtx->ctrDrbg); 00364 *palConfCtx = (uintptr_t)localConfigCtx; 00365 00366 finish: 00367 if (PAL_SUCCESS != status && NULL != localConfigCtx) 00368 { 00369 if (NULL != localConfigCtx->confCtx) 00370 { 00371 free(localConfigCtx->confCtx); 00372 } 00373 free(localConfigCtx); 00374 *palConfCtx = NULLPTR; 00375 } 00376 return status; 00377 } 00378 00379 00380 palStatus_t pal_plat_tlsConfigurationFree (palTLSConfHandle_t* palTLSConf) 00381 { 00382 palStatus_t status = PAL_SUCCESS; 00383 palTLSConf_t* localConfigCtx = NULL; 00384 00385 if (NULLPTR == palTLSConf || NULLPTR == *palTLSConf) 00386 { 00387 return PAL_ERR_INVALID_ARGUMENT ; 00388 } 00389 00390 localConfigCtx = (palTLSConf_t*)*palTLSConf; 00391 00392 if (true == localConfigCtx->hasKeys) 00393 { 00394 mbedtls_pk_free(&localConfigCtx->pkey); 00395 #if (PAL_ENABLE_X509 == 1) 00396 mbedtls_x509_crt_free(&localConfigCtx->owncert); 00397 } 00398 00399 if (true == localConfigCtx->hasChain) 00400 { 00401 mbedtls_x509_crt_free(&localConfigCtx->cacert); 00402 #endif 00403 } 00404 00405 mbedtls_ssl_config_free(localConfigCtx->confCtx); 00406 mbedtls_ctr_drbg_free(&localConfigCtx->ctrDrbg); 00407 00408 free(localConfigCtx->confCtx); 00409 00410 memset(localConfigCtx, 0, sizeof(palTLSConf_t)); 00411 free(localConfigCtx); 00412 *palTLSConf = NULLPTR; 00413 return status; 00414 } 00415 00416 00417 palStatus_t pal_plat_initTLS (palTLSConfHandle_t palTLSConf, palTLSHandle_t* palTLSHandle) 00418 { 00419 palStatus_t status = PAL_SUCCESS; 00420 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00421 00422 palTLS_t* localTLSHandle = (palTLS_t*)malloc( sizeof(palTLS_t)); 00423 if (NULL == localTLSHandle) 00424 { 00425 status = PAL_ERR_TLS_RESOURCE; 00426 goto finish; 00427 } 00428 00429 memset(localTLSHandle, 0 , sizeof(palTLS_t)); 00430 mbedtls_ssl_init(&localTLSHandle->tlsCtx); 00431 localConfigCtx->tlsContext = localTLSHandle; 00432 localTLSHandle->tlsInit = true; 00433 mbedtls_ssl_set_timer_cb(&localTLSHandle->tlsCtx, &localConfigCtx->timerCtx, palTimingSetDelay, palTimingGetDelay); 00434 *palTLSHandle = (palTLSHandle_t)localTLSHandle; 00435 00436 finish: 00437 return status; 00438 } 00439 00440 00441 palStatus_t pal_plat_freeTLS (palTLSHandle_t* palTLSHandle) 00442 { 00443 palStatus_t status = PAL_SUCCESS; 00444 palTLS_t* localTLSCtx = NULL; 00445 00446 localTLSCtx = (palTLS_t*)*palTLSHandle; 00447 if (false == localTLSCtx->tlsInit) 00448 { 00449 status = PAL_ERR_TLS_CONTEXT_NOT_INITIALIZED; 00450 goto finish; 00451 } 00452 00453 00454 mbedtls_ssl_free(&localTLSCtx->tlsCtx); 00455 free(localTLSCtx); 00456 *palTLSHandle = NULLPTR; 00457 00458 finish: 00459 return status; 00460 } 00461 00462 00463 palStatus_t pal_plat_setAuthenticationMode (palTLSConfHandle_t sslConf, palTLSAuthMode_t authMode) 00464 { 00465 palStatus_t status = PAL_SUCCESS; 00466 int32_t platAuthMode; 00467 palTLSConf_t* localConfigCtx = (palTLSConf_t*)sslConf; 00468 00469 switch(authMode) 00470 { 00471 case PAL_TLS_VERIFY_NONE: 00472 platAuthMode = MBEDTLS_SSL_VERIFY_NONE; 00473 break; 00474 case PAL_TLS_VERIFY_OPTIONAL: 00475 platAuthMode = MBEDTLS_SSL_VERIFY_OPTIONAL; 00476 break; 00477 case PAL_TLS_VERIFY_REQUIRED: 00478 platAuthMode = MBEDTLS_SSL_VERIFY_REQUIRED; 00479 break; 00480 default: 00481 status = PAL_ERR_INVALID_ARGUMENT ; 00482 goto finish; 00483 }; 00484 mbedtls_ssl_conf_authmode(localConfigCtx->confCtx, platAuthMode ); 00485 00486 finish: 00487 return status; 00488 } 00489 00490 palStatus_t pal_plat_setCipherSuites (palTLSConfHandle_t sslConf, palTLSSuites_t palSuite) 00491 { 00492 palStatus_t status = PAL_SUCCESS; 00493 palTLSConf_t* localConfigCtx = (palTLSConf_t*)sslConf; 00494 00495 switch(palSuite) 00496 { 00497 case PAL_TLS_PSK_WITH_AES_128_CBC_SHA256: 00498 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256; 00499 break; 00500 case PAL_TLS_PSK_WITH_AES_128_CCM_8: 00501 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8; 00502 break; 00503 case PAL_TLS_PSK_WITH_AES_256_CCM_8: 00504 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8; 00505 break; 00506 case PAL_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8: 00507 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8; 00508 break; 00509 case PAL_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: 00510 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256; 00511 break; 00512 case PAL_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: 00513 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384; 00514 break; 00515 #ifdef MBEDTLS_ARIA_C 00516 case PAL_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256: 00517 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256; 00518 break; 00519 case PAL_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256: 00520 localConfigCtx->cipherSuites[0] = MBEDTLS_TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256; 00521 break; 00522 #endif 00523 default: 00524 localConfigCtx->cipherSuites[0] = 0; 00525 status = PAL_ERR_TLS_INVALID_CIPHER; 00526 goto finish; 00527 } 00528 00529 mbedtls_ssl_conf_ciphersuites(localConfigCtx->confCtx, localConfigCtx->cipherSuites); 00530 finish: 00531 return status; 00532 } 00533 00534 palStatus_t pal_plat_sslGetVerifyResultExtended (palTLSHandle_t palTLSHandle, int32_t* verifyResult) 00535 { 00536 palStatus_t status = PAL_SUCCESS; 00537 palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle; 00538 int32_t platStatus = SSL_LIB_SUCCESS; 00539 *verifyResult = 0; 00540 00541 platStatus = mbedtls_ssl_get_verify_result(&localTLSCtx->tlsCtx); 00542 if (SSL_LIB_SUCCESS != platStatus) 00543 { 00544 status = PAL_ERR_X509_CERT_VERIFY_FAILED; 00545 #if (PAL_ENABLE_X509 == 1) 00546 //! please DO NOT change errors order 00547 if (MBEDTLS_X509_BADCERT_NOT_TRUSTED & platStatus) 00548 { 00549 *verifyResult |= PAL_ERR_X509_BADCERT_NOT_TRUSTED; 00550 status = PAL_ERR_X509_BADCERT_NOT_TRUSTED; 00551 } 00552 if (MBEDTLS_X509_BADCERT_BAD_KEY & platStatus) 00553 { 00554 *verifyResult |= PAL_ERR_X509_BADCERT_BAD_KEY; 00555 status = PAL_ERR_X509_BADCERT_BAD_KEY; 00556 } 00557 if (MBEDTLS_X509_BADCERT_BAD_PK & platStatus) 00558 { 00559 *verifyResult |= PAL_ERR_X509_BADCERT_BAD_PK; 00560 status = PAL_ERR_X509_BADCERT_BAD_PK; 00561 } 00562 if (MBEDTLS_X509_BADCERT_BAD_MD & platStatus) 00563 { 00564 *verifyResult |= PAL_ERR_X509_BADCERT_BAD_MD; 00565 status = PAL_ERR_X509_BADCERT_BAD_MD; 00566 } 00567 if (MBEDTLS_X509_BADCERT_FUTURE & platStatus) 00568 { 00569 *verifyResult |= PAL_ERR_X509_BADCERT_FUTURE; 00570 status = PAL_ERR_X509_BADCERT_FUTURE; 00571 } 00572 if (MBEDTLS_X509_BADCERT_EXPIRED & platStatus) 00573 { 00574 *verifyResult |= PAL_ERR_X509_BADCERT_EXPIRED; 00575 status = PAL_ERR_X509_BADCERT_EXPIRED; 00576 } 00577 #endif 00578 } 00579 return status; 00580 } 00581 00582 palStatus_t pal_plat_sslRead (palTLSHandle_t palTLSHandle, void *buffer, uint32_t len, uint32_t* actualLen) 00583 { 00584 palStatus_t status = PAL_SUCCESS; 00585 int32_t platStatus = SSL_LIB_SUCCESS; 00586 palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle; 00587 00588 platStatus = mbedtls_ssl_read(&localTLSCtx->tlsCtx, (unsigned char*)buffer, len); 00589 if (platStatus > SSL_LIB_SUCCESS) 00590 { 00591 *actualLen = platStatus; 00592 } 00593 else 00594 { 00595 status = translateTLSErrToPALError(platStatus); 00596 if (MBEDTLS_ERR_SSL_WANT_READ != platStatus) 00597 { 00598 PAL_LOG(ERR, "SSL Read return code %" PRId32 ".", platStatus); 00599 } 00600 else 00601 { 00602 PAL_LOG(DBG, "SSL Read return code %" PRId32 ".", platStatus); 00603 } 00604 } 00605 00606 return status; 00607 } 00608 00609 00610 palStatus_t pal_plat_sslWrite (palTLSHandle_t palTLSHandle, const void *buffer, uint32_t len, uint32_t *bytesWritten) 00611 { 00612 palStatus_t status = PAL_SUCCESS; 00613 int32_t platStatus = SSL_LIB_SUCCESS; 00614 palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle; 00615 00616 platStatus = mbedtls_ssl_write(&localTLSCtx->tlsCtx, (unsigned char*)buffer, len); 00617 if (platStatus > SSL_LIB_SUCCESS) 00618 { 00619 *bytesWritten = platStatus; 00620 } 00621 else 00622 { 00623 status = translateTLSErrToPALError(platStatus); 00624 if (MBEDTLS_ERR_SSL_WANT_WRITE != platStatus) 00625 { 00626 PAL_LOG(ERR, "SSL Write platform return code %" PRId32 ".", platStatus); 00627 } 00628 else 00629 { 00630 PAL_LOG(DBG, "SSL Write platform return code %" PRId32 ".", platStatus); 00631 } 00632 } 00633 00634 return status; 00635 } 00636 00637 00638 palStatus_t pal_plat_setHandShakeTimeOut (palTLSConfHandle_t palTLSConf, uint32_t timeoutInMilliSec) 00639 { 00640 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00641 uint32_t minTimeout = PAL_DTLS_PEER_MIN_TIMEOUT; 00642 uint32_t maxTimeout = timeoutInMilliSec >> 1; //! faster dividing by 2 00643 //! Since mbedTLS algorithm for UDP handshake algorithm is as follow: 00644 //! wait 'minTimeout' ..=> 'minTimeout = 2*minTimeout' while 'minTimeout < maxTimeout' 00645 //! if 'minTimeout >= maxTimeout' them wait 'maxTimeout'. 00646 //! The whole waiting time is the sum of the different intervals waited. 00647 //! Therefore we need divide the 'timeoutInMilliSec' by 2 to give a close approximation of the desired 'timeoutInMilliSec' 00648 //! 1 + 2 + ... + 'timeoutInMilliSec/2' ~= 'timeoutInMilliSec' 00649 00650 if (maxTimeout < PAL_DTLS_PEER_MIN_TIMEOUT) 00651 { 00652 minTimeout = (timeoutInMilliSec+1) >> 1; //to prevent 'minTimeout == 0' 00653 maxTimeout = timeoutInMilliSec; 00654 } 00655 00656 mbedtls_ssl_conf_handshake_timeout(localConfigCtx->confCtx, minTimeout, maxTimeout); 00657 00658 return PAL_SUCCESS; 00659 } 00660 00661 00662 palStatus_t pal_plat_sslSetup (palTLSHandle_t palTLSHandle, palTLSConfHandle_t palTLSConf) 00663 { 00664 palStatus_t status = PAL_SUCCESS; 00665 palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle; 00666 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00667 int32_t platStatus = SSL_LIB_SUCCESS; 00668 00669 if (!localTLSCtx->wantReadOrWrite) 00670 { 00671 platStatus = mbedtls_ssl_setup(&localTLSCtx->tlsCtx, localConfigCtx->confCtx); 00672 if (SSL_LIB_SUCCESS != platStatus) 00673 { 00674 if (MBEDTLS_ERR_SSL_ALLOC_FAILED == platStatus) 00675 { 00676 status = PAL_ERR_NO_MEMORY ; 00677 goto finish; 00678 } 00679 PAL_LOG(ERR, "SSL setup return code %" PRId32 ".", platStatus); 00680 status = PAL_ERR_GENERIC_FAILURE; 00681 goto finish; 00682 } 00683 00684 localConfigCtx->tlsContext = localTLSCtx; 00685 } 00686 finish: 00687 return status; 00688 } 00689 00690 palStatus_t pal_plat_handShake (palTLSHandle_t palTLSHandle, uint64_t* serverTime) 00691 { 00692 palStatus_t status = PAL_SUCCESS; 00693 palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle; 00694 int32_t platStatus = SSL_LIB_SUCCESS; 00695 while( (MBEDTLS_SSL_HANDSHAKE_OVER != localTLSCtx->tlsCtx.state) && (PAL_SUCCESS == status) ) 00696 { 00697 platStatus = mbedtls_ssl_handshake_step( &localTLSCtx->tlsCtx ); 00698 00699 /* Extract the first 4 bytes of the ServerHello random */ 00700 if( MBEDTLS_SSL_SERVER_HELLO_DONE == localTLSCtx->tlsCtx.state ) 00701 { 00702 *serverTime = (uint64_t) 00703 ( (uint32_t)localTLSCtx->tlsCtx.handshake->randbytes[32 + 0] << 24 ) | 00704 ( (uint32_t)localTLSCtx->tlsCtx.handshake->randbytes[32 + 1] << 16 ) | 00705 ( (uint32_t)localTLSCtx->tlsCtx.handshake->randbytes[32 + 2] << 8 ) | 00706 ( (uint32_t)localTLSCtx->tlsCtx.handshake->randbytes[32 + 3] << 0 ); 00707 } 00708 if (SSL_LIB_SUCCESS != platStatus) 00709 { 00710 status = translateTLSHandShakeErrToPALError(localTLSCtx, platStatus); 00711 } 00712 } 00713 return status; 00714 } 00715 00716 #if PAL_USE_SECURE_TIME 00717 palStatus_t pal_plat_renegotiate (palTLSHandle_t palTLSHandle, uint64_t serverTime) 00718 { 00719 palStatus_t status = PAL_SUCCESS; 00720 palStatus_t mutexStatus = PAL_SUCCESS; 00721 palTLS_t* localTLSCtx = (palTLS_t*)palTLSHandle; 00722 int32_t platStatus = SSL_LIB_SUCCESS; 00723 00724 status = pal_osMutexWait(g_palTLSTimeMutex, PAL_RTOS_WAIT_FOREVER); 00725 if (PAL_SUCCESS != status) 00726 { 00727 PAL_LOG(ERR, "Failed to get TLS time Mutex error: %" PRId32 ".", status); 00728 goto finish; 00729 } 00730 00731 00732 if (0 == g_timeFromHS) 00733 { 00734 g_timeFromHS = (mbedtls_time_t)serverTime; 00735 } 00736 else 00737 { //! need to change the code for multi-threading mode (Erez) 00738 status = PAL_ERR_TLS_MULTIPLE_HANDSHAKE; 00739 goto finish; 00740 } 00741 00742 platStatus = mbedtls_ssl_renegotiate(&localTLSCtx->tlsCtx); 00743 status = translateTLSHandShakeErrToPALError(localTLSCtx, platStatus); 00744 00745 finish: 00746 g_timeFromHS = 0; 00747 00748 mutexStatus = pal_osMutexRelease(g_palTLSTimeMutex); 00749 if (PAL_SUCCESS != mutexStatus) 00750 { 00751 PAL_LOG(ERR, "Failed to get TLS time Mutex error: %" PRId32 ".", mutexStatus); 00752 } 00753 if (PAL_SUCCESS == status) 00754 { 00755 status = mutexStatus; 00756 } 00757 00758 return status; 00759 } 00760 #endif //PAL_USE_SECURE_TIME 00761 00762 00763 #if (PAL_ENABLE_X509 == 1) 00764 palStatus_t pal_plat_setOwnCertAndPrivateKey (palTLSConfHandle_t palTLSConf, palX509_t* ownCert, palPrivateKey_t* privateKey) 00765 { 00766 palStatus_t status = PAL_SUCCESS; 00767 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00768 int32_t platStatus = SSL_LIB_SUCCESS; 00769 00770 mbedtls_pk_init(&localConfigCtx->pkey); 00771 00772 00773 platStatus = mbedtls_x509_crt_parse_der(&localConfigCtx->owncert, (const unsigned char *)ownCert->buffer, ownCert->size); 00774 if (SSL_LIB_SUCCESS != platStatus) 00775 { 00776 status = PAL_ERR_TLS_FAILED_TO_PARSE_CERT; 00777 goto finish; 00778 } 00779 00780 platStatus = mbedtls_pk_parse_key(&localConfigCtx->pkey, (const unsigned char *)privateKey->buffer, privateKey->size, NULL, 0 ); 00781 if (SSL_LIB_SUCCESS != platStatus) 00782 { 00783 status = PAL_ERR_TLS_FAILED_TO_PARSE_KEY; 00784 goto finish; 00785 } 00786 00787 platStatus = mbedtls_ssl_conf_own_cert(localConfigCtx->confCtx, &localConfigCtx->owncert, &localConfigCtx->pkey); 00788 if (SSL_LIB_SUCCESS != platStatus) 00789 { 00790 status = PAL_ERR_TLS_FAILED_TO_SET_CERT; 00791 } 00792 00793 localConfigCtx->hasKeys = true; 00794 00795 finish: 00796 PAL_LOG(DBG, "TLS set and parse status %" PRIu32 ".", platStatus); 00797 return status; 00798 } 00799 00800 palStatus_t pal_plat_setOwnPrivateKey (palTLSConfHandle_t palTLSConf, palPrivateKey_t* privateKey) 00801 { 00802 palStatus_t status = PAL_SUCCESS; 00803 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00804 int32_t platStatus = SSL_LIB_SUCCESS; 00805 00806 mbedtls_pk_init(&localConfigCtx->pkey); 00807 00808 platStatus = mbedtls_pk_parse_key(&localConfigCtx->pkey, (const unsigned char *)privateKey->buffer, privateKey->size, NULL, 0 ); 00809 if (SSL_LIB_SUCCESS != platStatus) 00810 { 00811 status = PAL_ERR_TLS_FAILED_TO_PARSE_KEY; 00812 goto finish; 00813 } 00814 00815 00816 localConfigCtx->hasKeys = true; 00817 00818 finish: 00819 PAL_LOG(DBG, "Privatekey set and parse status %" PRIu32 ".", platStatus); 00820 return status; 00821 } 00822 00823 palStatus_t pal_plat_setOwnCertChain (palTLSConfHandle_t palTLSConf, palX509_t* ownCert) 00824 { 00825 palStatus_t status = PAL_SUCCESS; 00826 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00827 int32_t platStatus = SSL_LIB_SUCCESS; 00828 00829 platStatus = mbedtls_x509_crt_parse_der(&localConfigCtx->owncert, (const unsigned char *)ownCert->buffer, ownCert->size); 00830 if (SSL_LIB_SUCCESS != platStatus) 00831 { 00832 status = PAL_ERR_TLS_FAILED_TO_PARSE_CERT; 00833 goto finish; 00834 } 00835 00836 platStatus = mbedtls_ssl_conf_own_cert(localConfigCtx->confCtx, &localConfigCtx->owncert, &localConfigCtx->pkey); 00837 if (SSL_LIB_SUCCESS != platStatus) 00838 { 00839 status = PAL_ERR_TLS_FAILED_TO_SET_CERT; 00840 } 00841 00842 localConfigCtx->hasKeys = true; 00843 00844 finish: 00845 PAL_LOG(DBG, "Own cert chain set and parse status %" PRIu32 ".", platStatus); 00846 return status; 00847 } 00848 00849 00850 palStatus_t pal_plat_setCAChain (palTLSConfHandle_t palTLSConf, palX509_t* caChain, palX509CRL_t* caCRL) 00851 { 00852 palStatus_t status = PAL_SUCCESS; 00853 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00854 int32_t platStatus = SSL_LIB_SUCCESS; 00855 00856 platStatus = mbedtls_x509_crt_parse_der(&localConfigCtx->cacert, (const unsigned char *)caChain->buffer, caChain->size); 00857 if (SSL_LIB_SUCCESS != platStatus) 00858 { 00859 PAL_LOG(ERR, "TLS CA chain status %" PRId32 ".", platStatus); 00860 status = PAL_ERR_GENERIC_FAILURE; 00861 goto finish; 00862 } 00863 mbedtls_ssl_conf_ca_chain(localConfigCtx->confCtx, &localConfigCtx->cacert, NULL ); 00864 00865 localConfigCtx->hasChain = true; 00866 finish: 00867 return status; 00868 } 00869 #endif 00870 00871 #if (PAL_ENABLE_PSK == 1) 00872 palStatus_t pal_plat_setPSK (palTLSConfHandle_t palTLSConf, const unsigned char *identity, uint32_t maxIdentityLenInBytes, const unsigned char *psk, uint32_t maxPskLenInBytes) 00873 { 00874 palStatus_t status = PAL_SUCCESS; 00875 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00876 int32_t platStatus = SSL_LIB_SUCCESS; 00877 00878 platStatus = mbedtls_ssl_conf_psk(localConfigCtx->confCtx, psk, maxPskLenInBytes, identity, maxIdentityLenInBytes); 00879 if (SSL_LIB_SUCCESS != platStatus) 00880 { 00881 if (MBEDTLS_ERR_SSL_ALLOC_FAILED == platStatus) 00882 { 00883 status = PAL_ERR_TLS_INIT; 00884 goto finish; 00885 } 00886 PAL_LOG(ERR, "TLS set psk status %" PRId32 ".", platStatus); 00887 status = PAL_ERR_GENERIC_FAILURE; 00888 } 00889 finish: 00890 return status; 00891 } 00892 00893 #endif 00894 palStatus_t pal_plat_tlsSetSocket (palTLSConfHandle_t palTLSConf, palTLSSocket_t* socket) 00895 { 00896 palStatus_t status = PAL_SUCCESS; 00897 00898 status = pal_plat_sslSetIOCallBacks (palTLSConf, socket, palBIOSend, palBIORecv); 00899 return status; 00900 } 00901 00902 palStatus_t pal_plat_sslSetIOCallBacks (palTLSConfHandle_t palTLSConf, palTLSSocket_t* palIOCtx, palBIOSend_f palBIOSend, palBIORecv_f palBIORecv) 00903 { 00904 palStatus_t status = PAL_SUCCESS; 00905 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00906 bool isNonBlocking = false; 00907 00908 localConfigCtx->palIOCtx = palIOCtx; 00909 00910 status = pal_isNonBlocking(palIOCtx->socket, &isNonBlocking); 00911 if (PAL_SUCCESS != status) 00912 { 00913 return status; 00914 } 00915 00916 if (isNonBlocking) 00917 { 00918 mbedtls_ssl_set_bio(&localConfigCtx->tlsContext->tlsCtx, palIOCtx, palBIOSend, palBIORecv, NULL); 00919 } 00920 else 00921 { 00922 mbedtls_ssl_set_bio(&localConfigCtx->tlsContext->tlsCtx, palIOCtx, palBIOSend, NULL, palBIORecv_timeout); 00923 } 00924 00925 return PAL_SUCCESS; 00926 } 00927 00928 00929 00930 palStatus_t pal_plat_sslSetDebugging (palTLSConfHandle_t palTLSConf, uint8_t turnOn) 00931 { 00932 palStatus_t status = PAL_SUCCESS; 00933 palLogFunc_f func = NULL; 00934 #if defined(MBEDTLS_DEBUG_C) 00935 mbedtls_debug_set_threshold(PAL_TLS_DEBUG_THRESHOLD); 00936 #endif 00937 00938 if (turnOn) 00939 { 00940 func = palDebug; 00941 } 00942 status = pal_plat_SetLoggingCb (palTLSConf, func, NULL); 00943 return status; 00944 } 00945 00946 palStatus_t pal_plat_SetLoggingCb (palTLSConfHandle_t palTLSConf, palLogFunc_f palLogFunction, void *logContext) 00947 { 00948 palTLSConf_t* localConfigCtx = (palTLSConf_t*)palTLSConf; 00949 00950 mbedtls_ssl_conf_dbg(localConfigCtx->confCtx, palLogFunction, logContext); 00951 return PAL_SUCCESS; 00952 } 00953 00954 PAL_PRIVATE uint64_t palTimingGetTimer(uint64_t *start_ticks, int reset) 00955 { 00956 uint64_t delta_ms; 00957 uint64_t ticks = pal_osKernelSysTick(); 00958 00959 if (reset) 00960 { 00961 *start_ticks = ticks; 00962 delta_ms = 0; 00963 } 00964 else 00965 { 00966 delta_ms = pal_osKernelSysMilliSecTick(ticks - *start_ticks); 00967 } 00968 00969 return delta_ms; 00970 } 00971 00972 00973 /* 00974 * Set delays to watch 00975 */ 00976 PAL_PRIVATE void palTimingSetDelay( void *data, uint32_t intMs, uint32_t finMs ) 00977 { 00978 00979 palTimingDelayContext_t *ctx = data; 00980 00981 ctx->int_ms = intMs; 00982 ctx->fin_ms = finMs; 00983 00984 if( finMs != 0 ) 00985 { 00986 (void) palTimingGetTimer( &ctx->start_ticks, 1 ); 00987 } 00988 } 00989 00990 /* 00991 * Get number of delays expired 00992 */ 00993 PAL_PRIVATE int palTimingGetDelay( void *data ) 00994 { 00995 int result = 0; 00996 palTimingDelayContext_t *ctx = data; 00997 uint64_t elapsed_ms; 00998 00999 if( ctx->fin_ms == 0 ) 01000 { 01001 result = -1; 01002 goto finish; 01003 } 01004 01005 elapsed_ms = palTimingGetTimer( &ctx->start_ticks, 0 ); 01006 01007 if( elapsed_ms >= ctx->fin_ms ) 01008 { 01009 result = 2; 01010 goto finish; 01011 } 01012 01013 if( elapsed_ms >= ctx->int_ms ) 01014 { 01015 result = 1; 01016 goto finish; 01017 } 01018 01019 finish: 01020 return result; 01021 } 01022 01023 01024 int pal_plat_entropySourceTLS( void *data, unsigned char *output, size_t len, size_t *olen ) 01025 { 01026 palStatus_t status = PAL_SUCCESS; 01027 (void)data; 01028 01029 status = pal_osRandomBuffer((uint8_t*) output, len); 01030 if (PAL_SUCCESS == status) 01031 { 01032 if (NULL != olen) 01033 { 01034 *olen = len; 01035 } 01036 return 0; 01037 } 01038 else 01039 { 01040 return -1; 01041 } 01042 } 01043 01044 PAL_PRIVATE int palBIOSend(palTLSSocketHandle_t socket, const unsigned char *buf, size_t len) 01045 { 01046 palStatus_t status = PAL_SUCCESS; 01047 size_t sentDataSize = 0; 01048 palTLSSocket_t* localSocket = (palTLSSocket_t*)socket; 01049 01050 if (NULLPTR == socket) 01051 { 01052 status = -1; 01053 goto finish; 01054 } 01055 01056 if (PAL_TLS_MODE == localSocket->transportationMode) 01057 { 01058 status = pal_send(localSocket->socket, buf, len, &sentDataSize); 01059 } 01060 else if (PAL_DTLS_MODE == localSocket->transportationMode) 01061 { 01062 status = pal_sendTo(localSocket->socket, buf, len, localSocket->socketAddress, localSocket->addressLength, &sentDataSize); 01063 } 01064 else 01065 { 01066 PAL_LOG(ERR, "TLS BIO send error"); 01067 status = PAL_ERR_GENERIC_FAILURE; 01068 } 01069 if (PAL_SUCCESS == status || PAL_ERR_NO_MEMORY == status || PAL_ERR_SOCKET_WOULD_BLOCK == status) 01070 { 01071 if (PAL_ERR_NO_MEMORY == status) 01072 { 01073 PAL_LOG(DBG, "Network module returned out of memory error, retrying..."); //Network module can return NO_MEMORY error since it was not able to allocate 01074 //memory at this point of time. In this case we translate the error to WANT_WRITE 01075 //in order to let the Network module retry to allocate the memory. 01076 //In case of real out of memory the handshake timeout will break the handshake process. 01077 } 01078 01079 if (0 != sentDataSize) 01080 { 01081 status = sentDataSize; 01082 } 01083 else 01084 { 01085 status = MBEDTLS_ERR_SSL_WANT_WRITE; 01086 } 01087 } 01088 finish: 01089 return status; 01090 } 01091 01092 PAL_PRIVATE int palBIORecv(palTLSSocketHandle_t socket, unsigned char *buf, size_t len) 01093 { 01094 palStatus_t status = PAL_SUCCESS; 01095 size_t recievedDataSize = 0; 01096 palTLSSocket_t* localSocket = (palTLSSocket_t*)socket; 01097 01098 if (NULLPTR == socket) 01099 { 01100 status = -1; 01101 goto finish; 01102 } 01103 01104 if (PAL_TLS_MODE == localSocket->transportationMode) 01105 { 01106 status = pal_recv(localSocket->socket, buf, len, &recievedDataSize); 01107 if (PAL_SUCCESS == status) 01108 { 01109 status = recievedDataSize; 01110 } 01111 else if (PAL_ERR_SOCKET_WOULD_BLOCK == status) 01112 { 01113 status = MBEDTLS_ERR_SSL_WANT_READ; 01114 } 01115 } 01116 else if (PAL_DTLS_MODE == localSocket->transportationMode) 01117 { 01118 status = pal_receiveFrom(localSocket->socket, buf, len, localSocket->socketAddress, &localSocket->addressLength, &recievedDataSize); 01119 if (PAL_SUCCESS == status) 01120 { 01121 if (0 != recievedDataSize) 01122 { 01123 status = recievedDataSize; 01124 } 01125 else 01126 { 01127 status = MBEDTLS_ERR_SSL_WANT_READ; 01128 } 01129 } 01130 else if (PAL_ERR_SOCKET_WOULD_BLOCK == status) 01131 { 01132 status = MBEDTLS_ERR_SSL_WANT_READ; 01133 } 01134 } 01135 else 01136 { 01137 PAL_LOG(ERR, "TLS BIO recv error"); 01138 status = PAL_ERR_GENERIC_FAILURE; 01139 } 01140 01141 finish: 01142 return status; 01143 } 01144 01145 PAL_PRIVATE int palBIORecv_timeout(palTLSSocketHandle_t socket, unsigned char *buf, size_t len, uint32_t timeout) 01146 { 01147 palStatus_t status = PAL_SUCCESS; 01148 size_t recievedDataSize = 0; 01149 uint32_t localTimeOut = timeout; 01150 palTLSSocket_t* localSocket = (palTLSSocket_t*)socket; 01151 bool isNonBlocking = false; 01152 01153 if (NULLPTR == socket) 01154 { 01155 status = -1; 01156 goto finish; 01157 } 01158 01159 status = pal_isNonBlocking(localSocket->socket, &isNonBlocking); 01160 if (PAL_SUCCESS != status) 01161 { 01162 goto finish; 01163 } 01164 01165 if (PAL_TLS_MODE == localSocket->transportationMode) 01166 { 01167 status = pal_recv(localSocket->socket, buf, len, &recievedDataSize); 01168 if (PAL_SUCCESS == status) 01169 { 01170 status = recievedDataSize; 01171 } 01172 else if (PAL_ERR_SOCKET_WOULD_BLOCK == status) 01173 { 01174 status = MBEDTLS_ERR_SSL_WANT_READ; 01175 } 01176 } 01177 else if (PAL_DTLS_MODE == localSocket->transportationMode) 01178 { 01179 if (false == isNonBlocking) // timeout is relevant only if socket is blocking 01180 { 01181 status = pal_setSocketOptions(localSocket->socket, PAL_SO_RCVTIMEO , &localTimeOut, sizeof(localTimeOut)); 01182 if (PAL_SUCCESS != status) 01183 { 01184 goto finish; 01185 } 01186 } 01187 01188 status = pal_receiveFrom(localSocket->socket, buf, len, localSocket->socketAddress, &localSocket->addressLength, &recievedDataSize); 01189 01190 if (PAL_SUCCESS == status) 01191 { 01192 if (0 != recievedDataSize) 01193 { 01194 status = recievedDataSize; 01195 } 01196 else 01197 { 01198 status = MBEDTLS_ERR_SSL_WANT_READ; 01199 } 01200 } 01201 else if (PAL_ERR_SOCKET_WOULD_BLOCK == status) 01202 { 01203 status = MBEDTLS_ERR_SSL_TIMEOUT; 01204 } 01205 } 01206 else 01207 { 01208 PAL_LOG(ERR, "TLS BIO recv timeout error"); 01209 status = PAL_ERR_GENERIC_FAILURE; 01210 } 01211 01212 finish: 01213 return status; 01214 } 01215 01216 #if PAL_USE_SECURE_TIME 01217 #ifdef MBEDTLS_PLATFORM_TIME_ALT 01218 PAL_PRIVATE mbedtls_time_t pal_mbedtlsTimeCB(mbedtls_time_t* timer) 01219 { 01220 palStatus_t status = PAL_SUCCESS; 01221 mbedtls_time_t mbedtlsTime = 0; 01222 01223 status = pal_osMutexWait(g_palTLSTimeMutex, PAL_RTOS_WAIT_FOREVER); 01224 if (PAL_SUCCESS != status) 01225 { 01226 PAL_LOG(ERR, "Failed to get TLS time Mutex error: %" PRId32 ".", status); 01227 goto finish; 01228 } 01229 01230 if (0 != g_timeFromHS) 01231 { 01232 mbedtlsTime = g_timeFromHS; 01233 } 01234 else 01235 { 01236 uint64_t currentTime = pal_osGetTime(); 01237 //mbedtls_time_t is defined to time_t, so we can do a safe copy since till 2038 the value in currentTime is less than MAX_TIME_T_VALUE 01238 mbedtlsTime = (mbedtls_time_t)currentTime; 01239 } 01240 status = pal_osMutexRelease(g_palTLSTimeMutex); 01241 if (PAL_SUCCESS != status) 01242 { 01243 PAL_LOG(ERR, "Failed to release TLS time Mutex error: %" PRId32 ".", status); 01244 } 01245 finish: 01246 if (PAL_SUCCESS != status) 01247 { 01248 mbedtlsTime = 0; 01249 } 01250 return mbedtlsTime; 01251 } 01252 #endif 01253 #endif //PAL_USE_SECURE_TIME 01254 01255 PAL_PRIVATE void palDebug(void *ctx, int debugLevel, const char *fileName, int line, const char *message) 01256 { 01257 (void)ctx; 01258 PAL_LOG(DBG, "%s: %d: %s", fileName, line, message); 01259 } 01260 01261 #ifdef MBEDTLS_ENTROPY_NV_SEED 01262 int mbedtls_platform_std_nv_seed_read( unsigned char *buf, size_t buf_len ) 01263 { 01264 palStatus_t status = PAL_SUCCESS; 01265 status = pal_osRandomBuffer(buf, buf_len); 01266 if (PAL_SUCCESS != status) 01267 { 01268 return -1; 01269 } 01270 return 0; 01271 } 01272 01273 int mbedtls_platform_std_nv_seed_write( unsigned char *buf, size_t buf_len ) 01274 { 01275 return 0; 01276 } 01277 #endif //MBEDTLS_ENTROPY_NV_SEED
Generated on Tue Jul 12 2022 19:12:14 by 1.7.2