Beispiel #1
0
void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, const mbedtls_ecp_point *X )
{
#ifndef TLS_DEBUG_HEAP_USE
    char str[DEBUG_BUF_SIZE];
#else
    char *str = tls_debug_zalloc(DEBUG_BUF_SIZE);
    if (str == NULL)
    	return;
#endif

    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
#ifndef TLS_DEBUG_HEAP_USE
    	return;
#else
	goto exit;
#endif

    mbedtls_snprintf( str, DEBUG_BUF_SIZE/*sizeof( str )*/, "%s(X)", text );
    mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X );

    mbedtls_snprintf( str, DEBUG_BUF_SIZE/*sizeof( str )*/, "%s(Y)", text );
    mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y );
#ifdef TLS_DEBUG_HEAP_USE
  exit:
  	tls_debug_free(str);
#endif
}
Beispiel #2
0
/*
 * Store the serial in printable form into buf; no more
 * than size characters will be written
 */
int mbedtls_x509_serial_gets( char *buf, size_t size, const mbedtls_x509_buf *serial )
{
    int ret;
    size_t i, n, nr;
    char *p;

    p = buf;
    n = size;

    nr = ( serial->len <= 32 )
        ? serial->len  : 28;

    for( i = 0; i < nr; i++ )
    {
        if( i == 0 && nr > 1 && serial->p[i] == 0x0 )
            continue;

        ret = mbedtls_snprintf( p, n, "%02X%s",
                serial->p[i], ( i < nr - 1 ) ? ":" : "" );
        MBEDTLS_X509_SAFE_SNPRINTF;
    }

    if( nr != serial->len )
    {
        ret = mbedtls_snprintf( p, n, "...." );
        MBEDTLS_X509_SAFE_SNPRINTF;
    }

    return( (int) ( size - n ) );
}
Beispiel #3
0
/*
 * Store the name in printable form into buf; no more
 * than size characters will be written
 */
int mbedtls_x509_dn_gets( char *buf, size_t size, const mbedtls_x509_name *dn )
{
    int ret;
    size_t i, n;
    unsigned char c, merge = 0;
    const mbedtls_x509_name *name;
    const char *short_name = NULL;
    char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;

    memset( s, 0, sizeof( s ) );

    name = dn;
    p = buf;
    n = size;

    while( name != NULL )
    {
        if( !name->oid.p )
        {
            name = name->next;
            continue;
        }

        if( name != dn )
        {
            ret = mbedtls_snprintf( p, n, merge ? " + " : ", " );
            MBEDTLS_X509_SAFE_SNPRINTF;
        }

        ret = mbedtls_oid_get_attr_short_name( &name->oid, &short_name );

        if( ret == 0 )
            ret = mbedtls_snprintf( p, n, "%s=", short_name );
        else
            ret = mbedtls_snprintf( p, n, "\?\?=" );
        MBEDTLS_X509_SAFE_SNPRINTF;

        for( i = 0; i < name->val.len; i++ )
        {
            if( i >= sizeof( s ) - 1 )
                break;

            c = name->val.p[i];
            if( c < 32 || c == 127 || ( c > 128 && c < 160 ) )
                 s[i] = '?';
            else s[i] = c;
        }
        s[i] = '\0';
        ret = mbedtls_snprintf( p, n, "%s", s );
        MBEDTLS_X509_SAFE_SNPRINTF;

        merge = name->next_merged;
        name = name->next;
    }

    return( (int) ( size - n ) );
}
Beispiel #4
0
void mbedtls_debug_print_mpi( const mbedtls_ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, const mbedtls_mpi *X )
{
    char str[DEBUG_BUF_SIZE];
    int j, k, zeros = 1;
    size_t i, n, idx = 0;

    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || X == NULL || level > debug_threshold )
        return;

    for( n = X->n - 1; n > 0; n-- )
        if( X->p[n] != 0 )
            break;

    for( j = ( sizeof(mbedtls_mpi_uint) << 3 ) - 1; j >= 0; j-- )
        if( ( ( X->p[n] >> j ) & 1 ) != 0 )
            break;

    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "value of '%s' (%d bits) is:\n",
              text, (int) ( ( n * ( sizeof(mbedtls_mpi_uint) << 3 ) ) + j + 1 ) );

    debug_send_line( ssl, level, file, line, str );

    idx = 0;
    for( i = n + 1, j = 0; i > 0; i-- )
    {
        if( zeros && X->p[i - 1] == 0 )
            continue;

        for( k = sizeof( mbedtls_mpi_uint ) - 1; k >= 0; k-- )
        {
            if( zeros && ( ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF ) == 0 )
                continue;
            else
                zeros = 0;

            if( j % 16 == 0 )
            {
                if( j > 0 )
                {
                    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "\n" );
                    debug_send_line( ssl, level, file, line, str );
                    idx = 0;
                }
            }

            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x", (unsigned int)
                             ( X->p[i - 1] >> ( k << 3 ) ) & 0xFF );

            j++;
        }

    }
Beispiel #5
0
void mbedtls_debug_print_ecp( const mbedtls_ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, const mbedtls_ecp_point *X )
{
    char str[DEBUG_BUF_SIZE];

    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
        return;

    mbedtls_snprintf( str, sizeof( str ), "%s(X)", text );
    mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->X );

    mbedtls_snprintf( str, sizeof( str ), "%s(Y)", text );
    mbedtls_debug_print_mpi( ssl, level, file, line, str, &X->Y );
}
Beispiel #6
0
/*
 * Helper for writing "RSA key size", "EC key size", etc
 */
int mbedtls_x509_key_size_helper( char *buf, size_t buf_size, const char *name )
{
    char *p = buf;
    size_t n = buf_size;
    int ret;

    ret = mbedtls_snprintf( p, n, "%s key size", name );
    MBEDTLS_X509_SAFE_SNPRINTF;

    return( 0 );
}
Beispiel #7
0
/*
 * Helper for writing signature algorithms
 */
int mbedtls_x509_sig_alg_gets( char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
                       mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
                       const void *sig_opts )
{
    int ret;
    char *p = buf;
    size_t n = size;
    const char *desc = NULL;

    ret = mbedtls_oid_get_sig_alg_desc( sig_oid, &desc );
    if( ret != 0 )
        ret = mbedtls_snprintf( p, n, "???"  );
    else
        ret = mbedtls_snprintf( p, n, "%s", desc );
    MBEDTLS_X509_SAFE_SNPRINTF;

#if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
    if( pk_alg == MBEDTLS_PK_RSASSA_PSS )
    {
        const mbedtls_pk_rsassa_pss_options *pss_opts;
        const mbedtls_md_info_t *md_info, *mgf_md_info;

        pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;

        md_info = mbedtls_md_info_from_type( md_alg );
        mgf_md_info = mbedtls_md_info_from_type( pss_opts->mgf1_hash_id );

        ret = mbedtls_snprintf( p, n, " (%s, MGF1-%s, 0x%02X)",
                              md_info ? mbedtls_md_get_name( md_info ) : "???",
                              mgf_md_info ? mbedtls_md_get_name( mgf_md_info ) : "???",
                              pss_opts->expected_salt_len );
        MBEDTLS_X509_SAFE_SNPRINTF;
    }
#else
    ((void) pk_alg);
    ((void) md_alg);
    ((void) sig_opts);
#endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */

    return( (int)( size - n ) );
}
Beispiel #8
0
/* Return the x.y.z.... style numeric string for the given OID */
int mbedtls_oid_get_numeric_string( char *buf, size_t size,
                            const mbedtls_asn1_buf *oid )
{
    int ret;
    size_t i, n;
    unsigned int value;
    char *p;

    p = buf;
    n = size;

    /* First byte contains first two dots */
    if( oid->len > 0 )
    {
        ret = mbedtls_snprintf( p, n, "%d.%d", oid->p[0] / 40, oid->p[0] % 40 );
        OID_SAFE_SNPRINTF;
    }

    value = 0;
    for( i = 1; i < oid->len; i++ )
    {
        /* Prevent overflow in value. */
        if( ( ( value << 7 ) >> 7 ) != value )
            return( MBEDTLS_ERR_OID_BUF_TOO_SMALL );

        value <<= 7;
        value += oid->p[i] & 0x7F;

        if( !( oid->p[i] & 0x80 ) )
        {
            /* Last byte */
            ret = mbedtls_snprintf( p, n, ".%d", value );
            OID_SAFE_SNPRINTF;
            value = 0;
        }
    }

    return( (int) ( size - n ) );
}
Beispiel #9
0
/*
 * Return an informational string about the CSR.
 */
int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
                   const mbedtls_x509_csr *csr )
{
    int ret;
    size_t n;
    char *p;
    char key_size_str[BEFORE_COLON];

    p = buf;
    n = size;

    ret = mbedtls_snprintf( p, n, "%sCSR version   : %d",
                               prefix, csr->version );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_snprintf( p, n, "\n%ssubject name  : ", prefix );
    MBEDTLS_X509_SAFE_SNPRINTF;
    ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
                             csr->sig_opts );
    MBEDTLS_X509_SAFE_SNPRINTF;

    if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
                                      mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
    {
        return( ret );
    }

    ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
                          (int) mbedtls_pk_get_bitlen( &csr->pk ) );
    MBEDTLS_X509_SAFE_SNPRINTF;

    return( (int) ( size - n ) );
}
Beispiel #10
0
static int test_snprintf(size_t n, const char ref_buf[10], int ref_ret)
{
	int ret;
	char buf[10] = "xxxxxxxxx";
	const char ref[10] = "xxxxxxxxx";

	ret = mbedtls_snprintf(buf, n, "%s", "123");
	if (ret < 0 || (size_t) ret >= n)
		ret = -1;

	if (strncmp(ref_buf, buf, sizeof(buf)) != 0 ||
	    ref_ret != ret || memcmp(buf + n, ref + n, sizeof(buf) - n) != 0) {
		return 1;
	}

	return 0;
}
Beispiel #11
0
/*
 * All calls to f_dbg must be made via this function
 */
static inline void debug_send_line( const mbedtls_ssl_context *ssl, int level,
                                    const char *file, int line,
                                    const char *str )
{
    /*
     * If in a threaded environment, we need a thread identifier.
     * Since there is no portable way to get one, use the address of the ssl
     * context instead, as it shouldn't be shared between threads.
     */
#if defined(MBEDTLS_THREADING_C)
    char idstr[20 + DEBUG_BUF_SIZE]; /* 0x + 16 nibbles + ': ' */
    mbedtls_snprintf( idstr, sizeof( idstr ), "%p: %s", ssl, str );
    ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, idstr );
