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.
Fork of mbedtls by
tests/suites/test_suite_hmac_drbg.function
- Committer:
- Jasper Wallace 
- Date:
- 2017-09-29
- Revision:
- 2:bbdeda018a3c
- Parent:
- 0:cdf462088d13
File content as of revision 2:bbdeda018a3c:
/* BEGIN_HEADER */
#include "mbedtls/hmac_drbg.h"
typedef struct
{
    unsigned char *p;
    size_t len;
} entropy_ctx;
int mbedtls_entropy_func( void *data, unsigned char *buf, size_t len )
{
    entropy_ctx *ctx = (entropy_ctx *) data;
    if( len > ctx->len )
        return( -1 );
    memcpy( buf, ctx->p, len );
    ctx->p += len;
    ctx->len -= len;
    return( 0 );
}
/* END_HEADER */
/* BEGIN_DEPENDENCIES
 * depends_on:MBEDTLS_HMAC_DRBG_C
 * END_DEPENDENCIES
 */
/* BEGIN_CASE */
void hmac_drbg_entropy_usage( int md_alg )
{
    unsigned char out[16];
    unsigned char buf[1024];
    const mbedtls_md_info_t *md_info;
    mbedtls_hmac_drbg_context ctx;
    entropy_ctx entropy;
    size_t last_len, i, reps = 10;
    mbedtls_hmac_drbg_init( &ctx );
    memset( buf, 0, sizeof( buf ) );
    memset( out, 0, sizeof( out ) );
    entropy.len = sizeof( buf );
    entropy.p = buf;
    md_info = mbedtls_md_info_from_type( md_alg );
    TEST_ASSERT( md_info != NULL );
    /* Init must use entropy */
    last_len = entropy.len;
    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &entropy,
                                 NULL, 0 ) == 0 );
    TEST_ASSERT( entropy.len < last_len );
    /* By default, PR is off and reseed_interval is large,
     * so the next few calls should not use entropy */
    last_len = entropy.len;
    for( i = 0; i < reps; i++ )
    {
        TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) - 4 ) == 0 );
        TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) - 4,
                                                buf, 16 ) == 0 );
    }
    TEST_ASSERT( entropy.len == last_len );
    /* While at it, make sure we didn't write past the requested length */
    TEST_ASSERT( out[sizeof( out ) - 4] == 0 );
    TEST_ASSERT( out[sizeof( out ) - 3] == 0 );
    TEST_ASSERT( out[sizeof( out ) - 2] == 0 );
    TEST_ASSERT( out[sizeof( out ) - 1] == 0 );
    /* Set reseed_interval to the number of calls done,
     * so the next call should reseed */
    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 2 * reps );
    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( entropy.len < last_len );
    /* The new few calls should not reseed */
    last_len = entropy.len;
    for( i = 0; i < reps / 2; i++ )
    {
        TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
        TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, out, sizeof( out ) ,
                                                buf, 16 ) == 0 );
    }
    TEST_ASSERT( entropy.len == last_len );
    /* Now enable PR, so the next few calls should all reseed */
    mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( entropy.len < last_len );
    /* Finally, check setting entropy_len */
    mbedtls_hmac_drbg_set_entropy_len( &ctx, 42 );
    last_len = entropy.len;
    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( (int) last_len - entropy.len == 42 );
    mbedtls_hmac_drbg_set_entropy_len( &ctx, 13 );
    last_len = entropy.len;
    TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
    TEST_ASSERT( (int) last_len - entropy.len == 13 );
exit:
    mbedtls_hmac_drbg_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_FS_IO */
void hmac_drbg_seed_file( int md_alg, char *path, int ret )
{
    const mbedtls_md_info_t *md_info;
    mbedtls_hmac_drbg_context ctx;
    mbedtls_hmac_drbg_init( &ctx );
    md_info = mbedtls_md_info_from_type( md_alg );
    TEST_ASSERT( md_info != NULL );
    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, rnd_std_rand, NULL,
                                 NULL, 0 ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_write_seed_file( &ctx, path ) == ret );
    TEST_ASSERT( mbedtls_hmac_drbg_update_seed_file( &ctx, path ) == ret );
