Simulated product dispenser

Dependencies:   HTS221

Fork of mbed-cloud-workshop-connect-HTS221 by Jim Carver

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pal_plat_TLS.c Source File

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