#else
    ssl->conf->f_dbg( ssl->conf->p_dbg, level, file, line, str );
#endif
}
Beispiel #12
0
void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
                      const char *file, int line, const char *text,
                      const unsigned char *buf, size_t len )
{
    char str[DEBUG_BUF_SIZE];
    char txt[17];
    size_t i, idx = 0;

    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
        return;

    mbedtls_snprintf( str + idx, sizeof( str ) - idx, "dumping '%s' (%u bytes)\n",
              text, (unsigned int) len );

    debug_send_line( ssl, level, file, line, str );

    idx = 0;
    memset( txt, 0, sizeof( txt ) );
    for( i = 0; i < len; i++ )
    {
        if( i >= 4096 )
            break;

        if( i % 16 == 0 )
        {
            if( i > 0 )
            {
                mbedtls_snprintf( str + idx, sizeof( str ) - idx, "  %s\n", txt );
                debug_send_line( ssl, level, file, line, str );

                idx = 0;
                memset( txt, 0, sizeof( txt ) );
            }

            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "%04x: ",
                             (unsigned int) i );

        }

        idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, " %02x",
                         (unsigned int) buf[i] );
        txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ;
    }

    if( len > 0 )
    {
        for( /* i = i */; i % 16 != 0; i++ )
            idx += mbedtls_snprintf( str + idx, sizeof( str ) - idx, "   " );

        mbedtls_snprintf( str + idx, sizeof( str ) - idx, "  %s\n", txt );
        debug_send_line( ssl, level, file, line, str );
    }
}
Beispiel #13
0
void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, int ret )
{
#ifndef TLS_DEBUG_HEAP_USE
    char str[DEBUG_BUF_SIZE];
#else
    char *str = tls_debug_zalloc(DEBUG_BUF_SIZE);
    if (str == NULL)
    	return;
#endif

    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
#ifndef TLS_DEBUG_HEAP_USE
    	return;
#else
	goto exit;
#endif

    /*
     * With non-blocking I/O and examples that just retry immediately,
     * the logs would be quickly flooded with WANT_READ, so ignore that.
     * Don't ignore WANT_WRITE however, since is is usually rare.
     */
    if( ret == MBEDTLS_ERR_SSL_WANT_READ )
#ifndef TLS_DEBUG_HEAP_USE
    	return;
#else
	goto exit;
#endif

    mbedtls_snprintf( str, DEBUG_BUF_SIZE/*sizeof( str )*/, "%s() returned %d (-0x%04x)\n",
              text, ret, -ret );

    debug_send_line( ssl, level, file, line, str );
#ifdef TLS_DEBUG_HEAP_USE
  exit:
  	tls_debug_free(str);
#endif
}
Beispiel #14
0
void mbedtls_debug_print_ret( const mbedtls_ssl_context *ssl, int level,
                      const char *file, int line,
                      const char *text, int ret )
{
    char str[DEBUG_BUF_SIZE];

    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
        return;

    /*
     * With non-blocking I/O and examples that just retry immediately,
     * the logs would be quickly flooded with WANT_READ, so ignore that.
     * Don't ignore WANT_WRITE however, since is is usually rare.
     */
    if( ret == MBEDTLS_ERR_SSL_WANT_READ )
        return;

    mbedtls_snprintf( str, sizeof( str ), "%s() returned %d (-0x%04x)\n",
              text, ret, -ret );

    debug_send_line( ssl, level, file, line, str );
}
Beispiel #15
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    mbedtls_pk_context pk;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    unsigned char hash[32];
    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
    char filename[512];
    const char *pers = "rsa_sign_pss";
    size_t olen = 0;

    mbedtls_entropy_init( &entropy );
    mbedtls_pk_init( &pk );
    mbedtls_ctr_drbg_init( &ctr_drbg );

    if( argc != 3 )
    {
        mbedtls_printf( "usage: rsa_sign_pss <key_file> <filename>\n" );

#if defined(_WIN32)
        mbedtls_printf( "\n" );
#endif

        goto exit;
    }

    mbedtls_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned %d\n", ret );
        goto exit;
    }

    mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
    fflush( stdout );

    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
    {
        ret = 1;
        mbedtls_printf( " failed\n  ! Could not read key from '%s'\n", argv[1] );
        mbedtls_printf( "  ! mbedtls_pk_parse_public_keyfile returned %d\n\n", ret );
        goto exit;
    }

    if( !mbedtls_pk_can_do( &pk, MBEDTLS_PK_RSA ) )
    {
        ret = 1;
        mbedtls_printf( " failed\n  ! Key is not an RSA key\n" );
        goto exit;
    }

    mbedtls_rsa_set_padding( mbedtls_pk_rsa( pk ), MBEDTLS_RSA_PKCS_V21, MBEDTLS_MD_SHA256 );

    /*
     * Compute the SHA-256 hash of the input file,
     * then calculate the RSA signature of the hash.
     */
    mbedtls_printf( "\n  . Generating the RSA/SHA-256 signature" );
    fflush( stdout );

    if( ( ret = mbedtls_md_file(
                    mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
                    argv[2], hash ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
        goto exit;
    }

    if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0, buf, &olen,
                         mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_pk_sign returned %d\n\n", ret );
        goto exit;
    }

    /*
     * Write the signature into <filename>.sig
     */
    mbedtls_snprintf( filename, 512, "%s.sig", argv[2] );

    if( ( f = fopen( filename, "wb+" ) ) == NULL )
    {
        ret = 1;
        mbedtls_printf( " failed\n  ! Could not create %s\n\n", filename );
        goto exit;
    }

    if( fwrite( buf, 1, olen, f ) != olen )
    {
        mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
        goto exit;
    }

    fclose( f );

    mbedtls_printf( "\n  . Done (created \"%s\")\n\n", filename );

exit:
    mbedtls_pk_free( &pk );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Beispiel #16
0
void mbedtls_strerror( int ret, char *buf, size_t buflen )
{
    size_t len;
    int use_ret;

    if( buflen == 0 )
        return;

    memset( buf, 0x00, buflen );

    if( ret < 0 )
        ret = -ret;

    if( ret & 0xFF80 )
    {
        use_ret = ret & 0xFF80;

        // High level error codes
        //
        // BEGIN generated code
#if defined(MBEDTLS_CIPHER_C)
        if( use_ret == -(MBEDTLS_ERR_CIPHER_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "CIPHER - The selected feature is not available" );
        if( use_ret == -(MBEDTLS_ERR_CIPHER_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "CIPHER - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_CIPHER_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "CIPHER - Failed to allocate memory" );
        if( use_ret == -(MBEDTLS_ERR_CIPHER_INVALID_PADDING) )
            mbedtls_snprintf( buf, buflen, "CIPHER - Input data contains invalid padding and is rejected" );
        if( use_ret == -(MBEDTLS_ERR_CIPHER_FULL_BLOCK_EXPECTED) )
            mbedtls_snprintf( buf, buflen, "CIPHER - Decryption of block requires a full block" );
        if( use_ret == -(MBEDTLS_ERR_CIPHER_AUTH_FAILED) )
            mbedtls_snprintf( buf, buflen, "CIPHER - Authentication failed (for AEAD modes)" );
#endif /* MBEDTLS_CIPHER_C */

#if defined(MBEDTLS_DHM_C)
        if( use_ret == -(MBEDTLS_ERR_DHM_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "DHM - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_DHM_READ_PARAMS_FAILED) )
            mbedtls_snprintf( buf, buflen, "DHM - Reading of the DHM parameters failed" );
        if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PARAMS_FAILED) )
            mbedtls_snprintf( buf, buflen, "DHM - Making of the DHM parameters failed" );
        if( use_ret == -(MBEDTLS_ERR_DHM_READ_PUBLIC_FAILED) )
            mbedtls_snprintf( buf, buflen, "DHM - Reading of the public values failed" );
        if( use_ret == -(MBEDTLS_ERR_DHM_MAKE_PUBLIC_FAILED) )
            mbedtls_snprintf( buf, buflen, "DHM - Making of the public value failed" );
        if( use_ret == -(MBEDTLS_ERR_DHM_CALC_SECRET_FAILED) )
            mbedtls_snprintf( buf, buflen, "DHM - Calculation of the DHM secret failed" );
        if( use_ret == -(MBEDTLS_ERR_DHM_INVALID_FORMAT) )
            mbedtls_snprintf( buf, buflen, "DHM - The ASN.1 data is not formatted correctly" );
        if( use_ret == -(MBEDTLS_ERR_DHM_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "DHM - Allocation of memory failed" );
        if( use_ret == -(MBEDTLS_ERR_DHM_FILE_IO_ERROR) )
            mbedtls_snprintf( buf, buflen, "DHM - Read/write of file failed" );
#endif /* MBEDTLS_DHM_C */

#if defined(MBEDTLS_ECP_C)
        if( use_ret == -(MBEDTLS_ERR_ECP_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "ECP - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_ECP_BUFFER_TOO_SMALL) )
            mbedtls_snprintf( buf, buflen, "ECP - The buffer is too small to write to" );
        if( use_ret == -(MBEDTLS_ERR_ECP_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "ECP - Requested curve not available" );
        if( use_ret == -(MBEDTLS_ERR_ECP_VERIFY_FAILED) )
            mbedtls_snprintf( buf, buflen, "ECP - The signature is not valid" );
        if( use_ret == -(MBEDTLS_ERR_ECP_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "ECP - Memory allocation failed" );
        if( use_ret == -(MBEDTLS_ERR_ECP_RANDOM_FAILED) )
            mbedtls_snprintf( buf, buflen, "ECP - Generation of random value, such as (ephemeral) key, failed" );
        if( use_ret == -(MBEDTLS_ERR_ECP_INVALID_KEY) )
            mbedtls_snprintf( buf, buflen, "ECP - Invalid private or public key" );
        if( use_ret == -(MBEDTLS_ERR_ECP_SIG_LEN_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "ECP - Signature is valid but shorter than the user-supplied length" );
#endif /* MBEDTLS_ECP_C */

#if defined(MBEDTLS_MD_C)
        if( use_ret == -(MBEDTLS_ERR_MD_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "MD - The selected feature is not available" );
        if( use_ret == -(MBEDTLS_ERR_MD_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "MD - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_MD_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "MD - Failed to allocate memory" );
        if( use_ret == -(MBEDTLS_ERR_MD_FILE_IO_ERROR) )
            mbedtls_snprintf( buf, buflen, "MD - Opening or reading of file failed" );
#endif /* MBEDTLS_MD_C */

#if defined(MBEDTLS_PEM_PARSE_C) || defined(MBEDTLS_PEM_WRITE_C)
        if( use_ret == -(MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT) )
            mbedtls_snprintf( buf, buflen, "PEM - No PEM header or footer found" );
        if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_DATA) )
            mbedtls_snprintf( buf, buflen, "PEM - PEM string is not as expected" );
        if( use_ret == -(MBEDTLS_ERR_PEM_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "PEM - Failed to allocate memory" );
        if( use_ret == -(MBEDTLS_ERR_PEM_INVALID_ENC_IV) )
            mbedtls_snprintf( buf, buflen, "PEM - RSA IV is not in hex-format" );
        if( use_ret == -(MBEDTLS_ERR_PEM_UNKNOWN_ENC_ALG) )
            mbedtls_snprintf( buf, buflen, "PEM - Unsupported key encryption algorithm" );
        if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_REQUIRED) )
            mbedtls_snprintf( buf, buflen, "PEM - Private key password can't be empty" );
        if( use_ret == -(MBEDTLS_ERR_PEM_PASSWORD_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "PEM - Given private key password does not allow for correct decryption" );
        if( use_ret == -(MBEDTLS_ERR_PEM_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "PEM - Unavailable feature, e.g. hashing/encryption combination" );
        if( use_ret == -(MBEDTLS_ERR_PEM_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "PEM - Bad input parameters to function" );
#endif /* MBEDTLS_PEM_PARSE_C || MBEDTLS_PEM_WRITE_C */

#if defined(MBEDTLS_PK_C)
        if( use_ret == -(MBEDTLS_ERR_PK_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "PK - Memory allocation failed" );
        if( use_ret == -(MBEDTLS_ERR_PK_TYPE_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "PK - Type mismatch, eg attempt to encrypt with an ECDSA key" );
        if( use_ret == -(MBEDTLS_ERR_PK_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "PK - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_PK_FILE_IO_ERROR) )
            mbedtls_snprintf( buf, buflen, "PK - Read/write of file failed" );
        if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_VERSION) )
            mbedtls_snprintf( buf, buflen, "PK - Unsupported key version" );
        if( use_ret == -(MBEDTLS_ERR_PK_KEY_INVALID_FORMAT) )
            mbedtls_snprintf( buf, buflen, "PK - Invalid key tag or value" );
        if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_PK_ALG) )
            mbedtls_snprintf( buf, buflen, "PK - Key algorithm is unsupported (only RSA and EC are supported)" );
        if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_REQUIRED) )
            mbedtls_snprintf( buf, buflen, "PK - Private key password can't be empty" );
        if( use_ret == -(MBEDTLS_ERR_PK_PASSWORD_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "PK - Given private key password does not allow for correct decryption" );
        if( use_ret == -(MBEDTLS_ERR_PK_INVALID_PUBKEY) )
            mbedtls_snprintf( buf, buflen, "PK - The pubkey tag or value is invalid (only RSA and EC are supported)" );
        if( use_ret == -(MBEDTLS_ERR_PK_INVALID_ALG) )
            mbedtls_snprintf( buf, buflen, "PK - The algorithm tag or value is invalid" );
        if( use_ret == -(MBEDTLS_ERR_PK_UNKNOWN_NAMED_CURVE) )
            mbedtls_snprintf( buf, buflen, "PK - Elliptic curve is unsupported (only NIST curves are supported)" );
        if( use_ret == -(MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "PK - Unavailable feature, e.g. RSA disabled for RSA key" );
        if( use_ret == -(MBEDTLS_ERR_PK_SIG_LEN_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "PK - The signature is valid but its length is less than expected" );
#endif /* MBEDTLS_PK_C */

#if defined(MBEDTLS_PKCS12_C)
        if( use_ret == -(MBEDTLS_ERR_PKCS12_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "PKCS12 - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_PKCS12_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "PKCS12 - Feature not available, e.g. unsupported encryption scheme" );
        if( use_ret == -(MBEDTLS_ERR_PKCS12_PBE_INVALID_FORMAT) )
            mbedtls_snprintf( buf, buflen, "PKCS12 - PBE ASN.1 data not as expected" );
        if( use_ret == -(MBEDTLS_ERR_PKCS12_PASSWORD_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "PKCS12 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS12_C */

#if defined(MBEDTLS_PKCS5_C)
        if( use_ret == -(MBEDTLS_ERR_PKCS5_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "PKCS5 - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_PKCS5_INVALID_FORMAT) )
            mbedtls_snprintf( buf, buflen, "PKCS5 - Unexpected ASN.1 data" );
        if( use_ret == -(MBEDTLS_ERR_PKCS5_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "PKCS5 - Requested encryption or digest alg not available" );
        if( use_ret == -(MBEDTLS_ERR_PKCS5_PASSWORD_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "PKCS5 - Given private key password does not allow for correct decryption" );
#endif /* MBEDTLS_PKCS5_C */

#if defined(MBEDTLS_RSA_C)
        if( use_ret == -(MBEDTLS_ERR_RSA_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "RSA - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_RSA_INVALID_PADDING) )
            mbedtls_snprintf( buf, buflen, "RSA - Input data contains invalid padding and is rejected" );
        if( use_ret == -(MBEDTLS_ERR_RSA_KEY_GEN_FAILED) )
            mbedtls_snprintf( buf, buflen, "RSA - Something failed during generation of a key" );
        if( use_ret == -(MBEDTLS_ERR_RSA_KEY_CHECK_FAILED) )
            mbedtls_snprintf( buf, buflen, "RSA - Key failed to pass the library's validity check" );
        if( use_ret == -(MBEDTLS_ERR_RSA_PUBLIC_FAILED) )
            mbedtls_snprintf( buf, buflen, "RSA - The public key operation failed" );
        if( use_ret == -(MBEDTLS_ERR_RSA_PRIVATE_FAILED) )
            mbedtls_snprintf( buf, buflen, "RSA - The private key operation failed" );
        if( use_ret == -(MBEDTLS_ERR_RSA_VERIFY_FAILED) )
            mbedtls_snprintf( buf, buflen, "RSA - The PKCS#1 verification failed" );
        if( use_ret == -(MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE) )
            mbedtls_snprintf( buf, buflen, "RSA - The output buffer for decryption is not large enough" );
        if( use_ret == -(MBEDTLS_ERR_RSA_RNG_FAILED) )
            mbedtls_snprintf( buf, buflen, "RSA - The random generator failed to generate non-zeros" );
#endif /* MBEDTLS_RSA_C */

#if defined(MBEDTLS_SSL_TLS_C)
        if( use_ret == -(MBEDTLS_ERR_SSL_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "SSL - The requested feature is not available" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "SSL - Bad input parameters to function" );
        if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_MAC) )
            mbedtls_snprintf( buf, buflen, "SSL - Verification of the message MAC failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_INVALID_RECORD) )
            mbedtls_snprintf( buf, buflen, "SSL - An invalid SSL record was received" );
        if( use_ret == -(MBEDTLS_ERR_SSL_CONN_EOF) )
            mbedtls_snprintf( buf, buflen, "SSL - The connection indicated an EOF" );
        if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_CIPHER) )
            mbedtls_snprintf( buf, buflen, "SSL - An unknown cipher was received" );
        if( use_ret == -(MBEDTLS_ERR_SSL_NO_CIPHER_CHOSEN) )
            mbedtls_snprintf( buf, buflen, "SSL - The server has no ciphersuites in common with the client" );
        if( use_ret == -(MBEDTLS_ERR_SSL_NO_RNG) )
            mbedtls_snprintf( buf, buflen, "SSL - No RNG was provided to the SSL module" );
        if( use_ret == -(MBEDTLS_ERR_SSL_NO_CLIENT_CERTIFICATE) )
            mbedtls_snprintf( buf, buflen, "SSL - No client certification received from the client, but required by the authentication mode" );
        if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_TOO_LARGE) )
            mbedtls_snprintf( buf, buflen, "SSL - Our own certificate(s) is/are too large to send in an SSL message" );
        if( use_ret == -(MBEDTLS_ERR_SSL_CERTIFICATE_REQUIRED) )
            mbedtls_snprintf( buf, buflen, "SSL - The own certificate is not set, but needed by the server" );
        if( use_ret == -(MBEDTLS_ERR_SSL_PRIVATE_KEY_REQUIRED) )
            mbedtls_snprintf( buf, buflen, "SSL - The own private key or pre-shared key is not set, but needed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_CA_CHAIN_REQUIRED) )
            mbedtls_snprintf( buf, buflen, "SSL - No CA Chain is set, but required to operate" );
        if( use_ret == -(MBEDTLS_ERR_SSL_UNEXPECTED_MESSAGE) )
            mbedtls_snprintf( buf, buflen, "SSL - An unexpected message was received from our peer" );
        if( use_ret == -(MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE) )
        {
            mbedtls_snprintf( buf, buflen, "SSL - A fatal alert message was received from our peer" );
            return;
        }
        if( use_ret == -(MBEDTLS_ERR_SSL_PEER_VERIFY_FAILED) )
            mbedtls_snprintf( buf, buflen, "SSL - Verification of our peer failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) )
            mbedtls_snprintf( buf, buflen, "SSL - The peer notified us that the connection is going to be closed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientHello handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHello handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the Certificate handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_REQUEST) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateRequest handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_KEY_EXCHANGE) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerKeyExchange handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO_DONE) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ServerHelloDone handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_RP) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Read Public" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CLIENT_KEY_EXCHANGE_CS) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ClientKeyExchange handshake message failed in DHM / ECDH Calculate Secret" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CERTIFICATE_VERIFY) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the CertificateVerify handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_CHANGE_CIPHER_SPEC) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the ChangeCipherSpec handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_FINISHED) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the Finished handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "SSL - Memory allocation failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FAILED) )
            mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function returned with error" );
        if( use_ret == -(MBEDTLS_ERR_SSL_HW_ACCEL_FALLTHROUGH) )
            mbedtls_snprintf( buf, buflen, "SSL - Hardware acceleration function skipped / left alone data" );
        if( use_ret == -(MBEDTLS_ERR_SSL_COMPRESSION_FAILED) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the compression / decompression failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_PROTOCOL_VERSION) )
            mbedtls_snprintf( buf, buflen, "SSL - Handshake protocol not within min/max boundaries" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BAD_HS_NEW_SESSION_TICKET) )
            mbedtls_snprintf( buf, buflen, "SSL - Processing of the NewSessionTicket handshake message failed" );
        if( use_ret == -(MBEDTLS_ERR_SSL_SESSION_TICKET_EXPIRED) )
            mbedtls_snprintf( buf, buflen, "SSL - Session ticket has expired" );
        if( use_ret == -(MBEDTLS_ERR_SSL_PK_TYPE_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "SSL - Public key type mismatch (eg, asked for RSA key exchange and presented EC key)" );
        if( use_ret == -(MBEDTLS_ERR_SSL_UNKNOWN_IDENTITY) )
            mbedtls_snprintf( buf, buflen, "SSL - Unknown identity received (eg, PSK identity)" );
        if( use_ret == -(MBEDTLS_ERR_SSL_INTERNAL_ERROR) )
            mbedtls_snprintf( buf, buflen, "SSL - Internal error (eg, unexpected failure in lower-level module)" );
        if( use_ret == -(MBEDTLS_ERR_SSL_COUNTER_WRAPPING) )
            mbedtls_snprintf( buf, buflen, "SSL - A counter would wrap (eg, too many messages exchanged)" );
        if( use_ret == -(MBEDTLS_ERR_SSL_WAITING_SERVER_HELLO_RENEGO) )
            mbedtls_snprintf( buf, buflen, "SSL - Unexpected message at ServerHello in renegotiation" );
        if( use_ret == -(MBEDTLS_ERR_SSL_HELLO_VERIFY_REQUIRED) )
            mbedtls_snprintf( buf, buflen, "SSL - DTLS client must retry for hello verification" );
        if( use_ret == -(MBEDTLS_ERR_SSL_BUFFER_TOO_SMALL) )
            mbedtls_snprintf( buf, buflen, "SSL - A buffer is too small to receive or write a message" );
        if( use_ret == -(MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE) )
            mbedtls_snprintf( buf, buflen, "SSL - None of the common ciphersuites is usable (eg, no suitable certificate, see debug messages)" );
        if( use_ret == -(MBEDTLS_ERR_SSL_WANT_READ) )
            mbedtls_snprintf( buf, buflen, "SSL - Connection requires a read call" );
        if( use_ret == -(MBEDTLS_ERR_SSL_WANT_WRITE) )
            mbedtls_snprintf( buf, buflen, "SSL - Connection requires a write call" );
        if( use_ret == -(MBEDTLS_ERR_SSL_TIMEOUT) )
            mbedtls_snprintf( buf, buflen, "SSL - The operation timed out" );
        if( use_ret == -(MBEDTLS_ERR_SSL_CLIENT_RECONNECT) )
            mbedtls_snprintf( buf, buflen, "SSL - The client initiated a reconnect from the same port" );
#endif /* MBEDTLS_SSL_TLS_C */

#if defined(MBEDTLS_X509_USE_C) || defined(MBEDTLS_X509_CREATE_C)
        if( use_ret == -(MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE) )
            mbedtls_snprintf( buf, buflen, "X509 - Unavailable feature, e.g. RSA hashing/encryption combination" );
        if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_OID) )
            mbedtls_snprintf( buf, buflen, "X509 - Requested OID is unknown" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_FORMAT) )
            mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR format is invalid, e.g. different type expected" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_VERSION) )
            mbedtls_snprintf( buf, buflen, "X509 - The CRT/CRL/CSR version element is invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SERIAL) )
            mbedtls_snprintf( buf, buflen, "X509 - The serial tag or value is invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_ALG) )
            mbedtls_snprintf( buf, buflen, "X509 - The algorithm tag or value is invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_NAME) )
            mbedtls_snprintf( buf, buflen, "X509 - The name tag or value is invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_DATE) )
            mbedtls_snprintf( buf, buflen, "X509 - The date tag or value is invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_SIGNATURE) )
            mbedtls_snprintf( buf, buflen, "X509 - The signature tag or value invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_INVALID_EXTENSIONS) )
            mbedtls_snprintf( buf, buflen, "X509 - The extension tag or value is invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_VERSION) )
            mbedtls_snprintf( buf, buflen, "X509 - CRT/CRL/CSR has an unsupported version number" );
        if( use_ret == -(MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG) )
            mbedtls_snprintf( buf, buflen, "X509 - Signature algorithm (oid) is unsupported" );
        if( use_ret == -(MBEDTLS_ERR_X509_SIG_MISMATCH) )
            mbedtls_snprintf( buf, buflen, "X509 - Signature algorithms do not match. (see \\c ::mbedtls_x509_crt sig_oid)" );
        if( use_ret == -(MBEDTLS_ERR_X509_CERT_VERIFY_FAILED) )
            mbedtls_snprintf( buf, buflen, "X509 - Certificate verification failed, e.g. CRL, CA or signature check failed" );
        if( use_ret == -(MBEDTLS_ERR_X509_CERT_UNKNOWN_FORMAT) )
            mbedtls_snprintf( buf, buflen, "X509 - Format not recognized as DER or PEM" );
        if( use_ret == -(MBEDTLS_ERR_X509_BAD_INPUT_DATA) )
            mbedtls_snprintf( buf, buflen, "X509 - Input invalid" );
        if( use_ret == -(MBEDTLS_ERR_X509_ALLOC_FAILED) )
            mbedtls_snprintf( buf, buflen, "X509 - Allocation of memory failed" );
        if( use_ret == -(MBEDTLS_ERR_X509_FILE_IO_ERROR) )
            mbedtls_snprintf( buf, buflen, "X509 - Read/write of file failed" );
        if( use_ret == -(MBEDTLS_ERR_X509_BUFFER_TOO_SMALL) )
            mbedtls_snprintf( buf, buflen, "X509 - Destination buffer is too small" );
#endif /* MBEDTLS_X509_USE_C || MBEDTLS_X509_CREATE_C */
        // END generated code

        if( strlen( buf ) == 0 )
            mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
    }

    use_ret = ret & ~0xFF80;

    if( use_ret == 0 )
        return;

    // If high level code is present, make a concatenation between both
    // error strings.
    //
    len = strlen( buf );

    if( len > 0 )
    {
        if( buflen - len < 5 )
            return;

        mbedtls_snprintf( buf + len, buflen - len, " : " );

        buf += len + 3;
        buflen -= len + 3;
    }

    // Low level error codes
    //
    // BEGIN generated code
#if defined(MBEDTLS_AES_C)
    if( use_ret == -(MBEDTLS_ERR_AES_INVALID_KEY_LENGTH) )
        mbedtls_snprintf( buf, buflen, "AES - Invalid key length" );
    if( use_ret == -(MBEDTLS_ERR_AES_INVALID_INPUT_LENGTH) )
        mbedtls_snprintf( buf, buflen, "AES - Invalid data input length" );
#endif /* MBEDTLS_AES_C */

#if defined(MBEDTLS_ASN1_PARSE_C)
    if( use_ret == -(MBEDTLS_ERR_ASN1_OUT_OF_DATA) )
        mbedtls_snprintf( buf, buflen, "ASN1 - Out of data when parsing an ASN1 data structure" );
    if( use_ret == -(MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) )
        mbedtls_snprintf( buf, buflen, "ASN1 - ASN1 tag was of an unexpected value" );
    if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_LENGTH) )
        mbedtls_snprintf( buf, buflen, "ASN1 - Error when trying to determine the length or invalid length" );
    if( use_ret == -(MBEDTLS_ERR_ASN1_LENGTH_MISMATCH) )
        mbedtls_snprintf( buf, buflen, "ASN1 - Actual length differs from expected length" );
    if( use_ret == -(MBEDTLS_ERR_ASN1_INVALID_DATA) )
        mbedtls_snprintf( buf, buflen, "ASN1 - Data is invalid. (not used)" );
    if( use_ret == -(MBEDTLS_ERR_ASN1_ALLOC_FAILED) )
        mbedtls_snprintf( buf, buflen, "ASN1 - Memory allocation failed" );
    if( use_ret == -(MBEDTLS_ERR_ASN1_BUF_TOO_SMALL) )
        mbedtls_snprintf( buf, buflen, "ASN1 - Buffer too small when writing ASN.1 data structure" );
#endif /* MBEDTLS_ASN1_PARSE_C */

#if defined(MBEDTLS_BASE64_C)
    if( use_ret == -(MBEDTLS_ERR_BASE64_BUFFER_TOO_SMALL) )
        mbedtls_snprintf( buf, buflen, "BASE64 - Output buffer too small" );
    if( use_ret == -(MBEDTLS_ERR_BASE64_INVALID_CHARACTER) )
        mbedtls_snprintf( buf, buflen, "BASE64 - Invalid character in input" );
#endif /* MBEDTLS_BASE64_C */

#if defined(MBEDTLS_BIGNUM_C)
    if( use_ret == -(MBEDTLS_ERR_MPI_FILE_IO_ERROR) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - An error occurred while reading from or writing to a file" );
    if( use_ret == -(MBEDTLS_ERR_MPI_BAD_INPUT_DATA) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - Bad input parameters to function" );
    if( use_ret == -(MBEDTLS_ERR_MPI_INVALID_CHARACTER) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - There is an invalid character in the digit string" );
    if( use_ret == -(MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - The buffer is too small to write to" );
    if( use_ret == -(MBEDTLS_ERR_MPI_NEGATIVE_VALUE) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are negative or result in illegal output" );
    if( use_ret == -(MBEDTLS_ERR_MPI_DIVISION_BY_ZERO) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - The input argument for division is zero, which is not allowed" );
    if( use_ret == -(MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - The input arguments are not acceptable" );
    if( use_ret == -(MBEDTLS_ERR_MPI_ALLOC_FAILED) )
        mbedtls_snprintf( buf, buflen, "BIGNUM - Memory allocation failed" );
#endif /* MBEDTLS_BIGNUM_C */

#if defined(MBEDTLS_BLOWFISH_C)
    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_KEY_LENGTH) )
        mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid key length" );
    if( use_ret == -(MBEDTLS_ERR_BLOWFISH_INVALID_INPUT_LENGTH) )
        mbedtls_snprintf( buf, buflen, "BLOWFISH - Invalid data input length" );
#endif /* MBEDTLS_BLOWFISH_C */

#if defined(MBEDTLS_CAMELLIA_C)
    if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_KEY_LENGTH) )
        mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid key length" );
    if( use_ret == -(MBEDTLS_ERR_CAMELLIA_INVALID_INPUT_LENGTH) )
        mbedtls_snprintf( buf, buflen, "CAMELLIA - Invalid data input length" );
#endif /* MBEDTLS_CAMELLIA_C */

#if defined(MBEDTLS_CCM_C)
    if( use_ret == -(MBEDTLS_ERR_CCM_BAD_INPUT) )
        mbedtls_snprintf( buf, buflen, "CCM - Bad input parameters to function" );
    if( use_ret == -(MBEDTLS_ERR_CCM_AUTH_FAILED) )
        mbedtls_snprintf( buf, buflen, "CCM - Authenticated decryption failed" );
#endif /* MBEDTLS_CCM_C */

#if defined(MBEDTLS_CTR_DRBG_C)
    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_ENTROPY_SOURCE_FAILED) )
        mbedtls_snprintf( buf, buflen, "CTR_DRBG - The entropy source failed" );
    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_REQUEST_TOO_BIG) )
        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Too many random requested in single call" );
    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG) )
        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Input too large (Entropy + additional)" );
    if( use_ret == -(MBEDTLS_ERR_CTR_DRBG_FILE_IO_ERROR) )
        mbedtls_snprintf( buf, buflen, "CTR_DRBG - Read/write error in file" );
#endif /* MBEDTLS_CTR_DRBG_C */

#if defined(MBEDTLS_DES_C)
    if( use_ret == -(MBEDTLS_ERR_DES_INVALID_INPUT_LENGTH) )
        mbedtls_snprintf( buf, buflen, "DES - The data input has an invalid length" );
#endif /* MBEDTLS_DES_C */

#if defined(MBEDTLS_ENTROPY_C)
    if( use_ret == -(MBEDTLS_ERR_ENTROPY_SOURCE_FAILED) )
        mbedtls_snprintf( buf, buflen, "ENTROPY - Critical entropy source failure" );
    if( use_ret == -(MBEDTLS_ERR_ENTROPY_MAX_SOURCES) )
        mbedtls_snprintf( buf, buflen, "ENTROPY - No more sources can be added" );
    if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_SOURCES_DEFINED) )
        mbedtls_snprintf( buf, buflen, "ENTROPY - No sources have been added to poll" );
    if( use_ret == -(MBEDTLS_ERR_ENTROPY_NO_STRONG_SOURCE) )
        mbedtls_snprintf( buf, buflen, "ENTROPY - No strong sources have been added to poll" );
    if( use_ret == -(MBEDTLS_ERR_ENTROPY_FILE_IO_ERROR) )
        mbedtls_snprintf( buf, buflen, "ENTROPY - Read/write error in file" );
#endif /* MBEDTLS_ENTROPY_C */

#if defined(MBEDTLS_GCM_C)
    if( use_ret == -(MBEDTLS_ERR_GCM_AUTH_FAILED) )
        mbedtls_snprintf( buf, buflen, "GCM - Authenticated decryption failed" );
    if( use_ret == -(MBEDTLS_ERR_GCM_BAD_INPUT) )
        mbedtls_snprintf( buf, buflen, "GCM - Bad input parameters to function" );
#endif /* MBEDTLS_GCM_C */

#if defined(MBEDTLS_HMAC_DRBG_C)
    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_REQUEST_TOO_BIG) )
        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Too many random requested in single call" );
    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_INPUT_TOO_BIG) )
        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Input too large (Entropy + additional)" );
    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_FILE_IO_ERROR) )
        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - Read/write error in file" );
    if( use_ret == -(MBEDTLS_ERR_HMAC_DRBG_ENTROPY_SOURCE_FAILED) )
        mbedtls_snprintf( buf, buflen, "HMAC_DRBG - The entropy source failed" );
#endif /* MBEDTLS_HMAC_DRBG_C */

#if defined(MBEDTLS_NET_C)
    if( use_ret == -(MBEDTLS_ERR_NET_SOCKET_FAILED) )
        mbedtls_snprintf( buf, buflen, "NET - Failed to open a socket" );
    if( use_ret == -(MBEDTLS_ERR_NET_CONNECT_FAILED) )
        mbedtls_snprintf( buf, buflen, "NET - The connection to the given server / port failed" );
    if( use_ret == -(MBEDTLS_ERR_NET_BIND_FAILED) )
        mbedtls_snprintf( buf, buflen, "NET - Binding of the socket failed" );
    if( use_ret == -(MBEDTLS_ERR_NET_LISTEN_FAILED) )
        mbedtls_snprintf( buf, buflen, "NET - Could not listen on the socket" );
    if( use_ret == -(MBEDTLS_ERR_NET_ACCEPT_FAILED) )
        mbedtls_snprintf( buf, buflen, "NET - Could not accept the incoming connection" );
    if( use_ret == -(MBEDTLS_ERR_NET_RECV_FAILED) )
        mbedtls_snprintf( buf, buflen, "NET - Reading information from the socket failed" );
    if( use_ret == -(MBEDTLS_ERR_NET_SEND_FAILED) )
        mbedtls_snprintf( buf, buflen, "NET - Sending information through the socket failed" );
    if( use_ret == -(MBEDTLS_ERR_NET_CONN_RESET) )
        mbedtls_snprintf( buf, buflen, "NET - Connection was reset by peer" );
    if( use_ret == -(MBEDTLS_ERR_NET_UNKNOWN_HOST) )
        mbedtls_snprintf( buf, buflen, "NET - Failed to get an IP address for the given hostname" );
    if( use_ret == -(MBEDTLS_ERR_NET_BUFFER_TOO_SMALL) )
        mbedtls_snprintf( buf, buflen, "NET - Buffer is too small to hold the data" );
    if( use_ret == -(MBEDTLS_ERR_NET_INVALID_CONTEXT) )
        mbedtls_snprintf( buf, buflen, "NET - The context is invalid, eg because it was free()ed" );
#endif /* MBEDTLS_NET_C */

#if defined(MBEDTLS_OID_C)
    if( use_ret == -(MBEDTLS_ERR_OID_NOT_FOUND) )
        mbedtls_snprintf( buf, buflen, "OID - OID is not found" );
    if( use_ret == -(MBEDTLS_ERR_OID_BUF_TOO_SMALL) )
        mbedtls_snprintf( buf, buflen, "OID - output buffer is too small" );
#endif /* MBEDTLS_OID_C */

#if defined(MBEDTLS_PADLOCK_C)
    if( use_ret == -(MBEDTLS_ERR_PADLOCK_DATA_MISALIGNED) )
        mbedtls_snprintf( buf, buflen, "PADLOCK - Input data should be aligned" );
#endif /* MBEDTLS_PADLOCK_C */

#if defined(MBEDTLS_THREADING_C)
    if( use_ret == -(MBEDTLS_ERR_THREADING_FEATURE_UNAVAILABLE) )
        mbedtls_snprintf( buf, buflen, "THREADING - The selected feature is not available" );
    if( use_ret == -(MBEDTLS_ERR_THREADING_BAD_INPUT_DATA) )
        mbedtls_snprintf( buf, buflen, "THREADING - Bad input parameters to function" );
    if( use_ret == -(MBEDTLS_ERR_THREADING_MUTEX_ERROR) )
        mbedtls_snprintf( buf, buflen, "THREADING - Locking / unlocking / free failed with error code" );
#endif /* MBEDTLS_THREADING_C */

#if defined(MBEDTLS_XTEA_C)
    if( use_ret == -(MBEDTLS_ERR_XTEA_INVALID_INPUT_LENGTH) )
        mbedtls_snprintf( buf, buflen, "XTEA - The data input has an invalid length" );
#endif /* MBEDTLS_XTEA_C */
    // END generated code

    if( strlen( buf ) != 0 )
        return;

    mbedtls_snprintf( buf, buflen, "UNKNOWN ERROR CODE (%04X)", use_ret );
}
Beispiel #17
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    int exit_code = MBEDTLS_EXIT_FAILURE;
    mbedtls_pk_context pk;
    mbedtls_entropy_context entropy;
    mbedtls_ctr_drbg_context ctr_drbg;
    unsigned char hash[32];
    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
    char filename[512];
    const char *pers = "mbedtls_pk_sign";
    size_t olen = 0;

    mbedtls_entropy_init( &entropy );
    mbedtls_ctr_drbg_init( &ctr_drbg );
    mbedtls_pk_init( &pk );

    if( argc != 3 )
    {
        mbedtls_printf( "usage: mbedtls_pk_sign <key_file> <filename>\n" );

#if defined(_WIN32)
        mbedtls_printf( "\n" );
#endif

        goto exit;
    }

    mbedtls_printf( "\n  . Seeding the random number generator..." );
    fflush( stdout );

    if( ( ret = mbedtls_ctr_drbg_seed( &ctr_drbg, mbedtls_entropy_func, &entropy,
                               (const unsigned char *) pers,
                               strlen( pers ) ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_ctr_drbg_seed returned -0x%04x\n", -ret );
        goto exit;
    }

    mbedtls_printf( "\n  . Reading private key from '%s'", argv[1] );
    fflush( stdout );

    if( ( ret = mbedtls_pk_parse_keyfile( &pk, argv[1], "" ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! Could not parse '%s'\n", argv[1] );
        goto exit;
    }

    /*
     * Compute the SHA-256 hash of the input file,
     * then calculate the signature of the hash.
     */
    mbedtls_printf( "\n  . Generating the SHA-256 signature" );
    fflush( stdout );

    if( ( ret = mbedtls_md_file(
                    mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
                    argv[2], hash ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
        goto exit;
    }

    if( ( ret = mbedtls_pk_sign( &pk, MBEDTLS_MD_SHA256, hash, 0, buf, &olen,
                         mbedtls_ctr_drbg_random, &ctr_drbg ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_pk_sign returned -0x%04x\n", -ret );
        goto exit;
    }

    /*
     * Write the signature into <filename>.sig
     */
    mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[2] );

    if( ( f = fopen( filename, "wb+" ) ) == NULL )
    {
        mbedtls_printf( " failed\n  ! Could not create %s\n\n", filename );
        goto exit;
    }

    if( fwrite( buf, 1, olen, f ) != olen )
    {
        mbedtls_printf( "failed\n  ! fwrite failed\n\n" );
        fclose( f );
        goto exit;
    }

    fclose( f );

    mbedtls_printf( "\n  . Done (created \"%s\")\n\n", filename );

    exit_code = MBEDTLS_EXIT_SUCCESS;

exit:
    mbedtls_pk_free( &pk );
    mbedtls_ctr_drbg_free( &ctr_drbg );
    mbedtls_entropy_free( &entropy );

#if defined(MBEDTLS_ERROR_C)
    if( exit_code != MBEDTLS_EXIT_SUCCESS )
    {
        mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
        mbedtls_printf( "  !  Last error was: %s\n", buf );
    }
#endif

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( exit_code );
}
Beispiel #18
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    size_t i;
    mbedtls_pk_context pk;
    unsigned char hash[20];
    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
    char filename[512];

    mbedtls_pk_init( &pk );

    if( argc != 3 )
    {
        mbedtls_printf( "usage: mbedtls_pk_verify <key_file> <filename>\n" );

#if defined(_WIN32)
        mbedtls_printf( "\n" );
#endif

        goto exit;
    }

    mbedtls_printf( "\n  . Reading public key from '%s'", argv[1] );
    fflush( stdout );

    if( ( ret = mbedtls_pk_parse_public_keyfile( &pk, argv[1] ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_pk_parse_public_keyfile returned -0x%04x\n", -ret );
        goto exit;
    }

    /*
     * Extract the signature from the text file
     */
    ret = 1;
    mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[2] );

    if( ( f = fopen( filename, "rb" ) ) == NULL )
    {
        mbedtls_printf( "\n  ! Could not open %s\n\n", filename );
        goto exit;
    }


    i = fread( buf, 1, sizeof(buf), f );

    fclose( f );

    /*
     * Compute the SHA-256 hash of the input file and compare
     * it with the hash decrypted from the signature.
     */
    mbedtls_printf( "\n  . Verifying the SHA-256 signature" );
    fflush( stdout );

    if( ( ret = mbedtls_md_file(
                    mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
                    argv[2], hash ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[2] );
        goto exit;
    }

    if( ( ret = mbedtls_pk_verify( &pk, MBEDTLS_MD_SHA256, hash, 0,
                           buf, i ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_pk_verify returned -0x%04x\n", -ret );
        goto exit;
    }

    mbedtls_printf( "\n  . OK (the decrypted SHA-256 hash matches)\n\n" );

    ret = 0;

exit:
    mbedtls_pk_free( &pk );

#if defined(MBEDTLS_ERROR_C)
    mbedtls_strerror( ret, (char *) buf, sizeof(buf) );
    mbedtls_printf( "  !  Last error was: %s\n", buf );
#endif

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Beispiel #19
0
int main( int argc, char *argv[] )
{
    int i;
    unsigned char tmp[200];
    char title[TITLE_LEN];
    todo_list todo;
#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
    unsigned char alloc_buf[HEAP_SIZE] = { 0 };
#endif

    if( argc <= 1 )
    {
        memset( &todo, 1, sizeof( todo ) );
    }
    else
    {
        memset( &todo, 0, sizeof( todo ) );

        for( i = 1; i < argc; i++ )
        {
            if( strcmp( argv[i], "md4" ) == 0 )
                todo.md4 = 1;
            else if( strcmp( argv[i], "md5" ) == 0 )
                todo.md5 = 1;
            else if( strcmp( argv[i], "ripemd160" ) == 0 )
                todo.ripemd160 = 1;
            else if( strcmp( argv[i], "sha1" ) == 0 )
                todo.sha1 = 1;
            else if( strcmp( argv[i], "sha256" ) == 0 )
                todo.sha256 = 1;
            else if( strcmp( argv[i], "sha512" ) == 0 )
                todo.sha512 = 1;
            else if( strcmp( argv[i], "arc4" ) == 0 )
                todo.arc4 = 1;
            else if( strcmp( argv[i], "des3" ) == 0 )
                todo.des3 = 1;
            else if( strcmp( argv[i], "des" ) == 0 )
                todo.des = 1;
            else if( strcmp( argv[i], "aes_cbc" ) == 0 )
                todo.aes_cbc = 1;
            else if( strcmp( argv[i], "aes_gcm" ) == 0 )
                todo.aes_gcm = 1;
            else if( strcmp( argv[i], "aes_ccm" ) == 0 )
                todo.aes_ccm = 1;
            else if( strcmp( argv[i], "aes_cmac" ) == 0 )
                todo.aes_cmac = 1;
            else if( strcmp( argv[i], "des3_cmac" ) == 0 )
                todo.des3_cmac = 1;
            else if( strcmp( argv[i], "camellia" ) == 0 )
                todo.camellia = 1;
            else if( strcmp( argv[i], "blowfish" ) == 0 )
                todo.blowfish = 1;
            else if( strcmp( argv[i], "havege" ) == 0 )
                todo.havege = 1;
            else if( strcmp( argv[i], "ctr_drbg" ) == 0 )
                todo.ctr_drbg = 1;
            else if( strcmp( argv[i], "hmac_drbg" ) == 0 )
                todo.hmac_drbg = 1;
            else if( strcmp( argv[i], "rsa" ) == 0 )
                todo.rsa = 1;
            else if( strcmp( argv[i], "dhm" ) == 0 )
                todo.dhm = 1;
            else if( strcmp( argv[i], "ecdsa" ) == 0 )
                todo.ecdsa = 1;
            else if( strcmp( argv[i], "ecdh" ) == 0 )
                todo.ecdh = 1;
            else
            {
                mbedtls_printf( "Unrecognized option: %s\n", argv[i] );
                mbedtls_printf( "Available options: " OPTIONS );
            }
        }
    }

    mbedtls_printf( "\n" );

#if defined(MBEDTLS_MEMORY_BUFFER_ALLOC_C)
    mbedtls_memory_buffer_alloc_init( alloc_buf, sizeof( alloc_buf ) );
#endif
    memset( buf, 0xAA, sizeof( buf ) );
    memset( tmp, 0xBB, sizeof( tmp ) );

#if defined(MBEDTLS_MD4_C)
    if( todo.md4 )
        TIME_AND_TSC( "MD4", mbedtls_md4_ret( buf, BUFSIZE, tmp ) );
#endif

#if defined(MBEDTLS_MD5_C)
    if( todo.md5 )
        TIME_AND_TSC( "MD5", mbedtls_md5_ret( buf, BUFSIZE, tmp ) );
#endif

#if defined(MBEDTLS_RIPEMD160_C)
    if( todo.ripemd160 )
        TIME_AND_TSC( "RIPEMD160", mbedtls_ripemd160_ret( buf, BUFSIZE, tmp ) );
#endif

#if defined(MBEDTLS_SHA1_C)
    if( todo.sha1 )
        TIME_AND_TSC( "SHA-1", mbedtls_sha1_ret( buf, BUFSIZE, tmp ) );
#endif

#if defined(MBEDTLS_SHA256_C)
    if( todo.sha256 )
        TIME_AND_TSC( "SHA-256", mbedtls_sha256_ret( buf, BUFSIZE, tmp, 0 ) );
#endif

#if defined(MBEDTLS_SHA512_C)
    if( todo.sha512 )
        TIME_AND_TSC( "SHA-512", mbedtls_sha512_ret( buf, BUFSIZE, tmp, 0 ) );
#endif

#if defined(MBEDTLS_ARC4_C)
    if( todo.arc4 )
    {
        mbedtls_arc4_context arc4;
        mbedtls_arc4_init( &arc4 );
        mbedtls_arc4_setup( &arc4, tmp, 32 );
        TIME_AND_TSC( "ARC4", mbedtls_arc4_crypt( &arc4, BUFSIZE, buf, buf ) );
        mbedtls_arc4_free( &arc4 );
    }
#endif

#if defined(MBEDTLS_DES_C)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
    if( todo.des3 )
    {
        mbedtls_des3_context des3;
        mbedtls_des3_init( &des3 );
        mbedtls_des3_set3key_enc( &des3, tmp );
        TIME_AND_TSC( "3DES",
                mbedtls_des3_crypt_cbc( &des3, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
        mbedtls_des3_free( &des3 );
    }

    if( todo.des )
    {
        mbedtls_des_context des;
        mbedtls_des_init( &des );
        mbedtls_des_setkey_enc( &des, tmp );
        TIME_AND_TSC( "DES",
                mbedtls_des_crypt_cbc( &des, MBEDTLS_DES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
        mbedtls_des_free( &des );
    }

#endif /* MBEDTLS_CIPHER_MODE_CBC */
#if defined(MBEDTLS_CMAC_C)
    if( todo.des3_cmac )
    {
        unsigned char output[8];
        const mbedtls_cipher_info_t *cipher_info;

        memset( buf, 0, sizeof( buf ) );
        memset( tmp, 0, sizeof( tmp ) );

        cipher_info = mbedtls_cipher_info_from_type( MBEDTLS_CIPHER_DES_EDE3_ECB );

        TIME_AND_TSC( "3DES-CMAC",
                      mbedtls_cipher_cmac( cipher_info, tmp, 192, buf,
                      BUFSIZE, output ) );
    }
#endif /* MBEDTLS_CMAC_C */
#endif /* MBEDTLS_DES_C */

#if defined(MBEDTLS_AES_C)
#if defined(MBEDTLS_CIPHER_MODE_CBC)
    if( todo.aes_cbc )
    {
        int keysize;
        mbedtls_aes_context aes;
        mbedtls_aes_init( &aes );
        for( keysize = 128; keysize <= 256; keysize += 64 )
        {
            mbedtls_snprintf( title, sizeof( title ), "AES-CBC-%d", keysize );

            memset( buf, 0, sizeof( buf ) );
            memset( tmp, 0, sizeof( tmp ) );
            mbedtls_aes_setkey_enc( &aes, tmp, keysize );

            TIME_AND_TSC( title,
                mbedtls_aes_crypt_cbc( &aes, MBEDTLS_AES_ENCRYPT, BUFSIZE, tmp, buf, buf ) );
        }
        mbedtls_aes_free( &aes );
    }
#endif
#if defined(MBEDTLS_GCM_C)
    if( todo.aes_gcm )
    {
        int keysize;
        mbedtls_gcm_context gcm;

        mbedtls_gcm_init( &gcm );
        for( keysize = 128; keysize <= 256; keysize += 64 )
        {
            mbedtls_snprintf( title, sizeof( title ), "AES-GCM-%d", keysize );

            memset( buf, 0, sizeof( buf ) );
            memset( tmp, 0, sizeof( tmp ) );
            mbedtls_gcm_setkey( &gcm, MBEDTLS_CIPHER_ID_AES, tmp, keysize );

            TIME_AND_TSC( title,
                    mbedtls_gcm_crypt_and_tag( &gcm, MBEDTLS_GCM_ENCRYPT, BUFSIZE, tmp,
                        12, NULL, 0, buf, buf, 16, tmp ) );

            mbedtls_gcm_free( &gcm );
        }
    }
#endif
#if defined(MBEDTLS_CCM_C)
    if( todo.aes_ccm )
    {
        int keysize;
        mbedtls_ccm_context ccm;

        mbedtls_ccm_init( &ccm );
        for( keysize = 128; keysize <= 256; keysize += 64 )
        {
            mbedtls_snprintf( title, sizeof( title ), "AES-CCM-%d", keysize );

            memset( buf, 0, sizeof( buf ) );
            memset( tmp, 0, sizeof( tmp ) );
            mbedtls_ccm_setkey( &ccm, MBEDTLS_CIPHER_ID_AES, tmp, keysize );

            TIME_AND_TSC( title,
                    mbedtls_ccm_encrypt_and_tag( &ccm, BUFSIZE, tmp,
                        12, NULL, 0, buf, buf, tmp, 16 ) );

            mbedtls_ccm_free( &ccm );
        }
    }
#endif
#if defined(MBEDTLS_CMAC_C)
    if( todo.aes_cmac )
    {
        unsigned char output[16];
        const mbedtls_cipher_info_t *cipher_info;
        mbedtls_cipher_type_t cipher_type;
        int keysize;

        for( keysize = 128, cipher_type = MBEDTLS_CIPHER_AES_128_ECB;
             keysize <= 256;
             keysize += 64, cipher_type++ )
        {
            mbedtls_snprintf( title, sizeof( title ), "AES-CMAC-%d", keysize );

            memset( buf, 0, sizeof( buf ) );
            memset( tmp, 0, sizeof( tmp ) );

            cipher_info = mbedtls_cipher_info_from_type( cipher_type );

            TIME_AND_TSC( title,
                          mbedtls_cipher_cmac( cipher_info, tmp, keysize,
                                               buf, BUFSIZE, output ) );
        }

        memset( buf, 0, sizeof( buf ) );
        memset( tmp, 0, sizeof( tmp ) );
        TIME_AND_TSC( "AES-CMAC-PRF-128",
                      mbedtls_aes_cmac_prf_128( tmp, 16, buf, BUFSIZE,
                                                output ) );
    }
#endif /* MBEDTLS_CMAC_C */
#endif /* MBEDTLS_AES_C */

#if defined(MBEDTLS_CAMELLIA_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
    if( todo.camellia )
    {
        int keysize;
        mbedtls_camellia_context camellia;
        mbedtls_camellia_init( &camellia );
        for( keysize = 128; keysize <= 256; keysize += 64 )
        {
            mbedtls_snprintf( title, sizeof( title ), "CAMELLIA-CBC-%d", keysize );

            memset( buf, 0, sizeof( buf ) );
            memset( tmp, 0, sizeof( tmp ) );
            mbedtls_camellia_setkey_enc( &camellia, tmp, keysize );

            TIME_AND_TSC( title,
                    mbedtls_camellia_crypt_cbc( &camellia, MBEDTLS_CAMELLIA_ENCRYPT,
                        BUFSIZE, tmp, buf, buf ) );
        }
        mbedtls_camellia_free( &camellia );
    }
#endif

#if defined(MBEDTLS_BLOWFISH_C) && defined(MBEDTLS_CIPHER_MODE_CBC)
    if( todo.blowfish )
    {
        int keysize;
        mbedtls_blowfish_context blowfish;
        mbedtls_blowfish_init( &blowfish );

        for( keysize = 128; keysize <= 256; keysize += 64 )
        {
            mbedtls_snprintf( title, sizeof( title ), "BLOWFISH-CBC-%d", keysize );

            memset( buf, 0, sizeof( buf ) );
            memset( tmp, 0, sizeof( tmp ) );
            mbedtls_blowfish_setkey( &blowfish, tmp, keysize );

            TIME_AND_TSC( title,
                    mbedtls_blowfish_crypt_cbc( &blowfish, MBEDTLS_BLOWFISH_ENCRYPT, BUFSIZE,
                        tmp, buf, buf ) );
        }

        mbedtls_blowfish_free( &blowfish );
    }
#endif

#if defined(MBEDTLS_HAVEGE_C)
    if( todo.havege )
    {
        mbedtls_havege_state hs;
        mbedtls_havege_init( &hs );
        TIME_AND_TSC( "HAVEGE", mbedtls_havege_random( &hs, buf, BUFSIZE ) );
        mbedtls_havege_free( &hs );
    }
#endif

#if defined(MBEDTLS_CTR_DRBG_C)
    if( todo.ctr_drbg )
    {
        mbedtls_ctr_drbg_context ctr_drbg;

        mbedtls_ctr_drbg_init( &ctr_drbg );

        if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
            mbedtls_exit(1);
        TIME_AND_TSC( "CTR_DRBG (NOPR)",
                if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
                mbedtls_exit(1) );

        if( mbedtls_ctr_drbg_seed( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
            mbedtls_exit(1);
        mbedtls_ctr_drbg_set_prediction_resistance( &ctr_drbg, MBEDTLS_CTR_DRBG_PR_ON );
        TIME_AND_TSC( "CTR_DRBG (PR)",
                if( mbedtls_ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
                mbedtls_exit(1) );
        mbedtls_ctr_drbg_free( &ctr_drbg );
    }
Beispiel #20
0
/*
 * Return an informational string about the CRL.
 */
int mbedtls_x509_crl_info( char *buf, size_t size, const char *prefix,
                   const mbedtls_x509_crl *crl )
{
    int ret;
    size_t n;
    char *p;
    const mbedtls_x509_crl_entry *entry;

    p = buf;
    n = size;

    ret = mbedtls_snprintf( p, n, "%sCRL version   : %d",
                               prefix, crl->version );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_snprintf( p, n, "\n%sissuer name   : ", prefix );
    MBEDTLS_X509_SAFE_SNPRINTF;
    ret = mbedtls_x509_dn_gets( p, n, &crl->issuer );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_snprintf( p, n, "\n%sthis update   : " \
                   "%04d-%02d-%02d %02d:%02d:%02d", prefix,
                   crl->this_update.year, crl->this_update.mon,
                   crl->this_update.day,  crl->this_update.hour,
                   crl->this_update.min,  crl->this_update.sec );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_snprintf( p, n, "\n%snext update   : " \
                   "%04d-%02d-%02d %02d:%02d:%02d", prefix,
                   crl->next_update.year, crl->next_update.mon,
                   crl->next_update.day,  crl->next_update.hour,
                   crl->next_update.min,  crl->next_update.sec );
    MBEDTLS_X509_SAFE_SNPRINTF;

    entry = &crl->entry;

    ret = mbedtls_snprintf( p, n, "\n%sRevoked certificates:",
                               prefix );
    MBEDTLS_X509_SAFE_SNPRINTF;

    while( entry != NULL && entry->raw.len != 0 )
    {
        ret = mbedtls_snprintf( p, n, "\n%sserial number: ",
                               prefix );
        MBEDTLS_X509_SAFE_SNPRINTF;

        ret = mbedtls_x509_serial_gets( p, n, &entry->serial );
        MBEDTLS_X509_SAFE_SNPRINTF;

        ret = mbedtls_snprintf( p, n, " revocation date: " \
                   "%04d-%02d-%02d %02d:%02d:%02d",
                   entry->revocation_date.year, entry->revocation_date.mon,
                   entry->revocation_date.day,  entry->revocation_date.hour,
                   entry->revocation_date.min,  entry->revocation_date.sec );
        MBEDTLS_X509_SAFE_SNPRINTF;

        entry = entry->next;
    }

    ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_x509_sig_alg_gets( p, n, &crl->sig_oid, crl->sig_pk, crl->sig_md,
                             crl->sig_opts );
    MBEDTLS_X509_SAFE_SNPRINTF;

    ret = mbedtls_snprintf( p, n, "\n" );
    MBEDTLS_X509_SAFE_SNPRINTF;

    return( (int) ( size - n ) );
}
Beispiel #21
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret, c;
    size_t i;
    mbedtls_rsa_context rsa;
    unsigned char hash[32];
    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
    char filename[512];

    ret = 1;
    if( argc != 2 )
    {
        mbedtls_printf( "usage: rsa_verify <filename>\n" );

#if defined(_WIN32)
        mbedtls_printf( "\n" );
#endif

        goto exit;
    }

    mbedtls_printf( "\n  . Reading public key from rsa_pub.txt" );
    fflush( stdout );

    if( ( f = fopen( "rsa_pub.txt", "rb" ) ) == NULL )
    {
        mbedtls_printf( " failed\n  ! Could not open rsa_pub.txt\n" \
                "  ! Please run rsa_genkey first\n\n" );
        goto exit;
    }

    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );

    if( ( ret = mbedtls_mpi_read_file( &rsa.N, 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &rsa.E, 16, f ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
        goto exit;
    }

    rsa.len = ( mbedtls_mpi_bitlen( &rsa.N ) + 7 ) >> 3;

    fclose( f );

    /*
     * Extract the RSA signature from the text file
     */
    ret = 1;
    mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[1] );

    if( ( f = fopen( filename, "rb" ) ) == NULL )
    {
        mbedtls_printf( "\n  ! Could not open %s\n\n", filename );
        goto exit;
    }

    i = 0;
    while( fscanf( f, "%02X", &c ) > 0 &&
           i < (int) sizeof( buf ) )
        buf[i++] = (unsigned char) c;

    fclose( f );

    if( i != rsa.len )
    {
        mbedtls_printf( "\n  ! Invalid RSA signature format\n\n" );
        goto exit;
    }

    /*
     * Compute the SHA-256 hash of the input file and
     * verify the signature
     */
    mbedtls_printf( "\n  . Verifying the RSA/SHA-256 signature" );
    fflush( stdout );

    if( ( ret = mbedtls_md_file(
                    mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
                    argv[1], hash ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[1] );
        goto exit;
    }

    if( ( ret = mbedtls_rsa_pkcs1_verify( &rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC,
                                  MBEDTLS_MD_SHA256, 20, hash, buf ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_verify returned -0x%0x\n\n", -ret );
        goto exit;
    }

    mbedtls_printf( "\n  . OK (the signature is valid)\n\n" );

    ret = 0;

exit:

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Beispiel #22
0
void mbedtls_debug_print_buf( const mbedtls_ssl_context *ssl, int level,
                      const char *file, int line, const char *text,
                      const unsigned char *buf, size_t len )
{
#ifndef TLS_DEBUG_HEAP_USE
    char str[DEBUG_BUF_SIZE];
#else
    char *str = tls_debug_zalloc(DEBUG_BUF_SIZE);
    if (str == NULL)
    	return;
#endif
    char txt[17];
    size_t i, idx = 0;

    if( ssl->conf == NULL || ssl->conf->f_dbg == NULL || level > debug_threshold )
#ifndef TLS_DEBUG_HEAP_USE
    	return;
#else
	goto exit;
#endif

    mbedtls_snprintf( str + idx, DEBUG_BUF_SIZE/*sizeof( str )*/ - idx, "dumping '%s' (%u bytes)\n",
              text, (unsigned int) len );

    debug_send_line( ssl, level, file, line, str );

    idx = 0;
    memset( txt, 0, sizeof( txt ) );
    for( i = 0; i < len; i++ )
    {
        if( i >= 4096 )
            break;

        if( i % 16 == 0 )
        {
            if( i > 0 )
            {
                mbedtls_snprintf( str + idx, DEBUG_BUF_SIZE/*sizeof( str )*/ - idx, "  %s\n", txt );
                debug_send_line( ssl, level, file, line, str );

                idx = 0;
                memset( txt, 0, sizeof( txt ) );
            }

            idx += mbedtls_snprintf( str + idx, DEBUG_BUF_SIZE/*sizeof( str )*/ - idx, "%04x: ",
                             (unsigned int) i );

        }

        idx += mbedtls_snprintf( str + idx, DEBUG_BUF_SIZE/*sizeof( str )*/ - idx, " %02x",
                         (unsigned int) buf[i] );
        txt[i % 16] = ( buf[i] > 31 && buf[i] < 127 ) ? buf[i] : '.' ;
    }

    if( len > 0 )
    {
        for( /* i = i */; i % 16 != 0; i++ )
            idx += mbedtls_snprintf( str + idx, DEBUG_BUF_SIZE/*sizeof( str )*/ - idx, "   " );

        mbedtls_snprintf( str + idx, DEBUG_BUF_SIZE/*sizeof( str )*/ - idx, "  %s\n", txt );
        debug_send_line( ssl, level, file, line, str );
    }
#ifdef TLS_DEBUG_HEAP_USE
  exit:
  	tls_debug_free(str);
#endif
}
Beispiel #23
0
int main( void )
{
    int ret, i;
    mbedtls_x509_crt cacert;
    mbedtls_x509_crl crl;
    char buf[10240];

    mbedtls_x509_crt_init( &cacert );
    mbedtls_x509_crl_init( &crl );

    /*
     * 1.1. Load the trusted CA
     */
    mbedtls_printf( "\n  . Loading the CA root certificate ..." );
    fflush( stdout );

    /*
     * Alternatively, you may load the CA certificates from a .pem or
     * .crt file by calling mbedtls_x509_crt_parse_file( &cacert, "myca.crt" ).
     */
    ret = mbedtls_x509_crt_parse_file( &cacert, "ssl/test-ca/test-ca.crt" );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    mbedtls_x509_crt_info( buf, 1024, "CRT: ", &cacert );
    mbedtls_printf("%s\n", buf );

    /*
     * 1.2. Load the CRL
     */
    mbedtls_printf( "  . Loading the CRL ..." );
    fflush( stdout );

    ret = mbedtls_x509_crl_parse_file( &crl, "ssl/test-ca/crl.pem" );
    if( ret != 0 )
    {
        mbedtls_printf( " failed\n  !  mbedtls_x509_crl_parse_file returned %d\n\n", ret );
        goto exit;
    }

    mbedtls_printf( " ok\n" );

    mbedtls_x509_crl_info( buf, 1024, "CRL: ", &crl );
    mbedtls_printf("%s\n", buf );

    for( i = 0; i < MAX_CLIENT_CERTS; i++ )
    {
        /*
         * 1.3. Load own certificate
         */
        char    name[512];
        uint32_t flags;
        mbedtls_x509_crt clicert;
        mbedtls_pk_context pk;

        mbedtls_x509_crt_init( &clicert );
        mbedtls_pk_init( &pk );

        mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_certificates[i]);

        mbedtls_printf( "  . Loading the client certificate %s...", name );
        fflush( stdout );

        ret = mbedtls_x509_crt_parse_file( &clicert, name );
        if( ret != 0 )
        {
            mbedtls_printf( " failed\n  !  mbedtls_x509_crt_parse_file returned %d\n\n", ret );
            goto exit;
        }

        mbedtls_printf( " ok\n" );

        /*
         * 1.4. Verify certificate validity with CA certificate
         */
        mbedtls_printf( "  . Verify the client certificate with CA certificate..." );
        fflush( stdout );

        ret = mbedtls_x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL,
                               NULL );
        if( ret != 0 )
        {
            if( ret == MBEDTLS_ERR_X509_CERT_VERIFY_FAILED )
            {
                 char vrfy_buf[512];

                 mbedtls_printf( " failed\n" );
                 mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );
                 mbedtls_printf( "%s\n", vrfy_buf );
             }
             else
             {
                mbedtls_printf( " failed\n  !  mbedtls_x509_crt_verify returned %d\n\n", ret );
                goto exit;
            }
        }

        mbedtls_printf( " ok\n" );

        /*
         * 1.5. Load own private key
         */
        mbedtls_snprintf(name, 512, "ssl/test-ca/%s", client_private_keys[i]);

        mbedtls_printf( "  . Loading the client private key %s...", name );
        fflush( stdout );

        ret = mbedtls_pk_parse_keyfile( &pk, name, NULL );
        if( ret != 0 )
        {
            mbedtls_printf( " failed\n  !  mbedtls_pk_parse_keyfile returned %d\n\n", ret );
            goto exit;
        }

        mbedtls_printf( " ok\n" );

        /*
         * 1.6. Verify certificate validity with private key
         */
        mbedtls_printf( "  . Verify the client certificate with private key..." );
        fflush( stdout );


        /* EC NOT IMPLEMENTED YET */
        if( ! mbedtls_pk_can_do( &clicert.pk, MBEDTLS_PK_RSA ) )
        {
            mbedtls_printf( " failed\n  !  certificate's key is not RSA\n\n" );
            ret = MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE;
            goto exit;
        }

        ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->N, &mbedtls_pk_rsa( clicert.pk )->N);
        if( ret != 0 )
        {
            mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for N returned %d\n\n", ret );
            goto exit;
        }

        ret = mbedtls_mpi_cmp_mpi(&mbedtls_pk_rsa( pk )->E, &mbedtls_pk_rsa( clicert.pk )->E);
        if( ret != 0 )
        {
            mbedtls_printf( " failed\n  !  mbedtls_mpi_cmp_mpi for E returned %d\n\n", ret );
            goto exit;
        }

        ret = mbedtls_rsa_check_privkey( mbedtls_pk_rsa( pk ) );
        if( ret != 0 )
        {
            mbedtls_printf( " failed\n  !  mbedtls_rsa_check_privkey returned %d\n\n", ret );
            goto exit;
        }

        mbedtls_printf( " ok\n" );

        mbedtls_x509_crt_free( &clicert );
        mbedtls_pk_free( &pk );
    }

exit:
    mbedtls_x509_crt_free( &cacert );
    mbedtls_x509_crl_free( &crl );

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( ret );
}
Beispiel #24
0
int main( int argc, char *argv[] )
{
    FILE *f;
    int ret = 1;
    int exit_code = MBEDTLS_EXIT_FAILURE;
    size_t i;
    mbedtls_rsa_context rsa;
    unsigned char hash[32];
    unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
    char filename[512];
    mbedtls_mpi N, P, Q, D, E, DP, DQ, QP;

    mbedtls_rsa_init( &rsa, MBEDTLS_RSA_PKCS_V15, 0 );

    mbedtls_mpi_init( &N ); mbedtls_mpi_init( &P ); mbedtls_mpi_init( &Q );
    mbedtls_mpi_init( &D ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &DP );
    mbedtls_mpi_init( &DQ ); mbedtls_mpi_init( &QP );

    if( argc != 2 )
    {
        mbedtls_printf( "usage: rsa_sign <filename>\n" );

#if defined(_WIN32)
        mbedtls_printf( "\n" );
#endif

        goto exit;
    }

    mbedtls_printf( "\n  . Reading private key from rsa_priv.txt" );
    fflush( stdout );

    if( ( f = fopen( "rsa_priv.txt", "rb" ) ) == NULL )
    {
        mbedtls_printf( " failed\n  ! Could not open rsa_priv.txt\n" \
                "  ! Please run rsa_genkey first\n\n" );
        goto exit;
    }

    if( ( ret = mbedtls_mpi_read_file( &N , 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &E , 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &D , 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &P , 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &Q , 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &DP , 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &DQ , 16, f ) ) != 0 ||
        ( ret = mbedtls_mpi_read_file( &QP , 16, f ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_mpi_read_file returned %d\n\n", ret );
        fclose( f );
        goto exit;
    }
    fclose( f );

    if( ( ret = mbedtls_rsa_import( &rsa, &N, &P, &Q, &D, &E ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_rsa_import returned %d\n\n",
                        ret );
        goto exit;
    }

    if( ( ret = mbedtls_rsa_complete( &rsa ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_rsa_complete returned %d\n\n",
                        ret );
        goto exit;
    }

    mbedtls_printf( "\n  . Checking the private key" );
    fflush( stdout );
    if( ( ret = mbedtls_rsa_check_privkey( &rsa ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_rsa_check_privkey failed with -0x%0x\n", -ret );
        goto exit;
    }

    /*
     * Compute the SHA-256 hash of the input file,
     * then calculate the RSA signature of the hash.
     */
    mbedtls_printf( "\n  . Generating the RSA/SHA-256 signature" );
    fflush( stdout );

    if( ( ret = mbedtls_md_file(
                    mbedtls_md_info_from_type( MBEDTLS_MD_SHA256 ),
                    argv[1], hash ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! Could not open or read %s\n\n", argv[1] );
        goto exit;
    }

    if( ( ret = mbedtls_rsa_pkcs1_sign( &rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, MBEDTLS_MD_SHA256,
                                20, hash, buf ) ) != 0 )
    {
        mbedtls_printf( " failed\n  ! mbedtls_rsa_pkcs1_sign returned -0x%0x\n\n", -ret );
        goto exit;
    }

    /*
     * Write the signature into <filename>.sig
     */
    mbedtls_snprintf( filename, sizeof(filename), "%s.sig", argv[1] );

    if( ( f = fopen( filename, "wb+" ) ) == NULL )
    {
        mbedtls_printf( " failed\n  ! Could not create %s\n\n", argv[1] );
        goto exit;
    }

    for( i = 0; i < rsa.len; i++ )
        mbedtls_fprintf( f, "%02X%s", buf[i],
                 ( i + 1 ) % 16 == 0 ? "\r\n" : " " );

    fclose( f );

    mbedtls_printf( "\n  . Done (created \"%s\")\n\n", filename );

    exit_code = MBEDTLS_EXIT_SUCCESS;

exit:

    mbedtls_rsa_free( &rsa );
    mbedtls_mpi_free( &N ); mbedtls_mpi_free( &P ); mbedtls_mpi_free( &Q );
    mbedtls_mpi_free( &D ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &DP );
    mbedtls_mpi_free( &DQ ); mbedtls_mpi_free( &QP );

#if defined(_WIN32)
    mbedtls_printf( "  + Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( exit_code );
}