exit:
    mbedtls_hmac_drbg_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void hmac_drbg_buf( int md_alg )
{
    unsigned char out[16];
    unsigned char buf[100];
    const mbedtls_md_info_t *md_info;
    mbedtls_hmac_drbg_context ctx;
    size_t i;
    mbedtls_hmac_drbg_init( &ctx );
    memset( buf, 0, sizeof( buf ) );
    memset( out, 0, sizeof( out ) );
    md_info = mbedtls_md_info_from_type( md_alg );
    TEST_ASSERT( md_info != NULL );
    TEST_ASSERT( mbedtls_hmac_drbg_seed_buf( &ctx, md_info, buf, sizeof( buf ) ) == 0 );
    /* Make sure it never tries to reseed (would segfault otherwise) */
    mbedtls_hmac_drbg_set_reseed_interval( &ctx, 3 );
    mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
    for( i = 0; i < 30; i++ )
        TEST_ASSERT( mbedtls_hmac_drbg_random( &ctx, out, sizeof( out ) ) == 0 );
exit:
    mbedtls_hmac_drbg_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void hmac_drbg_no_reseed( int md_alg,
                          char *entropy_hex, char *custom_hex,
                          char *add1_hex, char *add2_hex,
                          char *output_hex )
{
    unsigned char data[1024];
    unsigned char entropy[512];
    unsigned char custom[512];
    unsigned char add1[512];
    unsigned char add2[512];
    unsigned char output[512];
    unsigned char my_output[512];
    size_t custom_len, add1_len, add2_len, out_len;
    entropy_ctx p_entropy;
    const mbedtls_md_info_t *md_info;
    mbedtls_hmac_drbg_context ctx;
    mbedtls_hmac_drbg_init( &ctx );
    memset( my_output, 0, sizeof my_output );
    custom_len = unhexify( custom, custom_hex );
    add1_len = unhexify( add1, add1_hex );
    add2_len = unhexify( add2, add2_hex );
    out_len = unhexify( output, output_hex );
    p_entropy.len = unhexify( entropy, entropy_hex );
    p_entropy.p = entropy;
    md_info = mbedtls_md_info_from_type( md_alg );
    TEST_ASSERT( md_info != NULL );
    /* Test the simplified buffer-based variant */
    memcpy( data, entropy, p_entropy.len );
    memcpy( data + p_entropy.len, custom, custom_len );
    TEST_ASSERT( mbedtls_hmac_drbg_seed_buf( &ctx, md_info,
                                     data, p_entropy.len + custom_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add1, add1_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add2, add2_len ) == 0 );
    /* clear for second run */
    mbedtls_hmac_drbg_free( &ctx );
    TEST_ASSERT( memcmp( my_output, output, out_len ) == 0 );
    /* And now the normal entropy-based variant */
    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &p_entropy,
                                 custom, custom_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add1, add1_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add2, add2_len ) == 0 );
    TEST_ASSERT( memcmp( my_output, output, out_len ) == 0 );
exit:
    mbedtls_hmac_drbg_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void hmac_drbg_nopr( int md_alg,
                     char *entropy_hex, char *custom_hex,
                     char *add1_hex, char *add2_hex, char *add3_hex,
                     char *output_hex )
{
    unsigned char entropy[512];
    unsigned char custom[512];
    unsigned char add1[512];
    unsigned char add2[512];
    unsigned char add3[512];
    unsigned char output[512];
    unsigned char my_output[512];
    size_t custom_len, add1_len, add2_len, add3_len, out_len;
    entropy_ctx p_entropy;
    const mbedtls_md_info_t *md_info;
    mbedtls_hmac_drbg_context ctx;
    mbedtls_hmac_drbg_init( &ctx );
    memset( my_output, 0, sizeof my_output );
    custom_len = unhexify( custom, custom_hex );
    add1_len = unhexify( add1, add1_hex );
    add2_len = unhexify( add2, add2_hex );
    add3_len = unhexify( add3, add3_hex );
    out_len = unhexify( output, output_hex );
    p_entropy.len = unhexify( entropy, entropy_hex );
    p_entropy.p = entropy;
    md_info = mbedtls_md_info_from_type( md_alg );
    TEST_ASSERT( md_info != NULL );
    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &p_entropy,
                                 custom, custom_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_reseed( &ctx, add1, add1_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add2, add2_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add3, add3_len ) == 0 );
    TEST_ASSERT( memcmp( my_output, output, out_len ) == 0 );
exit:
    mbedtls_hmac_drbg_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE */
void hmac_drbg_pr( int md_alg,
                   char *entropy_hex, char *custom_hex,
                   char *add1_hex, char *add2_hex,
                   char *output_hex )
{
    unsigned char entropy[512];
    unsigned char custom[512];
    unsigned char add1[512];
    unsigned char add2[512];
    unsigned char output[512];
    unsigned char my_output[512];
    size_t custom_len, add1_len, add2_len, out_len;
    entropy_ctx p_entropy;
    const mbedtls_md_info_t *md_info;
    mbedtls_hmac_drbg_context ctx;
    mbedtls_hmac_drbg_init( &ctx );
    memset( my_output, 0, sizeof my_output );
    custom_len = unhexify( custom, custom_hex );
    add1_len = unhexify( add1, add1_hex );
    add2_len = unhexify( add2, add2_hex );
    out_len = unhexify( output, output_hex );
    p_entropy.len = unhexify( entropy, entropy_hex );
    p_entropy.p = entropy;
    md_info = mbedtls_md_info_from_type( md_alg );
    TEST_ASSERT( md_info != NULL );
    TEST_ASSERT( mbedtls_hmac_drbg_seed( &ctx, md_info, mbedtls_entropy_func, &p_entropy,
                                 custom, custom_len ) == 0 );
    mbedtls_hmac_drbg_set_prediction_resistance( &ctx, MBEDTLS_HMAC_DRBG_PR_ON );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add1, add1_len ) == 0 );
    TEST_ASSERT( mbedtls_hmac_drbg_random_with_add( &ctx, my_output, out_len,
                                            add2, add2_len ) == 0 );
    TEST_ASSERT( memcmp( my_output, output, out_len ) == 0 );
exit:
    mbedtls_hmac_drbg_free( &ctx );
}
/* END_CASE */
/* BEGIN_CASE depends_on:MBEDTLS_SELF_TEST */
void hmac_drbg_selftest( )
{
    TEST_ASSERT( mbedtls_hmac_drbg_self_test( 1 ) == 0 );
}
/* END_CASE */
            
    