/* * Checkup routine for HMAC_DRBG with SHA-1 */ int mbedtls_hmac_drbg_self_test( int verbose ) { mbedtls_hmac_drbg_context ctx; unsigned char buf[OUTPUT_LEN]; const mbedtls_md_info_t *md_info = mbedtls_md_info_from_type( MBEDTLS_MD_SHA1 ); mbedtls_hmac_drbg_init( &ctx ); /* * PR = True */ if( verbose != 0 ) mbedtls_printf( " HMAC_DRBG (PR = True) : " ); test_offset = 0; CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, hmac_drbg_self_test_entropy, (void *) entropy_pr, NULL, 0 ) ); mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON ); CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); CHK( memcmp( buf, result_pr, OUTPUT_LEN ) ); mbedtls_hmac_drbg_free( &ctx ); mbedtls_hmac_drbg_free( &ctx ); if( verbose != 0 ) mbedtls_printf( "passed\n" ); /* * PR = False */ if( verbose != 0 ) mbedtls_printf( " HMAC_DRBG (PR = False) : " ); mbedtls_hmac_drbg_init( &ctx ); test_offset = 0; CHK( mbedtls_hmac_drbg_seed( &ctx, md_info, hmac_drbg_self_test_entropy, (void *) entropy_nopr, NULL, 0 ) ); CHK( mbedtls_hmac_drbg_reseed( &ctx, NULL, 0 ) ); CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); CHK( mbedtls_hmac_drbg_random( &ctx, buf, OUTPUT_LEN ) ); CHK( memcmp( buf, result_nopr, OUTPUT_LEN ) ); mbedtls_hmac_drbg_free( &ctx ); mbedtls_hmac_drbg_free( &ctx ); if( verbose != 0 ) mbedtls_printf( "passed\n" ); if( verbose != 0 ) mbedtls_printf( "\n" ); return( 0 ); }
/* * Deterministic signature wrapper */ int mbedtls_ecdsa_sign_det( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, mbedtls_md_type_t md_alg ) { int ret; mbedtls_hmac_drbg_context rng_ctx; unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; size_t grp_len = ( grp->nbits + 7 ) / 8; const mbedtls_md_info_t *md_info; mbedtls_mpi h; if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); mbedtls_mpi_init( &h ); mbedtls_hmac_drbg_init( &rng_ctx ); /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); mbedtls_hmac_drbg_seed_buf( &rng_ctx, md_info, data, 2 * grp_len ); ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, &rng_ctx ); cleanup: mbedtls_hmac_drbg_free( &rng_ctx ); mbedtls_mpi_free( &h ); return( ret ); }
/* * Free the components of a sign_det restart sub-context */ static void ecdsa_restart_det_free( mbedtls_ecdsa_restart_det_ctx *ctx ) { if( ctx == NULL ) return; mbedtls_hmac_drbg_free( &ctx->rng_ctx ); ecdsa_restart_det_init( ctx ); }
static void conn_link_mbedtls_cleanup(void) { DEBUGASSERT(g_https_data.mbedtls); DEBUGASSERT(g_https_data.initialized); #ifdef CONFIG_MBEDTLS_ENABLE_CTR_DRBG mbedtls_ctr_drbg_free(&g_https_data.mbedtls->drbg); #else mbedtls_hmac_drbg_free(&g_https_data.mbedtls->drbg); #endif mbedtls_ssl_session_free(&g_https_data.mbedtls->saved_session); mbedtls_ssl_config_free(&g_https_data.mbedtls->conf); free(g_https_data.mbedtls); g_https_data.mbedtls = NULL; mbedtls_platform_set_calloc_free(calloc, free); g_https_data.initialized = false; DEBUGASSERT(!g_https_data.ssl_inbuf_in_use); }
/* * Deterministic signature wrapper */ static int ecdsa_sign_det_restartable( mbedtls_ecp_group *grp, mbedtls_mpi *r, mbedtls_mpi *s, const mbedtls_mpi *d, const unsigned char *buf, size_t blen, mbedtls_md_type_t md_alg, mbedtls_ecdsa_restart_ctx *rs_ctx ) { int ret; mbedtls_hmac_drbg_context rng_ctx; mbedtls_hmac_drbg_context *p_rng = &rng_ctx; unsigned char data[2 * MBEDTLS_ECP_MAX_BYTES]; size_t grp_len = ( grp->nbits + 7 ) / 8; const mbedtls_md_info_t *md_info; mbedtls_mpi h; if( ( md_info = mbedtls_md_info_from_type( md_alg ) ) == NULL ) return( MBEDTLS_ERR_ECP_BAD_INPUT_DATA ); mbedtls_mpi_init( &h ); mbedtls_hmac_drbg_init( &rng_ctx ); ECDSA_RS_ENTER( det ); #if defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && rs_ctx->det != NULL ) { /* redirect to our context */ p_rng = &rs_ctx->det->rng_ctx; /* jump to current step */ if( rs_ctx->det->state == ecdsa_det_sign ) goto sign; } #endif /* MBEDTLS_ECP_RESTARTABLE */ /* Use private key and message hash (reduced) to initialize HMAC_DRBG */ MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( d, data, grp_len ) ); MBEDTLS_MPI_CHK( derive_mpi( grp, &h, buf, blen ) ); MBEDTLS_MPI_CHK( mbedtls_mpi_write_binary( &h, data + grp_len, grp_len ) ); mbedtls_hmac_drbg_seed_buf( p_rng, md_info, data, 2 * grp_len ); #if defined(MBEDTLS_ECP_RESTARTABLE) if( rs_ctx != NULL && rs_ctx->det != NULL ) rs_ctx->det->state = ecdsa_det_sign; sign: #endif #if defined(MBEDTLS_ECDSA_SIGN_ALT) ret = mbedtls_ecdsa_sign( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, p_rng ); #else ret = ecdsa_sign_restartable( grp, r, s, d, buf, blen, mbedtls_hmac_drbg_random, p_rng, rs_ctx ); #endif /* MBEDTLS_ECDSA_SIGN_ALT */ cleanup: mbedtls_hmac_drbg_free( &rng_ctx ); mbedtls_mpi_free( &h ); ECDSA_RS_LEAVE( det ); return( ret ); }
static int conn_link_mbedtls_initialize(void) { if (g_https_data.initialized) return 0; g_https_data.mbedtls = calloc(1, sizeof(*g_https_data.mbedtls)); if (!g_https_data.mbedtls) return -1; mbedtls_platform_set_calloc_free(conn_link_mbedtls_calloc, conn_link_mbedtls_free); mbedtls_ssl_config_init(&g_https_data.mbedtls->conf); mbedtls_ssl_session_init(&g_https_data.mbedtls->saved_session); mbedtls_entropy_init(&g_https_data.mbedtls->entropy); #ifdef CONFIG_MBEDTLS_ENABLE_CTR_DRBG mbedtls_ctr_drbg_init(&g_https_data.mbedtls->drbg); if (mbedtls_ctr_drbg_seed(&g_https_data.mbedtls->drbg, mbedtls_entropy_func, &g_https_data.mbedtls->entropy, (const void *)"sfx", 3) != 0) { goto err_free; } #else const mbedtls_md_info_t *md_info = NULL; #ifdef MBEDTLS_SHA1_C md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); #elif defined(MBEDTLS_SHA256_C) md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA256); #elif defined(MBEDTLS_SHA512_C) md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA512); #endif DEBUGASSERT(md_info != NULL); mbedtls_hmac_drbg_init(&g_https_data.mbedtls->drbg); if (mbedtls_hmac_drbg_seed(&g_https_data.mbedtls->drbg, md_info, mbedtls_entropy_func, &g_https_data.mbedtls->entropy, (const void *)"sfx", 3) != 0) { goto err_free; } #endif if (mbedtls_ssl_config_defaults(&g_https_data.mbedtls->conf, MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, MBEDTLS_SSL_PRESET_DEFAULT) != 0) { goto err_free; } #ifdef CONFIG_MBEDTLS_ENABLE_CTR_DRBG mbedtls_ssl_conf_rng(&g_https_data.mbedtls->conf, mbedtls_ctr_drbg_random, &g_https_data.mbedtls->drbg); #else mbedtls_ssl_conf_rng(&g_https_data.mbedtls->conf, mbedtls_hmac_drbg_random, &g_https_data.mbedtls->drbg); #endif mbedtls_ssl_conf_authmode(&g_https_data.mbedtls->conf, MBEDTLS_SSL_VERIFY_NONE); #ifdef CONFIG_MBEDTLS_MAX_FRAGMENT mbedtls_ssl_conf_max_frag_len(&g_https_data.mbedtls->conf, MBEDTLS_SSL_MAX_FRAG_LEN_512); #endif #ifdef CONFIG_MBEDTLS_TRUNCATED_HMAC mbedtls_ssl_conf_truncated_hmac(&g_https_data.mbedtls->conf, MBEDTLS_SSL_TRUNC_HMAC_ENABLED); #endif #ifdef CONFIG_MBEDTLS_SESSION_TICKET /* Use SSL out-fragment buffer of at least 384 bytes with session tickets, * preferably at least 512 bytes. */ mbedtls_ssl_conf_session_tickets(&g_https_data.mbedtls->conf, MBEDTLS_SSL_SESSION_TICKETS_ENABLED); #endif g_https_data.initialized = true; return 0; err_free: #ifdef CONFIG_MBEDTLS_ENABLE_CTR_DRBG mbedtls_ctr_drbg_free(&g_https_data.mbedtls->drbg); #else mbedtls_hmac_drbg_free(&g_https_data.mbedtls->drbg); #endif mbedtls_ssl_session_free(&g_https_data.mbedtls->saved_session); mbedtls_ssl_config_free(&g_https_data.mbedtls->conf); free(g_https_data.mbedtls); g_https_data.mbedtls = NULL; mbedtls_platform_set_calloc_free(calloc, free); g_https_data.initialized = false; return -1; }