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