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