Marco Mayer / Mbed OS Queue
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers coap_security_handler.c Source File

coap_security_handler.c

00001 /*
00002  * Copyright (c) 2015-2017 ARM Limited. All Rights Reserved.
00003  */
00004 
00005 #include <string.h>
00006 #include <time.h>
00007 #include <stdlib.h>
00008 
00009 #include "coap_security_handler.h"
00010 
00011 #ifdef COAP_SECURITY_AVAILABLE
00012 
00013 #include "mbedtls/sha256.h"
00014 #include "mbedtls/error.h"
00015 #include "mbedtls/platform.h"
00016 #include "mbedtls/ssl_cookie.h"
00017 #include "mbedtls/entropy.h"
00018 #include "mbedtls/entropy_poll.h"
00019 #include "mbedtls/ctr_drbg.h"
00020 #include "mbedtls/ssl_ciphersuites.h"
00021 
00022 #include "ns_trace.h"
00023 #include "nsdynmemLIB.h"
00024 #include "coap_connection_handler.h"
00025 #include "randLIB.h"
00026 
00027 struct coap_security_s {
00028     mbedtls_ssl_config          _conf;
00029     mbedtls_ssl_context         _ssl;
00030 
00031     mbedtls_ctr_drbg_context    _ctr_drbg;
00032     mbedtls_entropy_context     _entropy;
00033     bool                        _is_started;
00034     simple_cookie_t             _cookie;
00035     key_block_t                 _keyblk;
00036 
00037     SecureConnectionMode        _conn_mode;
00038 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00039     mbedtls_x509_crt            _cacert;
00040     mbedtls_x509_crt            _owncert;
00041 #endif
00042     mbedtls_pk_context          _pkey;
00043 
00044     uint8_t                     _pw[64];
00045     uint8_t                     _pw_len;
00046 
00047     bool                        _is_blocking;
00048     int8_t                      _socket_id;
00049     int8_t                      _timer_id;
00050     void                        *_handle;
00051     send_cb                     *_send_cb;
00052     receive_cb                  *_receive_cb;
00053     start_timer_cb              *_start_timer_cb;
00054     timer_status_cb             *_timer_status_cb;
00055 
00056 };
00057 
00058 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
00059 const int ECJPAKE_SUITES[] = {
00060     MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8,
00061     0
00062 };
00063 #endif
00064 
00065 static const int PSK_SUITES[] = {
00066     MBEDTLS_TLS_PSK_WITH_AES_128_CBC_SHA256,
00067     MBEDTLS_TLS_PSK_WITH_AES_256_CCM_8,
00068     MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8,
00069     0
00070 };
00071 
00072 
00073 static void set_timer( void *sec_obj, uint32_t int_ms, uint32_t fin_ms );
00074 static int get_timer( void *sec_obj );
00075 static int coap_security_handler_configure_keys( coap_security_t *sec, coap_security_keys_t keys );
00076 
00077 int entropy_poll( void *data, unsigned char *output, size_t len, size_t *olen );
00078 
00079 //Point these back to M2MConnectionHandler!!!
00080 int f_send( void *ctx, const unsigned char *buf, size_t len );
00081 int f_recv(void *ctx, unsigned char *buf, size_t len);
00082 
00083 static int coap_security_handler_init(coap_security_t *sec){
00084     const char *pers = "dtls_client";
00085 #ifdef COAP_SERVICE_PROVIDE_STRONG_ENTROPY_SOURCE
00086     const int entropy_source_type = MBEDTLS_ENTROPY_SOURCE_STRONG;
00087 #else
00088     const int entropy_source_type = MBEDTLS_ENTROPY_SOURCE_WEAK;
00089 #endif
00090     
00091     mbedtls_ssl_init( &sec->_ssl );
00092     mbedtls_ssl_config_init( &sec->_conf );
00093     mbedtls_ctr_drbg_init( &sec->_ctr_drbg );
00094     mbedtls_entropy_init( &sec->_entropy );
00095 
00096 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00097     mbedtls_x509_crt_init( &sec->_cacert );
00098     mbedtls_x509_crt_init( &sec->_owncert );
00099 #endif
00100     mbedtls_pk_init( &sec->_pkey );
00101 
00102     memset(&sec->_cookie, 0, sizeof(simple_cookie_t));
00103     memset(&sec->_keyblk, 0, sizeof(key_block_t));
00104 
00105     sec->_is_started = false;
00106 
00107     if( mbedtls_entropy_add_source( &sec->_entropy, entropy_poll, NULL,
00108                                 128, entropy_source_type ) < 0 ){
00109         return -1;
00110     }
00111 
00112     if( ( mbedtls_ctr_drbg_seed( &sec->_ctr_drbg, mbedtls_entropy_func, &sec->_entropy,
00113                                (const unsigned char *) pers,
00114                                strlen( pers ) ) ) != 0 )
00115     {
00116         return -1;
00117     }
00118     return 0;
00119 }
00120 
00121 bool coap_security_handler_is_started(const coap_security_t *sec)
00122 {
00123     return sec->_is_started;
00124 }
00125 
00126 const void *coap_security_handler_keyblock(const coap_security_t *sec)
00127 {
00128     return sec->_keyblk.value;
00129 }
00130 
00131 static void coap_security_handler_reset(coap_security_t *sec){
00132 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00133     mbedtls_x509_crt_free(&sec->_cacert);
00134     mbedtls_x509_crt_free(&sec->_owncert);
00135 #endif
00136 
00137     mbedtls_pk_free(&sec->_pkey);
00138 
00139     mbedtls_entropy_free( &sec->_entropy );
00140     mbedtls_ctr_drbg_free( &sec->_ctr_drbg );
00141     mbedtls_ssl_config_free(&sec->_conf);
00142     mbedtls_ssl_free(&sec->_ssl);
00143 }
00144 
00145 
00146 coap_security_t *coap_security_create(int8_t socket_id, int8_t timer_id, void *handle, SecureConnectionMode mode,
00147                                           send_cb *socket_cb,
00148                                           receive_cb *receive_data_cb,
00149                                           start_timer_cb *timer_start_cb,
00150                                           timer_status_cb *timer_stat_cb)
00151 {
00152     if (socket_cb == NULL || receive_data_cb == NULL || timer_start_cb == NULL || timer_stat_cb == NULL) {
00153         return NULL;
00154     }
00155     coap_security_t *this = ns_dyn_mem_alloc(sizeof(coap_security_t));
00156     if( !this ){
00157         return NULL;
00158     }
00159     memset(this, 0, sizeof(coap_security_t));
00160     if (-1 == coap_security_handler_init(this)) {
00161         ns_dyn_mem_free(this);
00162         return NULL;
00163     }
00164     this->_handle = handle;
00165     this->_conn_mode = mode;
00166     memset(this->_pw, 0, 64);
00167     this->_pw_len = 0;
00168     this->_socket_id = socket_id;
00169     this->_timer_id = timer_id;
00170     this->_send_cb = socket_cb;
00171     this->_receive_cb = receive_data_cb;
00172     this->_start_timer_cb = timer_start_cb;
00173     this->_timer_status_cb = timer_stat_cb;
00174 
00175     return this;
00176 }
00177 
00178 void coap_security_destroy(coap_security_t *sec){
00179     if( sec ){
00180         coap_security_handler_reset(sec);
00181         ns_dyn_mem_free(sec);
00182         sec = NULL;
00183     }
00184 }
00185 
00186 /**** Random number functions ****/
00187 
00188 /**
00189  * Get a random array of bytes.
00190  * Called back by mbedtls when it wants to fill a buffer with random data
00191  * Must return 0 on success.
00192  */
00193 static int get_random(void *ctx, unsigned char *buf, size_t len)
00194 {
00195     static int initialised = 0;
00196     uint32_t i;
00197 
00198     (void)ctx; /* No context */
00199 
00200     if (!initialised) {
00201         randLIB_seed_random();
00202         initialised = 1;
00203     }
00204 
00205     for (i = 0; i < len; i++) {
00206         buf[i] = (uint8_t)randLIB_get_8bit();
00207     }
00208     return 0; /* Success */
00209 }
00210 
00211 /**** Cookie functions ****/
00212 static int simple_cookie_write(void *ctx,
00213                                unsigned char **p, unsigned char *end,
00214                                const unsigned char *info, size_t ilen)
00215 {
00216     //TODO: As per RFC 6347 cookie must be stateless. This is not the case in here!
00217     //This should be fixed if we see that dos attack would be an issue.
00218     //this is proposed solution in RFC: Cookie = HMAC(Secret, Client-IP, Client-Parameters)
00219     //Secret is generated here and oftenly changed to prevent statistical attack
00220     simple_cookie_t *p_cookie = (simple_cookie_t *)ctx;
00221 
00222     /* Not using additional info */
00223     (void)info;
00224     (void)ilen;
00225 
00226     if ((size_t)(end - *p) < COOKIE_SIMPLE_LEN) {
00227         return MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL;
00228     }
00229 
00230     /* Use a simple random number of length COOKIE_SIMPLE_LEN bytes */
00231     get_random(NULL, p_cookie->value, COOKIE_SIMPLE_LEN);
00232     memcpy(*p, p_cookie->value, COOKIE_SIMPLE_LEN);
00233     p_cookie->len = COOKIE_SIMPLE_LEN;
00234     *p += COOKIE_SIMPLE_LEN;
00235     return 0;
00236 }
00237 
00238 static int simple_cookie_check(void *ctx,
00239                                const unsigned char *cookie, size_t clen,
00240                                const unsigned char *info, size_t ilen)
00241 {
00242     simple_cookie_t *p_cookie = (simple_cookie_t *)ctx;
00243 
00244     /* Not using additional info */
00245     (void)info;
00246     (void)ilen;
00247 
00248     if ((p_cookie->len == 0) ||
00249         (clen != p_cookie->len) ||
00250         (memcmp(cookie, p_cookie->value, p_cookie->len) != 0)) {
00251         return -1; /* This is what it is in mbedtls... */
00252     }
00253     return 0;
00254 }
00255 
00256 /**** Key export function ****/
00257 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
00258 static int export_key_block(void *ctx,
00259                             const unsigned char *mk, const unsigned char *kb,
00260                             size_t maclen, size_t keylen, size_t ivlen)
00261 {
00262     key_block_t *p_key_block = (key_block_t *)ctx;
00263 
00264     /* Not using master key */
00265     (void)mk;
00266 
00267     /* Sanity check MAC and key lengths */
00268     if ((maclen != 0) || (((2 * keylen) + (2 * ivlen)) != KEY_BLOCK_LEN)) {
00269         return -1; /* Something seriously wrong! */
00270     }
00271 
00272     /* Copy the key block we are using */
00273     /* No need to skip over MAC keys, MAC len must be 0 if we are here */
00274     memcpy(p_key_block->value, kb /* + (2 * maclen)*/, (2 * keylen) + (2 * ivlen));
00275     return 0;
00276 }
00277 #endif
00278 
00279 int coap_security_handler_configure_keys( coap_security_t *sec, coap_security_keys_t keys )
00280 {
00281     int ret = -1;
00282     switch( sec->_conn_mode ){
00283         case Certificate:{
00284 #if defined(MBEDTLS_X509_CRT_PARSE_C)
00285         if(  mbedtls_x509_crt_parse( &sec->_cacert, keys._server_cert,
00286                                      keys._server_cert_len ) < 0 ){
00287             break;
00288         }
00289         if( mbedtls_x509_crt_parse( &sec->_owncert, keys._pub_cert_or_identifier,
00290                                     keys._pub_len ) < 0 ){
00291             break;
00292         }
00293         if( mbedtls_pk_parse_key(&sec->_pkey, keys._priv, keys._priv_len, NULL, 0) < 0){
00294             break;
00295         }
00296         //TODO: If needed in server mode, this won't work
00297         if( 0 != mbedtls_ssl_conf_own_cert(&sec->_conf, &sec->_owncert, &sec->_pkey) ){
00298             break;
00299         }
00300         //TODO: use MBEDTLS_SSL_VERIFY_REQUIRED instead of optional
00301         mbedtls_ssl_conf_authmode( &sec->_conf, MBEDTLS_SSL_VERIFY_OPTIONAL );
00302         mbedtls_ssl_conf_ca_chain( &sec->_conf, &sec->_cacert, NULL );
00303         ret = 0;
00304 #endif
00305         break;
00306         }
00307         case PSK: {
00308 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
00309         if( 0 != mbedtls_ssl_conf_psk(&sec->_conf, keys._priv, keys._priv_len, keys._pub_cert_or_identifier, keys._pub_len) ){
00310             break;
00311         }
00312         mbedtls_ssl_conf_ciphersuites(&sec->_conf, PSK_SUITES);
00313         ret = 0;
00314 #endif
00315         break;
00316         }
00317         case ECJPAKE: {
00318 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
00319             if( mbedtls_ssl_set_hs_ecjpake_password(&sec->_ssl, keys._priv, keys._priv_len) != 0 ){
00320                 return -1;
00321             }
00322             mbedtls_ssl_conf_ciphersuites(&sec->_conf, ECJPAKE_SUITES);
00323 
00324             //NOTE: If thread starts supporting PSK in other modes, then this will be needed!
00325             mbedtls_ssl_conf_export_keys_cb(&sec->_conf,
00326                                             export_key_block,
00327                                             &sec->_keyblk);
00328         ret = 0;
00329 #endif
00330         break;
00331         }
00332 
00333         default:
00334         break;
00335     }
00336     return ret;
00337 }
00338 
00339 int coap_security_handler_connect(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys){
00340     int ret = -1;
00341 
00342     if( !sec ){
00343         return ret;
00344     }
00345     sec->_is_blocking = true;
00346 
00347     int endpoint = MBEDTLS_SSL_IS_CLIENT;
00348     if( is_server ){
00349         endpoint = MBEDTLS_SSL_IS_SERVER;
00350     }
00351 
00352     int mode = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
00353     if( sock_mode == TLS ){
00354         mode = MBEDTLS_SSL_TRANSPORT_STREAM;
00355     }
00356 
00357     if( ( mbedtls_ssl_config_defaults( &sec->_conf,
00358                        endpoint,
00359                        mode, 0 ) ) != 0 )
00360     {
00361         return -1;
00362     }
00363 
00364     mbedtls_ssl_set_bio( &sec->_ssl, sec,
00365                         f_send, f_recv, NULL );
00366 
00367     mbedtls_ssl_set_timer_cb( &sec->_ssl, sec, set_timer,
00368                                             get_timer );
00369 
00370     if( coap_security_handler_configure_keys( sec, keys ) != 0 ){
00371         return -1;
00372     }
00373 
00374 #ifdef MBEDTLS_SSL_SRV_C
00375     mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write,
00376                                   simple_cookie_check,
00377                                   &sec->_cookie);
00378 #endif
00379 
00380     sec->_is_started = true;
00381 
00382     do {
00383         ret = mbedtls_ssl_handshake_step( &sec->_ssl );
00384         if( ret == MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED ){ //cookie check failed
00385             if( is_server ){
00386                 mbedtls_ssl_session_reset(&sec->_ssl);
00387 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
00388                 if( mbedtls_ssl_set_hs_ecjpake_password(&sec->_ssl, keys._priv, keys._priv_len) != 0 ){
00389                     return -1;
00390                 }
00391 #endif
00392                 ret = MBEDTLS_ERR_SSL_WANT_READ; //needed to keep doing
00393             }else{
00394                 ret = -1;
00395             }
00396         }
00397     }while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
00398            ret == MBEDTLS_ERR_SSL_WANT_WRITE );
00399 
00400     if( ret != 0){
00401         ret = -1;
00402     }else{
00403         if( mbedtls_ssl_get_verify_result( &sec->_ssl ) != 0 )
00404             {
00405                 ret = -1;
00406             }
00407     }
00408 
00409     return ret;
00410 }
00411 
00412 int coap_security_handler_connect_non_blocking(coap_security_t *sec, bool is_server, SecureSocketMode sock_mode, coap_security_keys_t keys, uint32_t timeout_min, uint32_t timeout_max)
00413 {
00414 
00415     if( !sec ){
00416         return -1;
00417     }
00418     sec->_is_blocking = false;
00419 
00420     int endpoint = MBEDTLS_SSL_IS_CLIENT;
00421     if( is_server ){
00422         endpoint = MBEDTLS_SSL_IS_SERVER;
00423     }
00424 
00425     int mode = MBEDTLS_SSL_TRANSPORT_DATAGRAM;
00426     if( sock_mode == TLS ){
00427         mode = MBEDTLS_SSL_TRANSPORT_STREAM;
00428     }
00429 
00430     if( ( mbedtls_ssl_config_defaults( &sec->_conf,
00431                        endpoint,
00432                        mode, 0 ) ) != 0 )
00433     {
00434         return -1;
00435     }
00436 
00437     if(!timeout_max && !timeout_min){
00438         mbedtls_ssl_conf_handshake_timeout( &sec->_conf, DTLS_HANDSHAKE_TIMEOUT_MIN, DTLS_HANDSHAKE_TIMEOUT_MAX );
00439     }
00440     else{
00441         mbedtls_ssl_conf_handshake_timeout( &sec->_conf, timeout_min, timeout_max );
00442     }
00443 
00444     mbedtls_ssl_conf_rng( &sec->_conf, mbedtls_ctr_drbg_random, &sec->_ctr_drbg );
00445 
00446     if( ( mbedtls_ssl_setup( &sec->_ssl, &sec->_conf ) ) != 0 )
00447     {
00448        return -1;
00449     }
00450 
00451     mbedtls_ssl_set_bio( &sec->_ssl, sec,
00452                         f_send, f_recv, NULL );
00453 
00454     mbedtls_ssl_set_timer_cb( &sec->_ssl, sec, set_timer,
00455                                             get_timer );
00456 
00457 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
00458     //TODO: Figure out better way!!!
00459     //Password should never be stored in multiple places!!!
00460     if( is_server && keys._priv_len > 0){
00461         memcpy(sec->_pw, keys._priv, keys._priv_len);
00462         sec->_pw_len = keys._priv_len;
00463     }
00464 #endif
00465 
00466     if( coap_security_handler_configure_keys( sec, keys ) != 0 ){
00467         return -1;
00468     }
00469 
00470 #ifdef MBEDTLS_SSL_SRV_C
00471     mbedtls_ssl_conf_dtls_cookies(&sec->_conf, simple_cookie_write,
00472                                   simple_cookie_check,
00473                                   &sec->_cookie);
00474 #endif
00475 
00476     mbedtls_ssl_conf_min_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
00477     mbedtls_ssl_conf_max_version(&sec->_conf, MBEDTLS_SSL_MAJOR_VERSION_3, MBEDTLS_SSL_MAJOR_VERSION_3);
00478     
00479     sec->_is_started = true;
00480 
00481     int ret = mbedtls_ssl_handshake_step( &sec->_ssl );
00482     if( ret == 0 ){
00483         ret = mbedtls_ssl_handshake_step( &sec->_ssl );
00484         if( is_server && 0 == ret){
00485             ret = coap_security_handler_continue_connecting( sec );
00486         }
00487     }
00488 
00489     if( ret >= 0){
00490         ret = 1;
00491     }else{
00492         ret = -1;
00493     }
00494     return ret;
00495 }
00496 
00497 int coap_security_handler_continue_connecting(coap_security_t *sec){
00498     int ret = -1;
00499 
00500     while( ret != MBEDTLS_ERR_SSL_WANT_READ ){
00501         ret = mbedtls_ssl_handshake_step( &sec->_ssl );
00502 
00503         if( MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED == ret){
00504             mbedtls_ssl_session_reset(&sec->_ssl);
00505 #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED)
00506             if( mbedtls_ssl_set_hs_ecjpake_password(&sec->_ssl, sec->_pw, sec->_pw_len) != 0 ){
00507                 return -1;
00508             }
00509 #endif
00510             return 1;
00511         }
00512         else if(ret && (ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE)){
00513             return ret;
00514         }
00515 
00516         if( sec->_ssl.state == MBEDTLS_SSL_HANDSHAKE_OVER ){
00517             return 0;
00518         }
00519     }
00520 
00521     if(ret == MBEDTLS_ERR_SSL_WANT_READ || ret == MBEDTLS_ERR_SSL_WANT_WRITE){
00522         return 1;
00523     }
00524 
00525     return -1;
00526 }
00527 
00528 
00529 int coap_security_handler_send_message(coap_security_t *sec, unsigned char *message, size_t len){
00530     int ret=-1;
00531 
00532     if( sec ){
00533         do ret = mbedtls_ssl_write( &sec->_ssl, (unsigned char *) message, len );
00534         while( ret == MBEDTLS_ERR_SSL_WANT_READ ||
00535                ret == MBEDTLS_ERR_SSL_WANT_WRITE );
00536     }
00537 
00538     return ret; //bytes written
00539 }
00540 
00541 int coap_security_send_close_alert(coap_security_t *sec)
00542 {
00543     if( !sec ){
00544         return -1;
00545     }
00546 
00547     if(!mbedtls_ssl_close_notify(&sec->_ssl)){
00548         return 0;
00549     }
00550     return -1;
00551 }
00552 
00553 int coap_security_handler_read(coap_security_t *sec, unsigned char* buffer, size_t len){
00554     int ret=-1;
00555     int max_loops = 100;
00556 
00557     if( sec && buffer ){
00558         memset( buffer, 0, len );
00559         do {
00560             ret = mbedtls_ssl_read( &sec->_ssl, buffer, len );
00561         } while( (ret == MBEDTLS_ERR_SSL_WANT_READ ||
00562                   ret == MBEDTLS_ERR_SSL_WANT_WRITE)
00563                 && --max_loops);
00564     }
00565     return ret; //bytes read
00566 }
00567 
00568 /**** Timer functions ****/
00569 
00570 /**
00571  * Set timer function.
00572  * Called back by mbedtls when it wants to set a timer.
00573  * Accepts an intermediate and a final delay in milliseconds
00574  * If the final delay is 0, cancels the running timer.
00575  * TODO - might be better to use an event timer in conjunction with
00576  * CoAP tasklet
00577  */
00578 static void set_timer(void *sec_obj, uint32_t int_ms, uint32_t fin_ms)
00579 {
00580     coap_security_t *sec = (coap_security_t *)sec_obj;
00581     if( sec->_start_timer_cb ){
00582         sec->_start_timer_cb( sec->_timer_id, int_ms, fin_ms);
00583     }
00584 }
00585 
00586 /**
00587  * Get timer function.
00588  * Called back by mbedtls when it wants to get a timer state.
00589  * Returns the state of the current timer
00590  * TODO - might be better to use an event timer in conjunction with
00591  * CoAP tasklet
00592  */
00593 static int get_timer(void *sec_obj)
00594 {
00595     coap_security_t *sec = (coap_security_t *)sec_obj;
00596     if( sec->_timer_status_cb ){
00597         return sec->_timer_status_cb(sec->_timer_id);
00598     }
00599     return -1;
00600 }
00601 
00602 int f_send( void *ctx, const unsigned char *buf, size_t len){
00603     coap_security_t *sec = (coap_security_t *)ctx;
00604     return sec->_send_cb(sec->_socket_id, sec->_handle, buf, len);
00605 }
00606 
00607 int f_recv(void *ctx, unsigned char *buf, size_t len){
00608     coap_security_t *sec = (coap_security_t *)ctx;
00609     return sec->_receive_cb(sec->_socket_id, buf, len);
00610 }
00611 
00612 int entropy_poll( void *ctx, unsigned char *output, size_t len,
00613                            size_t *olen )
00614 {
00615     (void)ctx;
00616     //TODO: change to more secure random
00617     randLIB_seed_random();
00618     char *c = (char*)ns_dyn_mem_temporary_alloc(len);
00619     if( !c ){
00620         return MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
00621     }
00622     memset(c, 0, len);
00623     for(uint16_t i=0; i < len; i++){
00624         *(c + i) = (char)randLIB_get_8bit();
00625     }
00626     memmove(output, c, len);
00627     *olen = len;
00628 
00629     ns_dyn_mem_free(c);
00630     return( 0 );
00631 }
00632 
00633 #endif // COAP_SECURITY_AVAILABLE