Esempio n. 1
0
/*
 * Perform a public RSA and check the message digest
 */
int rsa_pkcs1_verify( rsa_context *ctx, int alg_id,
                      uchar *hash, int hashlen,
                      uchar *sig,  int siglen )
{
    int len;
    uchar *p, c, buf[512];

    if( siglen != ctx->len || siglen < 48 || siglen > 512 )
        return( ERR_RSA_VERIFY_FAILED );

    if( rsa_public( ctx, sig, siglen, buf, siglen ) != 0 )
        return( ERR_RSA_VERIFY_FAILED );

    p = buf;

    if( *p++ != 0 || *p++ != RSA_SIGN )
        return( ERR_RSA_VERIFY_FAILED );

    while( *p != 0 )
    {
        if( p >= buf + siglen - 1 || *p != 0xFF )
            return( ERR_RSA_VERIFY_FAILED );
        p++;
    }
    p++;

    len = siglen - (int)( p - buf );

    if( len == 34 )
    {
        c = p[13];
        p[13] = 0;

        if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
            return( ERR_RSA_VERIFY_FAILED );

        if( ( c == 2 && alg_id == RSA_MD2 ) ||
            ( c == 4 && alg_id == RSA_MD4 ) ||
            ( c == 5 && alg_id == RSA_MD5 ) )
        {
            if( memcmp( p + 18, hash, 16 ) == 0 ) 
                return( 0 );
        }
    }

    if( len == 35 && alg_id == RSA_SHA1 )
    {
        if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
            memcmp( p + 15, hash, 20 ) == 0 )
            return( 0 );
    }

    if( len == hashlen && alg_id == RSA_NONE )
    {
        if( memcmp( p, hash, hashlen ) == 0 )
            return( 0 );
    }

    return( ERR_RSA_VERIFY_FAILED );
}
Esempio n. 2
0
/*
 * Add the PKCS#1 v1.5 padding and do a public RSA
 */
int rsa_pkcs1_encrypt( rsa_context   *ctx,
                       unsigned char *input,  int ilen,
                       unsigned char *output, int *olen )
{
    int nb_pad;
    unsigned char *p = output;

    if( *olen != ctx->len || *olen < ilen + 11 )
    {
        return( ERR_RSA_BAD_INPUT_DATA );
    }

    nb_pad = *olen - 3 - ilen;

    *p++ = 0;
    *p++ = RSA_CRYPT;

    while( nb_pad-- > 0 )
    {
        do { *p = rand(); } while( *p == 0 );
        p++;
    }

    *p++ = 0;
    memcpy( p, input, ilen );

    return( rsa_public( ctx, output, *olen, output, olen ) );
}
Esempio n. 3
0
/*
 * Add the PKCS1 v1.5 padding and do a public RSA
 */
int rsa_pkcs1_encrypt( rsa_context *ctx,
                       uchar *input,  int ilen,
                       uchar *output, int olen )
{
    int nb_pad;
    uchar *p = output;

    if( olen != ctx->len || olen < ilen + 11 )
        return( ERR_RSA_ENCRYPT_FAILED );

    nb_pad = olen - 3 - ilen;

    *p++ = 0;
    *p++ = RSA_CRYPT;

    while( nb_pad-- > 0 )
    {
        do { *p = (uchar) rand(); } while( *p == 0 );
        p++;
    }

    *p++ = 0;
    memcpy( p, input, ilen );

    if( rsa_public( ctx, output, olen, output, olen ) != 0 )
        return( ERR_RSA_ENCRYPT_FAILED );

    return( 0 );
}
Esempio n. 4
0
File: rsa.c Progetto: ahawad/opensgx
/*
 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-ENCRYPT function
 */
int rsa_rsaes_pkcs1_v15_encrypt( rsa_context *ctx,
                                 int (*f_rng)(void *, unsigned char *, size_t),
                                 void *p_rng,
                                 int mode, size_t ilen,
                                 const unsigned char *input,
                                 unsigned char *output )
{
    size_t nb_pad, olen;
    int ret;
    unsigned char *p = output;

    if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    if( f_rng == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    olen = ctx->len;

    if( olen < ilen + 11 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    nb_pad = olen - 3 - ilen;

    *p++ = 0;
    if( mode == RSA_PUBLIC )
    {
        *p++ = RSA_CRYPT;

        while( nb_pad-- > 0 )
        {
            int rng_dl = 100;

            do {
                ret = f_rng( p_rng, p, 1 );
            } while( *p == 0 && --rng_dl && ret == 0 );

            // Check if RNG failed to generate data
            //
            if( rng_dl == 0 || ret != 0 )
                return( POLARSSL_ERR_RSA_RNG_FAILED + ret );

            p++;
        }
    }
    else
    {
        *p++ = RSA_SIGN;

        while( nb_pad-- > 0 )
            *p++ = 0xFF;
    }

    *p++ = 0;
    memcpy( p, input, ilen );

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, output, output )
            : rsa_private( ctx, f_rng, p_rng, output, output ) );
}
Esempio n. 5
0
File: rsa.c Progetto: sunfirefox/est
/*
    Add the message padding, then do an RSA operation
 */
int rsa_pkcs1_encrypt(rsa_context *ctx, int mode, int ilen, uchar *input, uchar *output)
{
    int nb_pad, olen;
    uchar *p = output;

    olen = ctx->len;

    switch (ctx->padding) {
    case RSA_PKCS_V15:

        if (ilen < 0 || olen < ilen + 11) {
            return EST_ERR_RSA_BAD_INPUT_DATA;
        }
        nb_pad = olen - 3 - ilen;
        *p++ = 0;
        *p++ = RSA_CRYPT;

        while (nb_pad-- > 0) {
            do {
                *p = (uchar)rand();
            } while (*p == 0);
            p++;
        }
        *p++ = 0;
        memcpy(p, input, ilen);
        break;

    default:
        return EST_ERR_RSA_INVALID_PADDING;
    }
    return (mode == RSA_PUBLIC) ? rsa_public(ctx, output, output) : rsa_private(ctx, output, output);
}
Esempio n. 6
0
File: rsa.c Progetto: nagash91/EDC
/*
 * Do an RSA operation, then remove the message padding
 */
int rsa_pkcs1_decrypt( rsa_context *ctx,
                       int mode, int *olen,
                       unsigned char *input,
                       unsigned char *output,
		       int output_max_len)
{
    int ret, ilen;
    unsigned char *p;
    unsigned char buf[1024];

    ilen = ctx->len;

    if( ilen < 16 || ilen > (int) sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, input, buf )
          : rsa_private( ctx, input, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            if( *p++ != 0 || *p++ != RSA_CRYPT )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            while( *p != 0 )
            {
                if( p >= buf + ilen - 1 )
                    return( POLARSSL_ERR_RSA_INVALID_PADDING );
                p++;
            }
            p++;
            break;

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    if (ilen - (int)(p - buf) > output_max_len)
    	return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );

    *olen = ilen - (int)(p - buf);
    memcpy( output, p, *olen );

    return( 0 );
}
Esempio n. 7
0
/*
 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
 */
int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
                                 int (*f_rng)(void *, unsigned char *, size_t),
                                 void *p_rng,
                                 int mode, size_t *olen,
                                 const unsigned char *input,
                                 unsigned char *output,
                                 size_t output_max_len)
{
    int ret;
    size_t ilen, pad_count = 0, i;
    unsigned char *p, bad, pad_done = 0;
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];

    if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ilen = ctx->len;

    if( ilen < 16 || ilen > sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, input, buf )
          : rsa_private( ctx, f_rng, p_rng, input, buf );

    if( ret != 0 )
        return( ret );

    p = buf;
    bad = 0;

    /*
     * Check and get padding len in "constant-time"
     */
    bad |= *p++; /* First byte must be 0 */

    /* This test does not depend on secret data */
    if( mode == RSA_PRIVATE )
    {
        bad |= *p++ ^ RSA_CRYPT;

        /* Get padding len, but always read till end of buffer
         * (minus one, for the 00 byte) */
        for( i = 0; i < ilen - 3; i++ )
        {
            pad_done  |= ((p[i] | (unsigned char)-p[i]) >> 7) ^ 1;
            pad_count += ((pad_done | (unsigned char)-pad_done) >> 7) ^ 1;
        }

        p += pad_count;
        bad |= *p++; /* Must be zero */
    }
Esempio n. 8
0
/*
 * Add the message padding, then do an RSA operation
 */
int rsa_pkcs1_encrypt( rsa_context *ctx,
                       int (*f_rng)(void *),
                       void *p_rng,
                       int mode, int  ilen,
                       const unsigned char *input,
                       unsigned char *output )
{
    int nb_pad, olen;
    unsigned char *p = output;

    olen = ctx->len;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            if( ilen < 0 || olen < ilen + 11 || f_rng == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            nb_pad = olen - 3 - ilen;

            *p++ = 0;
            *p++ = RSA_CRYPT;

            while( nb_pad-- > 0 )
            {
                int rng_dl = 100;

                do {
                    *p = (unsigned char) f_rng( p_rng );
                } while( *p == 0 && --rng_dl );

                // Check if RNG failed to generate data
                //
                if( rng_dl == 0 )
                    return POLARSSL_ERR_RSA_RNG_FAILED;

                p++;
            }
            *p++ = 0;
            memcpy( p, input, ilen );
            break;

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, output, output )
            : rsa_private( ctx, output, output ) );
}
Esempio n. 9
0
int ctr_rsa_public(const u8 signature[0x100], u8 output[0x100], rsakey2048* key)
{
	ctr_rsa_context ctx;
	u32 result;

	ctr_rsa_init(&ctx, key);

	result = rsa_public(&ctx.rsa, signature, output);

	ctr_rsa_free(&ctx);

	if (result == 0)
		return 1;
	else
		return 0;
}
Esempio n. 10
0
File: rsa.c Progetto: sunfirefox/est
/*
    Do an RSA operation, then remove the message padding
 */
int rsa_pkcs1_decrypt(rsa_context *ctx, int mode, int *olen, uchar *input, uchar *output, int output_max_len)
{
    int ret, ilen;
    uchar *p;
    uchar buf[512];

    ilen = ctx->len;

    if (ilen < 16 || ilen > (int)sizeof(buf)) {
        return EST_ERR_RSA_BAD_INPUT_DATA;
    }
    ret = (mode == RSA_PUBLIC) ? rsa_public(ctx, input, buf) : rsa_private(ctx, input, buf);

    if (ret != 0) {
        return ret;
    }
    p = buf;

    switch (ctx->padding) {
    case RSA_PKCS_V15:

        if (*p++ != 0 || *p++ != RSA_CRYPT) {
            return EST_ERR_RSA_INVALID_PADDING;
        }
        while (*p != 0) {
            if (p >= buf + ilen - 1) {
                return EST_ERR_RSA_INVALID_PADDING;
            }
            p++;
        }
        p++;
        break;

    default:
        return EST_ERR_RSA_INVALID_PADDING;
    }
    if (ilen - (int)(p - buf) > output_max_len) {
        return EST_ERR_RSA_OUTPUT_TO_LARGE;
    }
    *olen = ilen - (int)(p - buf);
    memcpy(output, p, *olen);
    return 0;
}
Esempio n. 11
0
void
crypto_rsa_encrypt(int len, uint8 * in, uint8 * out, uint32 modulus_size, uint8 * modulus, uint8 * exponent)
{
	rsa_context ctx;
	rsa_init(&ctx, 0, 0);
	ctx.len = modulus_size;
	mpi_init(&ctx.N, &ctx.E, NULL);
	mpi_read_binary(&ctx.N, modulus, modulus_size);
	mpi_read_binary(&ctx.E, exponent, SEC_EXPONENT_SIZE);
	ASSERT(!rsa_check_pubkey( &ctx ));

	ASSERT(modulus_size <= SEC_MAX_MODULUS_SIZE);
	uint8 in2[SEC_MAX_MODULUS_SIZE];
	memset(in2, 0, modulus_size - len);
	memcpy(in2 + modulus_size - len, in, len);
	int err = rsa_public(&ctx, in2, out);
	ASSERT(!err);
	mpi_free(&ctx.N, &ctx.E, NULL);
	rsa_free(&ctx);
}
Esempio n. 12
0
int main( void )
{
    int keysize;
    unsigned long i, j, tsc;
    unsigned char buf[BUFSIZE];
    unsigned char tmp[32];
    arc4_context arc4;
    des3_context des3;
    des_context des;
    aes_context aes;
    rsa_context rsa;

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

    printf( "\n" );

    /*
     * MD2 timing
     */ 
    printf( "  MD2       :  " );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        md2_csum( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 32; j++ )
        md2_csum( buf, BUFSIZE, tmp );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * MD4 timing
     */ 
    printf( "  MD4       :  " );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        md4_csum( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        md4_csum( buf, BUFSIZE, tmp );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * MD5 timing
     */ 
    printf( "  MD5       :  " );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        md5_csum( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        md5_csum( buf, BUFSIZE, tmp );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * SHA-1 timing
     */ 
    printf( "  SHA-1     :  " );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        sha1_csum( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha1_csum( buf, BUFSIZE, tmp );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * SHA-256 timing
     */ 
    printf( "  SHA-256   :  " );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        sha2_csum( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha2_csum( buf, BUFSIZE, tmp );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * ARC4 timing
     */ 
    printf( "  ARC4      :  " );
    fflush( stdout );

    arc4_setup( &arc4, tmp, 32 );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        arc4_crypt( &arc4, buf, BUFSIZE );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        arc4_crypt( &arc4, buf, BUFSIZE );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * Triple-DES timing
     */ 
    printf( "  3DES      :  " );
    fflush( stdout );

    des3_set_3keys( &des3, tmp );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        des3_cbc_encrypt( &des3, tmp, buf, buf, BUFSIZE );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        des3_cbc_encrypt( &des3, tmp, buf, buf, BUFSIZE );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * DES timing
     */ 
    printf( "  DES       :  " );
    fflush( stdout );

    des_set_key( &des, tmp );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        des_cbc_encrypt( &des, tmp, buf, buf, BUFSIZE );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        des_cbc_encrypt( &des, tmp, buf, buf, BUFSIZE );

    printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    /*
     * AES timings
     */ 
    for( keysize = 128; keysize <= 256; keysize += 64 )
    {
        printf( "  AES-%d   :  ", keysize );
        fflush( stdout );

        aes_set_key( &aes, tmp, keysize );

        set_alarm( 1 );

        for( i = 1; ! alarmed; i++ )
            aes_cbc_encrypt( &aes, tmp, buf, buf, BUFSIZE );

        tsc = hardclock();
        for( j = 0; j < 1024; j++ )
            aes_cbc_encrypt( &aes, tmp, buf, buf, BUFSIZE );

        printf( "%9ld Kb/s,  %9ld cycles/byte\n", i * BUFSIZE / 1024,
                        ( hardclock() - tsc ) / ( j * BUFSIZE ) );
    }

    /*
     * RSA-1024 timing
     */ 
    printf( "  RSA-1024  :  " );
    fflush( stdout );

    rsa_gen_key( &rsa, 1024, 65537, myrand, NULL );
    set_alarm( 4 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, 128, buf, 128 );
    }

    printf( "%9ld  public/s\n", i / 4 );

    printf( "  RSA-1024  :  " );
    fflush( stdout );
    set_alarm( 4 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, 128, buf, 128 );
    }

    printf( "%9ld private/s\n", i / 4 );

    rsa_free( &rsa );

    /*
     * RSA-2048 timing
     */ 
    printf( "  RSA-2048  :  " );
    fflush( stdout );

    rsa_gen_key( &rsa, 2048, 65537, myrand, NULL );
    set_alarm( 4 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, 256, buf, 256 );
    }

    printf( "%9ld  public/s\n", i / 4 );

    printf( "  RSA-2048  :  " );
    fflush( stdout );

    set_alarm( 4 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, 256, buf, 256 );
    }

    printf( "%9ld private/s\n\n", i / 4 );

    rsa_free( &rsa );

#ifdef WIN32
    printf( "  Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( 0 );
}
Esempio n. 13
0
/*
 * Do an RSA operation to sign the message digest
 */
int rsa_pkcs1_sign( rsa_context *ctx,
                    int mode,
                    int hash_id,
                    int hashlen,
                    unsigned char *hash,
                    unsigned char *sig )
{
    int nb_pad, olen;
    unsigned char *p = sig;

    olen = ctx->len;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            switch( hash_id )
            {
                case RSA_RAW:
                    nb_pad = olen - 3 - hashlen;
                    break;

                case RSA_MD2:
                case RSA_MD4:
                case RSA_MD5:
                    nb_pad = olen - 3 - 34;
                    break;

                case RSA_SHA1:
                    nb_pad = olen - 3 - 35;
                    break;

                default:
                    return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            if( nb_pad < 8 )
                return( XYSSL_ERR_RSA_BAD_INPUT_DATA );

            *p++ = 0;
            *p++ = RSA_SIGN;
            memset( p, 0xFF, nb_pad );
            p += nb_pad;
            *p++ = 0;
            break;

        default:

            return( XYSSL_ERR_RSA_INVALID_PADDING );
    }

    switch( hash_id )
    {
        case RSA_RAW:
            memcpy( p, hash, hashlen );
            break;

        case RSA_MD2:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 2; break;

        case RSA_MD4:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 4; break;

        case RSA_MD5:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 5; break;

        case RSA_SHA1:
            memcpy( p, ASN1_HASH_SHA1, 15 );
            memcpy( p + 15, hash, 20 );
            break;

        default:
            return( XYSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, sig, sig )
            : rsa_private( ctx, sig, sig ) );
}
Esempio n. 14
0
/*
 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-SIGN function
 */
int rsa_rsassa_pss_sign( rsa_context *ctx,
                         int (*f_rng)(void *, unsigned char *, size_t),
                         void *p_rng,
                         int mode,
                         int hash_id,
                         unsigned int hashlen,
                         const unsigned char *hash,
                         unsigned char *sig )
{
    size_t olen;
    unsigned char *p = sig;
    unsigned char salt[POLARSSL_MD_MAX_SIZE];
    unsigned int slen, hlen, offset = 0;
    int ret;
    size_t msb;
    const md_info_t *md_info;
    md_context_t md_ctx;

    if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    olen = ctx->len;

    switch( hash_id )
    {
        case SIG_RSA_MD2:
        case SIG_RSA_MD4:
        case SIG_RSA_MD5:
            hashlen = 16;
            break;

        case SIG_RSA_SHA1:
            hashlen = 20;
            break;

        case SIG_RSA_SHA224:
            hashlen = 28;
            break;

        case SIG_RSA_SHA256:
            hashlen = 32;
            break;

        case SIG_RSA_SHA384:
            hashlen = 48;
            break;

        case SIG_RSA_SHA512:
            hashlen = 64;
            break;

        default:
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    md_info = md_info_from_type( ctx->hash_id );
    if( md_info == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    hlen = md_get_size( md_info );
    slen = hlen;

    if( olen < hlen + slen + 2 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    memset( sig, 0, olen );

    msb = mpi_msb( &ctx->N ) - 1;

    // Generate salt of length slen
    //
    if( ( ret = f_rng( p_rng, salt, slen ) ) != 0 )
        return( POLARSSL_ERR_RSA_RNG_FAILED + ret );

    // Note: EMSA-PSS encoding is over the length of N - 1 bits
    //
    msb = mpi_msb( &ctx->N ) - 1;
    p += olen - hlen * 2 - 2;
    *p++ = 0x01;
    memcpy( p, salt, slen );
    p += slen;

    md_init_ctx( &md_ctx, md_info );

    // Generate H = Hash( M' )
    //
    md_starts( &md_ctx );
    md_update( &md_ctx, p, 8 );
    md_update( &md_ctx, hash, hashlen );
    md_update( &md_ctx, salt, slen );
    md_finish( &md_ctx, p );

    // Compensate for boundary condition when applying mask
    //
    if( msb % 8 == 0 )
        offset = 1;

    // maskedDB: Apply dbMask to DB
    //
    mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );

    md_free_ctx( &md_ctx );

    msb = mpi_msb( &ctx->N ) - 1;
    sig[0] &= 0xFF >> ( olen * 8 - msb );

    p += hlen;
    *p++ = 0xBC;

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, sig, sig )
            : rsa_private( ctx, sig, sig ) );
}
Esempio n. 15
0
/*
 * Implementation of the PKCS#1 v2.1 RSAES-PKCS1-V1_5-DECRYPT function
 */
int rsa_rsaes_pkcs1_v15_decrypt( rsa_context *ctx,
                                 int mode, size_t *olen,
                                 const unsigned char *input,
                                 unsigned char *output,
                                 size_t output_max_len)
{
    int ret, correct = 1;
    size_t ilen, pad_count = 0;
    unsigned char *p, *q;
    unsigned char bt;
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];

    if( ctx->padding != RSA_PKCS_V15 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ilen = ctx->len;

    if( ilen < 16 || ilen > sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, input, buf )
          : rsa_private( ctx, input, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    if( *p++ != 0 )
        correct = 0;

    bt = *p++;
    if( ( bt != RSA_CRYPT && mode == RSA_PRIVATE ) ||
        ( bt != RSA_SIGN && mode == RSA_PUBLIC ) )
    {
        correct = 0;
    }

    if( bt == RSA_CRYPT )
    {
        while( *p != 0 && p < buf + ilen - 1 )
            pad_count += ( *p++ != 0 );

        correct &= ( *p == 0 && p < buf + ilen - 1 );

        q = p;

        // Also pass over all other bytes to reduce timing differences
        //
        while ( q < buf + ilen - 1 )
            pad_count += ( *q++ != 0 );

        // Prevent compiler optimization of pad_count
        //
        correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */
        p++;
    }
    else
    {
        while( *p == 0xFF && p < buf + ilen - 1 )
            pad_count += ( *p++ == 0xFF );

        correct &= ( *p == 0 && p < buf + ilen - 1 );

        q = p;

        // Also pass over all other bytes to reduce timing differences
        //
        while ( q < buf + ilen - 1 )
            pad_count += ( *q++ != 0 );

        // Prevent compiler optimization of pad_count
        //
        correct |= pad_count & 0x100000; /* Always 0 unless 1M bit keys */
        p++;
    }

    if( correct == 0 )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    if (ilen - (p - buf) > output_max_len)
        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );

    *olen = ilen - (p - buf);
    memcpy( output, p, *olen );

    return( 0 );
}
Esempio n. 16
0
/*
 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-DECRYPT function
 */
int rsa_rsaes_oaep_decrypt( rsa_context *ctx,
                            int mode,
                            const unsigned char *label, size_t label_len,
                            size_t *olen,
                            const unsigned char *input,
                            unsigned char *output,
                            size_t output_max_len )
{
    int ret;
    size_t ilen;
    unsigned char *p;
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    unsigned char lhash[POLARSSL_MD_MAX_SIZE];
    unsigned int hlen;
    const md_info_t *md_info;
    md_context_t md_ctx;

    if( ctx->padding != RSA_PKCS_V21 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ilen = ctx->len;

    if( ilen < 16 || ilen > sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, input, buf )
          : rsa_private( ctx, input, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    if( *p++ != 0 )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    md_info = md_info_from_type( ctx->hash_id );
    if( md_info == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    hlen = md_get_size( md_info );

    md_init_ctx( &md_ctx, md_info );

    // Generate lHash
    //
    md( md_info, label, label_len, lhash );

    // seed: Apply seedMask to maskedSeed
    //
    mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
               &md_ctx );

    // DB: Apply dbMask to maskedDB
    //
    mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,
               &md_ctx );

    p += hlen;
    md_free_ctx( &md_ctx );

    // Check validity
    //
    if( memcmp( lhash, p, hlen ) != 0 )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    p += hlen;

    while( *p == 0 && p < buf + ilen )
        p++;

    if( p == buf + ilen )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    if( *p++ != 0x01 )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    if (ilen - (p - buf) > output_max_len)
        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );

    *olen = ilen - (p - buf);
    memcpy( output, p, *olen );

    return( 0 );
}
Esempio n. 17
0
/*
 * Implementation of the PKCS#1 v2.1 RSAES-OAEP-ENCRYPT function
 */
int rsa_rsaes_oaep_encrypt( rsa_context *ctx,
                            int (*f_rng)(void *, unsigned char *, size_t),
                            void *p_rng,
                            int mode,
                            const unsigned char *label, size_t label_len,
                            size_t ilen,
                            const unsigned char *input,
                            unsigned char *output )
{
    size_t olen;
    int ret;
    unsigned char *p = output;
    unsigned int hlen;
    const md_info_t *md_info;
    md_context_t md_ctx;

    if( ctx->padding != RSA_PKCS_V21 || f_rng == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    md_info = md_info_from_type( ctx->hash_id );

    if( md_info == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    olen = ctx->len;
    hlen = md_get_size( md_info );

    if( olen < ilen + 2 * hlen + 2 || f_rng == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    memset( output, 0, olen );

    *p++ = 0;

    // Generate a random octet string seed
    //
    if( ( ret = f_rng( p_rng, p, hlen ) ) != 0 )
        return( POLARSSL_ERR_RSA_RNG_FAILED + ret );

    p += hlen;

    // Construct DB
    //
    md( md_info, label, label_len, p );
    p += hlen;
    p += olen - 2 * hlen - 2 - ilen;
    *p++ = 1;
    memcpy( p, input, ilen );

    md_init_ctx( &md_ctx, md_info );

    // maskedDB: Apply dbMask to DB
    //
    mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,
               &md_ctx );

    // maskedSeed: Apply seedMask to seed
    //
    mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,
               &md_ctx );

    md_free_ctx( &md_ctx );

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, output, output )
            : rsa_private( ctx, output, output ) );
}
Esempio n. 18
0
/*
 * Do an RSA operation and check the message digest
 */
int rsa_pkcs1_verify( rsa_context *ctx,
                      int mode,
                      int hash_id,
                      unsigned int hashlen,
                      const unsigned char *hash,
                      unsigned char *sig )
{
    int ret;
    size_t len, siglen;
    unsigned char *p, c;
    unsigned char buf[1024];
#if defined(POLARSSL_PKCS1_V21)
    unsigned char zeros[8];
    unsigned int hlen;
    size_t slen, msb;
    const md_info_t *md_info;
    md_context_t md_ctx;
#endif
    siglen = ctx->len;

    if( siglen < 16 || siglen > (int) sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, sig, buf )
          : rsa_private( ctx, sig, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            if( *p++ != 0 || *p++ != RSA_SIGN )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            while( *p != 0 )
            {
                if( p >= buf + siglen - 1 || *p != 0xFF )
                    return( POLARSSL_ERR_RSA_INVALID_PADDING );
                p++;
            }
            p++;

            len = siglen - (int)( p - buf );

            if( len == 34 )
            {
                c = p[13];
                p[13] = 0;

                if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
                    return( POLARSSL_ERR_RSA_VERIFY_FAILED );

                if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
                        ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
                        ( c == 5 && hash_id == SIG_RSA_MD5 ) )
                {
                    if( memcmp( p + 18, hash, 16 ) == 0 ) 
                        return( 0 );
                    else
                        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
                }
            }

            if( len == 35 && hash_id == SIG_RSA_SHA1 )
            {
                if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
                        memcmp( p + 15, hash, 20 ) == 0 )
                    return( 0 );
                else
                    return( POLARSSL_ERR_RSA_VERIFY_FAILED );
            }
            if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
                    ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
                    ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
                    ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
            {
                c = p[1] - 17;
                p[1] = 17;
                p[14] = 0;

                if( p[18] == c &&
                        memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
                        memcmp( p + 19, hash, c ) == 0 )
                    return( 0 );
                else
                    return( POLARSSL_ERR_RSA_VERIFY_FAILED );
            }

            if( len == hashlen && hash_id == SIG_RSA_RAW )
            {
                if( memcmp( p, hash, hashlen ) == 0 )
                    return( 0 );
                else
                    return( POLARSSL_ERR_RSA_VERIFY_FAILED );
            }

            break;

#if defined(POLARSSL_PKCS1_V21)
        case RSA_PKCS_V21:
            
            if( buf[siglen - 1] != 0xBC )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            switch( hash_id )
            {
                case SIG_RSA_MD2:
                case SIG_RSA_MD4:
                case SIG_RSA_MD5:
                    hashlen = 16;
                    break;

                case SIG_RSA_SHA1:
                    hashlen = 20;
                    break;

                case SIG_RSA_SHA224:
                    hashlen = 28;
                    break;

                case SIG_RSA_SHA256:
                    hashlen = 32;
                    break;

                case SIG_RSA_SHA384:
                    hashlen = 48;
                    break;

                case SIG_RSA_SHA512:
                    hashlen = 64;
                    break;

                default:
                    return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            md_info = md_info_from_type( ctx->hash_id );
            if( md_info == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
                
            hlen = md_get_size( md_info );
            slen = siglen - hlen - 1;

            memset( &md_ctx, 0, sizeof( md_context_t ) );
            memset( zeros, 0, 8 );

            md_init_ctx( &md_ctx, md_info );

            // Note: EMSA-PSS verification is over the length of N - 1 bits
            //
            msb = mpi_msb( &ctx->N ) - 1;

            // Compensate for boundary condition when applying mask
            //
            if( msb % 8 == 0 )
            {
                p++;
                siglen -= 1;
            }
            if( buf[0] >> ( 8 - siglen * 8 + msb ) )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );

            buf[0] &= 0xFF >> ( siglen * 8 - msb );

            while( *p == 0 && p < buf + siglen )
                p++;

            if( p == buf + siglen )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            if( *p++ != 0x01 )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            slen -= p - buf;

            // Generate H = Hash( M' )
            //
            md_starts( &md_ctx );
            md_update( &md_ctx, zeros, 8 );
            md_update( &md_ctx, hash, hashlen );
            md_update( &md_ctx, p, slen );
            md_finish( &md_ctx, p );

            if( memcmp( p, p + slen, hlen ) == 0 )
                return( 0 );
            else
                return( POLARSSL_ERR_RSA_VERIFY_FAILED );
            break;
#endif

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
Esempio n. 19
0
File: rsa.c Progetto: nagash91/EDC
/*
 * Do an RSA operation and check the message digest
 */
int rsa_pkcs1_verify( rsa_context *ctx,
                      int mode,
                      int hash_id,
                      int hashlen,
                      unsigned char *hash,
                      unsigned char *sig )
{
    int ret, len, siglen;
    unsigned char *p, c;
    unsigned char buf[1024];

    siglen = ctx->len;

    if( siglen < 16 || siglen > (int) sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, sig, buf )
          : rsa_private( ctx, sig, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            if( *p++ != 0 || *p++ != RSA_SIGN )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            while( *p != 0 )
            {
                if( p >= buf + siglen - 1 || *p != 0xFF )
                    return( POLARSSL_ERR_RSA_INVALID_PADDING );
                p++;
            }
            p++;
            break;

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    len = siglen - (int)( p - buf );

    if( len == 34 )
    {
        c = p[13];
        p[13] = 0;

        if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );

        if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
            ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
            ( c == 5 && hash_id == SIG_RSA_MD5 ) )
        {
            if( memcmp( p + 18, hash, 16 ) == 0 ) 
                return( 0 );
            else
                return( POLARSSL_ERR_RSA_VERIFY_FAILED );
        }
    }

    if( len == 35 && hash_id == SIG_RSA_SHA1 )
    {
        if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
            memcmp( p + 15, hash, 20 ) == 0 )
            return( 0 );
        else
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
    }
    if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
        ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
        ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
        ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
    {
    	c = p[1] - 17;
        p[1] = 17;
        p[14] = 0;

        if( p[18] == c &&
                memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
                memcmp( p + 19, hash, c ) == 0 )
            return( 0 );
        else
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
    }

    if( len == hashlen && hash_id == SIG_RSA_RAW )
    {
        if( memcmp( p, hash, hashlen ) == 0 )
            return( 0 );
        else
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
    }

    return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
Esempio n. 20
0
void rsa_generate_key(RSAPrivateKey *prv, RSAPublicKey *pub,

                    RandomState *state, unsigned int bits)

{

  MP_INT test, aux;

  unsigned int pbits, qbits;

  int ret;



  mpz_init(&prv->q);

  mpz_init(&prv->p);

  mpz_init(&prv->e);

  mpz_init(&prv->d);

  mpz_init(&prv->u);

  mpz_init(&prv->n);

  mpz_init(&test);

  mpz_init(&aux);



  /* Compute the number of bits in each prime. */

  pbits = bits / 2;

  qbits = bits - pbits;



#ifndef RSAREF

 retry0:

#endif /* !RSAREF */



  if (rsa_verbose)

    {

      fprintf(stderr, "Generating p:  ");

    }



  /* Generate random number p. */

  rsa_random_prime(&prv->p, state, pbits);



 retry:



  if (rsa_verbose)

    {

      fprintf(stderr, "Generating q:  ");

    }



  /* Generate random number q. */

  rsa_random_prime(&prv->q, state, qbits);



  /* Sort them so that p < q. */

  ret = mpz_cmp(&prv->p, &prv->q);

  if (ret == 0)

    {

      if (rsa_verbose)

       fprintf(stderr, "Generated the same prime twice!\n");

      goto retry;

    }

  if (ret > 0)

    {

      mpz_set(&aux, &prv->p);

      mpz_set(&prv->p, &prv->q);

      mpz_set(&prv->q, &aux);

    }



  /* Make sure that p and q are not too close together (I am not sure if this

     is important). */

  mpz_sub(&aux, &prv->q, &prv->p);

  mpz_div_2exp(&test, &prv->q, 10);

  if (mpz_cmp(&aux, &test) < 0)

    {

      if (rsa_verbose)

       fprintf(stderr, "The primes are too close together.\n");

      goto retry;

    }



  /* Make certain p and q are relatively prime (in case one or both were false

     positives...  Though this is quite impossible). */

  mpz_gcd(&aux, &prv->p, &prv->q);

  if (mpz_cmp_ui(&aux, 1) != 0)

    {

      if (rsa_verbose)

       fprintf(stderr, "The primes are not relatively prime!\n");

      goto retry;

    }



  /* Derive the RSA private key from the primes. */

  if (rsa_verbose)

    fprintf(stderr, "Computing the keys...\n");

  derive_rsa_keys(&prv->n, &prv->e, &prv->d, &prv->u, &prv->p, &prv->q, 5);

  prv->bits = bits;



  /* Initialize the public key with public data from the private key. */

  pub->bits = bits;

  mpz_init_set(&pub->n, &prv->n);

  mpz_init_set(&pub->e, &prv->e);



#ifndef RSAREF /* I don't want to kludge these to work with RSAREF. */

  /* Test that the key really works.  This should never fail (I think). */

  if (rsa_verbose)

    fprintf(stderr, "Testing the keys...\n");

  rsa_random_integer(&test, state, bits);

  mpz_mod(&test, &test, &pub->n); /* must be less than n. */

  rsa_private(&aux, &test, prv);

  rsa_public(&aux, &aux, pub);

  if (mpz_cmp(&aux, &test) != 0)

    {

      if (rsa_verbose)

       fprintf(stderr, "**** private+public failed to decrypt.\n");

      goto retry0;

    }



  rsa_public(&aux, &test, pub);

  rsa_private(&aux, &aux, prv);

  if (mpz_cmp(&aux, &test) != 0)

    {

      if (rsa_verbose)

       fprintf(stderr, "**** public+private failed to decrypt.\n");

      goto retry0;

    }

#endif /* !RSAREF */



  mpz_clear(&aux);

  mpz_clear(&test);



  if (rsa_verbose)

    fprintf(stderr, "Key generation complete.\n");

}
Esempio n. 21
0
/*
 * Implementation of the PKCS#1 v2.1 RSASSA-PKCS1-v1_5-VERIFY function
 */
int rsa_rsassa_pkcs1_v15_verify( rsa_context *ctx,
                                 int (*f_rng)(void *, unsigned char *, size_t),
                                 void *p_rng,
                                 int mode,
                                 int hash_id,
                                 unsigned int hashlen,
                                 const unsigned char *hash,
                                 unsigned char *sig )
{
    int ret;
    size_t len, siglen;
    unsigned char *p, c;
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];

    if( ctx->padding != RSA_PKCS_V15 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    siglen = ctx->len;

    if( siglen < 16 || siglen > sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, sig, buf )
          : rsa_private( ctx, f_rng, p_rng, sig, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    if( *p++ != 0 || *p++ != RSA_SIGN )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    while( *p != 0 )
    {
        if( p >= buf + siglen - 1 || *p != 0xFF )
            return( POLARSSL_ERR_RSA_INVALID_PADDING );
        p++;
    }
    p++;

    len = siglen - ( p - buf );

    if( len == 33 && hash_id == SIG_RSA_SHA1 )
    {
        if( memcmp( p, ASN1_HASH_SHA1_ALT, 13 ) == 0 &&
                memcmp( p + 13, hash, 20 ) == 0 )
            return( 0 );
        else
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
    }
    if( len == 34 )
    {
        c = p[13];
        p[13] = 0;

        if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );

        if( ( c == 2 && hash_id == SIG_RSA_MD2 ) ||
                ( c == 4 && hash_id == SIG_RSA_MD4 ) ||
                ( c == 5 && hash_id == SIG_RSA_MD5 ) )
        {
            if( memcmp( p + 18, hash, 16 ) == 0 )
                return( 0 );
            else
                return( POLARSSL_ERR_RSA_VERIFY_FAILED );
        }
    }

    if( len == 35 && hash_id == SIG_RSA_SHA1 )
    {
        if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
                memcmp( p + 15, hash, 20 ) == 0 )
            return( 0 );
        else
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
    }
    if( ( len == 19 + 28 && p[14] == 4 && hash_id == SIG_RSA_SHA224 ) ||
            ( len == 19 + 32 && p[14] == 1 && hash_id == SIG_RSA_SHA256 ) ||
            ( len == 19 + 48 && p[14] == 2 && hash_id == SIG_RSA_SHA384 ) ||
            ( len == 19 + 64 && p[14] == 3 && hash_id == SIG_RSA_SHA512 ) )
    {
        c = p[1] - 17;
        p[1] = 17;
        p[14] = 0;

        if( p[18] == c &&
                memcmp( p, ASN1_HASH_SHA2X, 18 ) == 0 &&
                memcmp( p + 19, hash, c ) == 0 )
            return( 0 );
        else
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
    }

    if( len == hashlen && hash_id == SIG_RSA_RAW )
    {
        if( memcmp( p, hash, hashlen ) == 0 )
            return( 0 );
        else
            return( POLARSSL_ERR_RSA_VERIFY_FAILED );
    }

    return( POLARSSL_ERR_RSA_INVALID_PADDING );
}
Esempio n. 22
0
/*
 * Perform a public RSA and check the message digest
 */
int rsa_pkcs1_verify( rsa_context   *ctx,  int alg_id,
                      unsigned char *hash, int hashlen,
                      unsigned char *sig,  int siglen )
{
    int ret, len;
    unsigned char *p, c, buf[512];

    if( siglen != ctx->len || siglen < 16 || siglen > 512 )
        return( ERR_RSA_BAD_INPUT_DATA );

    if( ( ret = rsa_public( ctx, sig, siglen, buf, &siglen ) ) != 0 )
        return( ret );

    p = buf;

    if( *p++ != 0 || *p++ != RSA_SIGN )
        return( ERR_RSA_INVALID_PADDING );

    while( *p != 0 )
    {
        if( p >= buf + siglen - 1 || *p != 0xFF )
            return( ERR_RSA_INVALID_PADDING );
        p++;
    }
    p++;

    len = siglen - (int)( p - buf );

    if( len == 34 )
    {
        c = p[13];
        p[13] = 0;

        if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
            return( ERR_RSA_VERIFY_FAILED );

        if( ( c == 2 && alg_id == RSA_MD2 ) ||
            ( c == 4 && alg_id == RSA_MD4 ) ||
            ( c == 5 && alg_id == RSA_MD5 ) )
        {
            if( memcmp( p + 18, hash, 16 ) == 0 ) 
                return( 0 );
            else
                return( ERR_RSA_VERIFY_FAILED );
        }
    }

    if( len == 35 && alg_id == RSA_SHA1 )
    {
        if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
            memcmp( p + 15, hash, 20 ) == 0 )
            return( 0 );
        else
            return( ERR_RSA_VERIFY_FAILED );
    }

    if( len == hashlen && alg_id == RSA_RAW )
    {
        if( memcmp( p, hash, hashlen ) == 0 )
            return( 0 );
        else
            return( ERR_RSA_VERIFY_FAILED );
    }

    return( ERR_RSA_INVALID_PADDING );
}
Esempio n. 23
0
int main( int argc, char *argv[] )
{
    int keysize;
    unsigned long i, j, tsc;
    unsigned char tmp[64];
#if defined(POLARSSL_ARC4_C)
    arc4_context arc4;
#endif
#if defined(POLARSSL_DES_C)
    des3_context des3;
    des_context des;
#endif
#if defined(POLARSSL_AES_C)
    aes_context aes;
#endif
#if defined(POLARSSL_CAMELLIA_C)
    camellia_context camellia;
#endif
#if defined(POLARSSL_RSA_C) && defined(POLARSSL_BIGNUM_C) &&    \
    defined(POLARSSL_GENPRIME)
    rsa_context rsa;
#endif
#if defined(POLARSSL_HAVEGE_C)
    havege_state hs;
#endif
#if defined(POLARSSL_CTR_DRBG_C)
    ctr_drbg_context    ctr_drbg;
#endif
    ((void) argc);
    ((void) argv);

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

    printf( "\n" );

#if defined(POLARSSL_MD4_C)
    printf( HEADER_FORMAT, "MD4" );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        md4( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        md4( buf, BUFSIZE, tmp );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_MD5_C)
    printf( HEADER_FORMAT, "MD5" );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        md5( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        md5( buf, BUFSIZE, tmp );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_SHA1_C)
    printf( HEADER_FORMAT, "SHA-1" );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        sha1( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha1( buf, BUFSIZE, tmp );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_SHA2_C)
    printf( HEADER_FORMAT, "SHA-256" );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        sha2( buf, BUFSIZE, tmp, 0 );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha2( buf, BUFSIZE, tmp, 0 );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_SHA4_C)
    printf( HEADER_FORMAT, "SHA-512" );
    fflush( stdout );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        sha4( buf, BUFSIZE, tmp, 0 );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha4( buf, BUFSIZE, tmp, 0 );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_ARC4_C)
    printf( HEADER_FORMAT, "ARC4" );
    fflush( stdout );

    arc4_setup( &arc4, tmp, 32 );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        arc4_crypt( &arc4, BUFSIZE, buf, buf );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        arc4_crypt( &arc4, BUFSIZE, buf, buf );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_DES_C)
    printf( HEADER_FORMAT, "3DES" );
    fflush( stdout );

    des3_set3key_enc( &des3, tmp );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        des3_crypt_cbc( &des3, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        des3_crypt_cbc( &des3, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    printf( HEADER_FORMAT, "DES" );
    fflush( stdout );

    des_setkey_enc( &des, tmp );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        des_crypt_cbc( &des, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        des_crypt_cbc( &des, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_AES_C)
    for( keysize = 128; keysize <= 256; keysize += 64 )
    {
        printf( "  AES-%d         :  ", keysize );
        fflush( stdout );

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

        set_alarm( 1 );

        for( i = 1; ! alarmed; i++ )
            aes_crypt_cbc( &aes, AES_ENCRYPT, BUFSIZE, tmp, buf, buf );

        tsc = hardclock();
        for( j = 0; j < 4096; j++ )
            aes_crypt_cbc( &aes, AES_ENCRYPT, BUFSIZE, tmp, buf, buf );

        printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                        ( hardclock() - tsc ) / ( j * BUFSIZE ) );
    }
#endif

#if defined(POLARSSL_CAMELLIA_C)
    for( keysize = 128; keysize <= 256; keysize += 64 )
    {
        printf( "  CAMELLIA-%d    :  ", keysize );
        fflush( stdout );

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

        set_alarm( 1 );

        for( i = 1; ! alarmed; i++ )
            camellia_crypt_cbc( &camellia, CAMELLIA_ENCRYPT, BUFSIZE, tmp, buf, buf );

        tsc = hardclock();
        for( j = 0; j < 4096; j++ )
            camellia_crypt_cbc( &camellia, CAMELLIA_ENCRYPT, BUFSIZE, tmp, buf, buf );

        printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                        ( hardclock() - tsc ) / ( j * BUFSIZE ) );
    }
#endif

#if defined(POLARSSL_HAVEGE_C)
    printf( HEADER_FORMAT, "HAVEGE" );
    fflush( stdout );

    havege_init( &hs );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        havege_random( &hs, buf, BUFSIZE );

    tsc = hardclock();
    for( j = 1; j < 1024; j++ )
        havege_random( &hs, buf, BUFSIZE );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_CTR_DRBG_C)
    printf( HEADER_FORMAT, "CTR_DRBG (NOPR)" );
    fflush( stdout );

    if( ctr_drbg_init( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
        exit(1);

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        if( ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
            exit(1);

    tsc = hardclock();
    for( j = 1; j < 1024; j++ )
        if( ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
            exit(1);

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    printf( HEADER_FORMAT, "CTR_DRBG (PR)" );
    fflush( stdout );

    if( ctr_drbg_init( &ctr_drbg, myrand, NULL, NULL, 0 ) != 0 )
        exit(1);

    ctr_drbg_set_prediction_resistance( &ctr_drbg, CTR_DRBG_PR_ON );

    set_alarm( 1 );
    for( i = 1; ! alarmed; i++ )
        if( ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
            exit(1);

    tsc = hardclock();
    for( j = 1; j < 1024; j++ )
        if( ctr_drbg_random( &ctr_drbg, buf, BUFSIZE ) != 0 )
            exit(1);

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_RSA_C) && defined(POLARSSL_BIGNUM_C) &&    \
    defined(POLARSSL_GENPRIME)
    rsa_init( &rsa, RSA_PKCS_V15, 0 );
    rsa_gen_key( &rsa, myrand, NULL, 1024, 65537 );

    printf( HEADER_FORMAT, "RSA-1024" );
    fflush( stdout );
    set_alarm( 3 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, buf );
    }

    printf( "%9lu  public/s\n", i / 3 );

    printf( HEADER_FORMAT, "RSA-1024" );
    fflush( stdout );
    set_alarm( 3 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, buf );
    }

    printf( "%9lu private/s\n", i / 3 );

    rsa_free( &rsa );

    rsa_init( &rsa, RSA_PKCS_V15, 0 );
    rsa_gen_key( &rsa, myrand, NULL, 2048, 65537 );

    printf( HEADER_FORMAT, "RSA-2048" );
    fflush( stdout );
    set_alarm( 3 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, buf );
    }

    printf( "%9lu  public/s\n", i / 3 );

    printf( HEADER_FORMAT, "RSA-2048" );
    fflush( stdout );
    set_alarm( 3 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, buf );
    }

    printf( "%9lu private/s\n", i / 3 );

    rsa_free( &rsa );

    rsa_init( &rsa, RSA_PKCS_V15, 0 );
    rsa_gen_key( &rsa, myrand, NULL, 4096, 65537 );

    printf( HEADER_FORMAT, "RSA-4096" );
    fflush( stdout );
    set_alarm( 3 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, buf );
    }

    printf( "%9lu  public/s\n", i / 3 );

    printf( HEADER_FORMAT, "RSA-4096" );
    fflush( stdout );
    set_alarm( 3 );

    for( i = 1; ! alarmed; i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, buf );
    }

    printf( "%9lu private/s\n", i / 3 );

    rsa_free( &rsa );
#endif

    printf( "\n" );

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

    return( 0 );
}
Esempio n. 24
0
/*
 * Implementation of the PKCS#1 v2.1 RSASSA-PSS-VERIFY function
 */
int rsa_rsassa_pss_verify( rsa_context *ctx,
                           int mode,
                           int hash_id,
                           unsigned int hashlen,
                           const unsigned char *hash,
                           unsigned char *sig )
{
    int ret;
    size_t siglen;
    unsigned char *p;
    unsigned char buf[POLARSSL_MPI_MAX_SIZE];
    unsigned char result[POLARSSL_MD_MAX_SIZE];
    unsigned char zeros[8];
    unsigned int hlen;
    size_t slen, msb;
    const md_info_t *md_info;
    md_context_t md_ctx;

    if( ctx->padding != RSA_PKCS_V21 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    siglen = ctx->len;

    if( siglen < 16 || siglen > sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, sig, buf )
          : rsa_private( ctx, sig, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    if( buf[siglen - 1] != 0xBC )
        return( POLARSSL_ERR_RSA_INVALID_PADDING );

    switch( hash_id )
    {
        case SIG_RSA_MD2:
        case SIG_RSA_MD4:
        case SIG_RSA_MD5:
            hashlen = 16;
            break;

        case SIG_RSA_SHA1:
            hashlen = 20;
            break;

        case SIG_RSA_SHA224:
            hashlen = 28;
            break;

        case SIG_RSA_SHA256:
            hashlen = 32;
            break;

        case SIG_RSA_SHA384:
            hashlen = 48;
            break;

        case SIG_RSA_SHA512:
            hashlen = 64;
            break;

        default:
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    md_info = md_info_from_type( ctx->hash_id );
    if( md_info == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    hlen = md_get_size( md_info );
    slen = siglen - hlen - 1;

    memset( zeros, 0, 8 );

    // Note: EMSA-PSS verification is over the length of N - 1 bits
    //
    msb = mpi_msb( &ctx->N ) - 1;

    // Compensate for boundary condition when applying mask
    //
    if( msb % 8 == 0 )
    {
        p++;
        siglen -= 1;
    }
    if( buf[0] >> ( 8 - siglen * 8 + msb ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    md_init_ctx( &md_ctx, md_info );

    mgf_mask( p, siglen - hlen - 1, p + siglen - hlen - 1, hlen, &md_ctx );

    buf[0] &= 0xFF >> ( siglen * 8 - msb );

    while( *p == 0 && p < buf + siglen )
        p++;

    if( p == buf + siglen ||
        *p++ != 0x01 )
    {
        md_free_ctx( &md_ctx );
        return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    slen -= p - buf;

    // Generate H = Hash( M' )
    //
    md_starts( &md_ctx );
    md_update( &md_ctx, zeros, 8 );
    md_update( &md_ctx, hash, hashlen );
    md_update( &md_ctx, p, slen );
    md_finish( &md_ctx, result );

    md_free_ctx( &md_ctx );

    if( memcmp( p + slen, result, hlen ) == 0 )
        return( 0 );
    else
        return( POLARSSL_ERR_RSA_VERIFY_FAILED );
}
Esempio n. 25
0
/*
 * Add the message padding, then do an RSA operation
 */
int rsa_pkcs1_encrypt( rsa_context *ctx,
                       int (*f_rng)(void *),
                       void *p_rng,
                       int mode, size_t ilen,
                       const unsigned char *input,
                       unsigned char *output )
{
    size_t nb_pad, olen;
    unsigned char *p = output;
#if defined(POLARSSL_PKCS1_V21)
    unsigned int i, hlen;
    const md_info_t *md_info;
    md_context_t md_ctx;
#endif

    olen = ctx->len;

    if( f_rng == NULL )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            if( olen < ilen + 11 )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            nb_pad = olen - 3 - ilen;

            *p++ = 0;
            *p++ = RSA_CRYPT;

            while( nb_pad-- > 0 )
            {
                int rng_dl = 100;

                do {
                    *p = (unsigned char) f_rng( p_rng );
                } while( *p == 0 && --rng_dl );

                // Check if RNG failed to generate data
                //
                if( rng_dl == 0 )
                    return POLARSSL_ERR_RSA_RNG_FAILED;

                p++;
            }
            *p++ = 0;
            memcpy( p, input, ilen );
            break;
        
#if defined(POLARSSL_PKCS1_V21)
        case RSA_PKCS_V21:

            md_info = md_info_from_type( ctx->hash_id );
            if( md_info == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            hlen = md_get_size( md_info );

            if( olen < ilen + 2 * hlen + 2 || f_rng == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            memset( output, 0, olen );
            memset( &md_ctx, 0, sizeof( md_context_t ) );

            md_init_ctx( &md_ctx, md_info );

            *p++ = 0;

            // Generate a random octet string seed
            //
            for( i = 0; i < hlen; ++i )
                *p++ = (unsigned char) f_rng( p_rng ); 

            // Construct DB
            //
            md( md_info, p, 0, p );
            p += hlen;
            p += olen - 2 * hlen - 2 - ilen;
            *p++ = 1;
            memcpy( p, input, ilen ); 

            // maskedDB: Apply dbMask to DB
            //
            mgf_mask( output + hlen + 1, olen - hlen - 1, output + 1, hlen,  
                       &md_ctx );

            // maskedSeed: Apply seedMask to seed
            //
            mgf_mask( output + 1, hlen, output + hlen + 1, olen - hlen - 1,  
                       &md_ctx );
            break;
#endif

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, output, output )
            : rsa_private( ctx, output, output ) );
}
Esempio n. 26
0
File: rsa.c Progetto: ahawad/opensgx
/*
 * Do an RSA operation to sign the message digest
 */
int rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
                               int (*f_rng)(void *, unsigned char *, size_t),
                               void *p_rng,
                               int mode,
                               md_type_t md_alg,
                               unsigned int hashlen,
                               const unsigned char *hash,
                               unsigned char *sig )
{
    size_t nb_pad, olen, oid_size = 0;
    unsigned char *p = sig;
    const char *oid;

    if( mode == RSA_PRIVATE && ctx->padding != RSA_PKCS_V15 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    olen = ctx->len;
    nb_pad = olen - 3;

    if( md_alg != POLARSSL_MD_NONE )
    {
        const md_info_t *md_info = md_info_from_type( md_alg );
        if( md_info == NULL )
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

        if( oid_get_oid_by_md( md_alg, &oid, &oid_size ) != 0 )
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

        nb_pad -= 10 + oid_size;

        hashlen = md_get_size( md_info );
    }

    nb_pad -= hashlen;

    if( ( nb_pad < 8 ) || ( nb_pad > olen ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    *p++ = 0;
    *p++ = RSA_SIGN;
    memset( p, 0xFF, nb_pad );
    p += nb_pad;
    *p++ = 0;

    if( md_alg == POLARSSL_MD_NONE )
    {
        memcpy( p, hash, hashlen );
    }
    else
    {
        /*
         * DigestInfo ::= SEQUENCE {
         *   digestAlgorithm DigestAlgorithmIdentifier,
         *   digest Digest }
         *
         * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
         *
         * Digest ::= OCTET STRING
         */
        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
        *p++ = (unsigned char) ( 0x08 + oid_size + hashlen );
        *p++ = ASN1_SEQUENCE | ASN1_CONSTRUCTED;
        *p++ = (unsigned char) ( 0x04 + oid_size );
        *p++ = ASN1_OID;
        *p++ = oid_size & 0xFF;
        memcpy( p, oid, oid_size );
        p += oid_size;
        *p++ = ASN1_NULL;
        *p++ = 0x00;
        *p++ = ASN1_OCTET_STRING;
        *p++ = hashlen;
        memcpy( p, hash, hashlen );
    }

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, sig, sig )
            : rsa_private( ctx, f_rng, p_rng, sig, sig ) );
}
Esempio n. 27
0
File: rsa.c Progetto: nagash91/EDC
/*
 * Do an RSA operation to sign the message digest
 */
int rsa_pkcs1_sign( rsa_context *ctx,
                    int mode,
                    int hash_id,
                    int hashlen,
                    unsigned char *hash,
                    unsigned char *sig )
{
    int nb_pad, olen;
    unsigned char *p = sig;

    olen = ctx->len;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            switch( hash_id )
            {
                case SIG_RSA_RAW:
                    nb_pad = olen - 3 - hashlen;
                    break;

                case SIG_RSA_MD2:
                case SIG_RSA_MD4:
                case SIG_RSA_MD5:
                    nb_pad = olen - 3 - 34;
                    break;

                case SIG_RSA_SHA1:
                    nb_pad = olen - 3 - 35;
                    break;

                case SIG_RSA_SHA224:
                    nb_pad = olen - 3 - 47;
                    break;

                case SIG_RSA_SHA256:
                    nb_pad = olen - 3 - 51;
                    break;

                case SIG_RSA_SHA384:
                    nb_pad = olen - 3 - 67;
                    break;

                case SIG_RSA_SHA512:
                    nb_pad = olen - 3 - 83;
                    break;


                default:
                    return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            if( nb_pad < 8 )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            *p++ = 0;
            *p++ = RSA_SIGN;
            memset( p, 0xFF, nb_pad );
            p += nb_pad;
            *p++ = 0;
            break;

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    switch( hash_id )
    {
        case SIG_RSA_RAW:
            memcpy( p, hash, hashlen );
            break;

        case SIG_RSA_MD2:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 2; break;

        case SIG_RSA_MD4:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 4; break;

        case SIG_RSA_MD5:
            memcpy( p, ASN1_HASH_MDX, 18 );
            memcpy( p + 18, hash, 16 );
            p[13] = 5; break;

        case SIG_RSA_SHA1:
            memcpy( p, ASN1_HASH_SHA1, 15 );
            memcpy( p + 15, hash, 20 );
            break;

        case SIG_RSA_SHA224:
            memcpy( p, ASN1_HASH_SHA2X, 19 );
            memcpy( p + 19, hash, 28 );
            p[1] += 28; p[14] = 4; p[18] += 28; break;

        case SIG_RSA_SHA256:
            memcpy( p, ASN1_HASH_SHA2X, 19 );
            memcpy( p + 19, hash, 32 );
            p[1] += 32; p[14] = 1; p[18] += 32; break;

        case SIG_RSA_SHA384:
            memcpy( p, ASN1_HASH_SHA2X, 19 );
            memcpy( p + 19, hash, 48 );
            p[1] += 48; p[14] = 2; p[18] += 48; break;

        case SIG_RSA_SHA512:
            memcpy( p, ASN1_HASH_SHA2X, 19 );
            memcpy( p + 19, hash, 64 );
            p[1] += 64; p[14] = 3; p[18] += 64; break;

        default:
            return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, sig, sig )
            : rsa_private( ctx, sig, sig ) );
}
Esempio n. 28
0
/*
 * Do an RSA operation, then remove the message padding
 */
int rsa_pkcs1_decrypt( rsa_context *ctx,
                       int mode, size_t *olen,
                       const unsigned char *input,
                       unsigned char *output,
                       size_t output_max_len)
{
    int ret;
    size_t ilen;
    unsigned char *p;
    unsigned char buf[1024];
#if defined(POLARSSL_PKCS1_V21)
    unsigned char lhash[POLARSSL_MD_MAX_SIZE];
    unsigned int hlen;
    const md_info_t *md_info;
    md_context_t md_ctx;
#endif

    ilen = ctx->len;

    if( ilen < 16 || ilen > (int) sizeof( buf ) )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    ret = ( mode == RSA_PUBLIC )
          ? rsa_public(  ctx, input, buf )
          : rsa_private( ctx, input, buf );

    if( ret != 0 )
        return( ret );

    p = buf;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            if( *p++ != 0 || *p++ != RSA_CRYPT )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            while( *p != 0 )
            {
                if( p >= buf + ilen - 1 )
                    return( POLARSSL_ERR_RSA_INVALID_PADDING );
                p++;
            }
            p++;
            break;

#if defined(POLARSSL_PKCS1_V21)
        case RSA_PKCS_V21:
            
            if( *p++ != 0 )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            md_info = md_info_from_type( ctx->hash_id );
            if( md_info == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
                
            hlen = md_get_size( md_info );
            memset( &md_ctx, 0, sizeof( md_context_t ) );

            md_init_ctx( &md_ctx, md_info );
            
            // Generate lHash
            //
            md( md_info, lhash, 0, lhash );

            // seed: Apply seedMask to maskedSeed
            //
            mgf_mask( buf + 1, hlen, buf + hlen + 1, ilen - hlen - 1,
                       &md_ctx );

            // DB: Apply dbMask to maskedDB
            //
            mgf_mask( buf + hlen + 1, ilen - hlen - 1, buf + 1, hlen,  
                       &md_ctx );

            p += hlen;

            // Check validity
            //
            if( memcmp( lhash, p, hlen ) != 0 )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            p += hlen;

            while( *p == 0 && p < buf + ilen )
                p++;

            if( p == buf + ilen )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            if( *p++ != 0x01 )
                return( POLARSSL_ERR_RSA_INVALID_PADDING );

            break;
#endif

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    if (ilen - (int)(p - buf) > output_max_len)
        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );

    *olen = ilen - (int)(p - buf);
    memcpy( output, p, *olen );

    return( 0 );
}
int main( void )
{
    int keysize;
    unsigned long i, j, tsc;
    unsigned char tmp[64];
    t_cpu_time timer;

    /* Keep compiler happy */
    UNUSED(keysize);
    UNUSED(i);
    UNUSED(j);
    UNUSED(tsc);
    UNUSED(tmp[0]);
    UNUSED(timer);


    // USART options.
    static usart_serial_options_t USART_SERIAL_OPTIONS =
    {
            .baudrate     = USART_SERIAL_EXAMPLE_BAUDRATE,
            .charlength   = USART_SERIAL_CHAR_LENGTH,
            .paritytype   = USART_SERIAL_PARITY,
            .stopbits     = USART_SERIAL_STOP_BIT
    };

    sysclk_init();

    // Initialize the board.
    // The board-specific conf_board.h file contains the configuration of the board
    // initialization.
    board_init();

    // Initialize Serial Interface using Stdio Library
    stdio_serial_init(USART_SERIAL_EXAMPLE,&USART_SERIAL_OPTIONS);

    printf( "Start Benchmark\n");

#if defined(POLARSSL_ARC4_C)
    arc4_context arc4;
#endif
#if defined(POLARSSL_DES_C)
    des3_context des3;
    des_context des;
#endif
#if defined(POLARSSL_AES_C)
    aes_context aes;
#endif
#if defined(POLARSSL_CAMELLIA_C)
    camellia_context camellia;
#endif
#if defined(POLARSSL_RSA_C)
    rsa_context rsa;
#endif

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

    printf( "\n" );

#if defined(POLARSSL_MD4_C)
    printf( "  MD4       :  " );
    fflush( stdout );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        md4( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        md4( buf, BUFSIZE, tmp );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_MD5_C)
    printf( "  MD5       :  " );
    fflush( stdout );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        md5( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        md5( buf, BUFSIZE, tmp );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_SHA1_C)
    printf( "  SHA-1     :  " );
    fflush( stdout );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        sha1( buf, BUFSIZE, tmp );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha1( buf, BUFSIZE, tmp );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_SHA2_C)
    printf( "  SHA-256   :  " );
    fflush( stdout );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        sha2( buf, BUFSIZE, tmp, 0 );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha2( buf, BUFSIZE, tmp, 0 );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_SHA4_C)
    printf( "  SHA-512   :  " );
    fflush( stdout );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        sha4( buf, BUFSIZE, tmp, 0 );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        sha4( buf, BUFSIZE, tmp, 0 );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_ARC4_C)
    printf( "  ARC4      :  " );
    fflush( stdout );

    arc4_setup( &arc4, tmp, 32 );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        arc4_crypt( &arc4, BUFSIZE, buf, buf );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        arc4_crypt( &arc4, BUFSIZE, buf, buf );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_DES_C)
    printf( "  3DES      :  " );
    fflush( stdout );

    des3_set3key_enc( &des3, tmp );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        des3_crypt_cbc( &des3, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        des3_crypt_cbc( &des3, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );

    printf( "  DES       :  " );
    fflush( stdout );

    des_setkey_enc( &des, tmp );

    cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);
    for( i = 1; !cpu_is_timeout(&timer); i++ )
        des_crypt_cbc( &des, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    tsc = hardclock();
    for( j = 0; j < 1024; j++ )
        des_crypt_cbc( &des, DES_ENCRYPT, BUFSIZE, tmp, buf, buf );

    printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                    ( hardclock() - tsc ) / ( j * BUFSIZE ) );
#endif

#if defined(POLARSSL_AES_C)
    for( keysize = 128; keysize <= 256; keysize += 64 )
    {
        printf( "  AES-%d   :  ", keysize );
        fflush( stdout );

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

        cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);

        for( i = 1; !cpu_is_timeout(&timer); i++ )
            aes_crypt_cbc( &aes, AES_ENCRYPT, BUFSIZE, tmp, buf, buf );

        tsc = hardclock();
        for( j = 0; j < 4096; j++ )
            aes_crypt_cbc( &aes, AES_ENCRYPT, BUFSIZE, tmp, buf, buf );

        printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                        ( hardclock() - tsc ) / ( j * BUFSIZE ) );
    }
#endif

#if defined(POLARSSL_CAMELLIA_C)
    for( keysize = 128; keysize <= 256; keysize += 64 )
    {
        printf( "  CAMELLIA-%d   :  ", keysize );
        fflush( stdout );

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

        cpu_set_timeout(cpu_ms_2_cy(1000, CPU_HZ),&timer);

        for( i = 1; !cpu_is_timeout(&timer); i++ )
            camellia_crypt_cbc( &camellia, CAMELLIA_ENCRYPT, BUFSIZE, tmp, buf, buf );

        tsc = hardclock();
        for( j = 0; j < 4096; j++ )
            camellia_crypt_cbc( &camellia, CAMELLIA_ENCRYPT, BUFSIZE, tmp, buf, buf );

        printf( "%9lu Kb/s,  %9lu cycles/byte\n", i * BUFSIZE / 1024,
                        ( hardclock() - tsc ) / ( j * BUFSIZE ) );
    }
#endif

#if defined(POLARSSL_RSA_C)
    rsa_init( &rsa, RSA_PKCS_V15, 0 );
    rsa_gen_key( &rsa, myrand, NULL, 1024, 65537 );

    printf( "  RSA-1024  :  " );
    fflush( stdout );
    cpu_set_timeout(cpu_ms_2_cy(3000, CPU_HZ),&timer);

    for( i = 1; !cpu_is_timeout(&timer); i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, buf );
    }

    printf( "%9lu  public/s\n", i / 3 );

    printf( "  RSA-1024  :  " );
    fflush( stdout );
    cpu_set_timeout(cpu_ms_2_cy(3000, CPU_HZ),&timer);

    for( i = 1; !cpu_is_timeout(&timer); i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, buf );
    }

    printf( "%9lu private/s\n", i / 3 );

    rsa_free( &rsa );

    rsa_init( &rsa, RSA_PKCS_V15, 0 );
    rsa_gen_key( &rsa, myrand, NULL, 2048, 65537 );

    printf( "  RSA-2048  :  " );
    fflush( stdout );
    cpu_set_timeout(cpu_ms_2_cy(3000, CPU_HZ),&timer);

    for( i = 1; !cpu_is_timeout(&timer); i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, buf );
    }

    printf( "%9lu  public/s\n", i / 3 );

    printf( "  RSA-2048  :  " );
    fflush( stdout );
    cpu_set_timeout(cpu_ms_2_cy(3000, CPU_HZ),&timer);

    for( i = 1; ! cpu_is_timeout(&timer); i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, buf );
    }

    printf( "%9lu private/s\n", i / 3 );

    rsa_free( &rsa );

    rsa_init( &rsa, RSA_PKCS_V15, 0 );
    rsa_gen_key( &rsa, myrand, NULL, 4096, 65537 );

    printf( "  RSA-4096  :  " );
    fflush( stdout );
    cpu_set_timeout(cpu_ms_2_cy(3000, CPU_HZ),&timer);

    for( i = 1; !cpu_is_timeout(&timer); i++ )
    {
        buf[0] = 0;
        rsa_public( &rsa, buf, buf );
    }

    printf( "%9lu  public/s\n", i / 3 );

    printf( "  RSA-4096  :  " );
    fflush( stdout );
    cpu_set_timeout(cpu_ms_2_cy(3000, CPU_HZ),&timer);

    for( i = 1; ! cpu_is_timeout(&timer); i++ )
    {
        buf[0] = 0;
        rsa_private( &rsa, buf, buf );
    }

    printf( "%9lu private/s\n", i / 3 );

    rsa_free( &rsa );
#endif

    printf( "\n" );

#ifdef WIN32
    printf( "  Press Enter to exit this program.\n" );
    fflush( stdout ); getchar();
#endif

    return( 0 );
}
Esempio n. 30
0
/*
 * Do an RSA operation to sign the message digest
 */
int rsa_pkcs1_sign( rsa_context *ctx,
                    int (*f_rng)(void *),
                    void *p_rng,
                    int mode,
                    int hash_id,
                    unsigned int hashlen,
                    const unsigned char *hash,
                    unsigned char *sig )
{
    size_t nb_pad, olen;
    unsigned char *p = sig;
#if defined(POLARSSL_PKCS1_V21)
    unsigned char salt[POLARSSL_MD_MAX_SIZE];
    unsigned int i, slen, hlen, offset = 0;
    size_t msb;
    const md_info_t *md_info;
    md_context_t md_ctx;
#else
    (void) f_rng;
    (void) p_rng;
#endif

    olen = ctx->len;

    switch( ctx->padding )
    {
        case RSA_PKCS_V15:

            switch( hash_id )
            {
                case SIG_RSA_RAW:
                    nb_pad = olen - 3 - hashlen;
                    break;

                case SIG_RSA_MD2:
                case SIG_RSA_MD4:
                case SIG_RSA_MD5:
                    nb_pad = olen - 3 - 34;
                    break;

                case SIG_RSA_SHA1:
                    nb_pad = olen - 3 - 35;
                    break;

                case SIG_RSA_SHA224:
                    nb_pad = olen - 3 - 47;
                    break;

                case SIG_RSA_SHA256:
                    nb_pad = olen - 3 - 51;
                    break;

                case SIG_RSA_SHA384:
                    nb_pad = olen - 3 - 67;
                    break;

                case SIG_RSA_SHA512:
                    nb_pad = olen - 3 - 83;
                    break;


                default:
                    return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            if( nb_pad < 8 )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            *p++ = 0;
            *p++ = RSA_SIGN;
            memset( p, 0xFF, nb_pad );
            p += nb_pad;
            *p++ = 0;

            switch( hash_id )
            {
                case SIG_RSA_RAW:
                    memcpy( p, hash, hashlen );
                    break;

                case SIG_RSA_MD2:
                    memcpy( p, ASN1_HASH_MDX, 18 );
                    memcpy( p + 18, hash, 16 );
                    p[13] = 2; break;

                case SIG_RSA_MD4:
                    memcpy( p, ASN1_HASH_MDX, 18 );
                    memcpy( p + 18, hash, 16 );
                    p[13] = 4; break;

                case SIG_RSA_MD5:
                    memcpy( p, ASN1_HASH_MDX, 18 );
                    memcpy( p + 18, hash, 16 );
                    p[13] = 5; break;

                case SIG_RSA_SHA1:
                    memcpy( p, ASN1_HASH_SHA1, 15 );
                    memcpy( p + 15, hash, 20 );
                    break;

                case SIG_RSA_SHA224:
                    memcpy( p, ASN1_HASH_SHA2X, 19 );
                    memcpy( p + 19, hash, 28 );
                    p[1] += 28; p[14] = 4; p[18] += 28; break;

                case SIG_RSA_SHA256:
                    memcpy( p, ASN1_HASH_SHA2X, 19 );
                    memcpy( p + 19, hash, 32 );
                    p[1] += 32; p[14] = 1; p[18] += 32; break;

                case SIG_RSA_SHA384:
                    memcpy( p, ASN1_HASH_SHA2X, 19 );
                    memcpy( p + 19, hash, 48 );
                    p[1] += 48; p[14] = 2; p[18] += 48; break;

                case SIG_RSA_SHA512:
                    memcpy( p, ASN1_HASH_SHA2X, 19 );
                    memcpy( p + 19, hash, 64 );
                    p[1] += 64; p[14] = 3; p[18] += 64; break;

                default:
                    return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            break;

#if defined(POLARSSL_PKCS1_V21)
        case RSA_PKCS_V21:

            if( f_rng == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

            switch( hash_id )
            {
                case SIG_RSA_MD2:
                case SIG_RSA_MD4:
                case SIG_RSA_MD5:
                    hashlen = 16;
                    break;

                case SIG_RSA_SHA1:
                    hashlen = 20;
                    break;

                case SIG_RSA_SHA224:
                    hashlen = 28;
                    break;

                case SIG_RSA_SHA256:
                    hashlen = 32;
                    break;

                case SIG_RSA_SHA384:
                    hashlen = 48;
                    break;

                case SIG_RSA_SHA512:
                    hashlen = 64;
                    break;

                default:
                    return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
            }

            md_info = md_info_from_type( ctx->hash_id );
            if( md_info == NULL )
                return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
                
            hlen = md_get_size( md_info );
            slen = hlen;

            memset( sig, 0, olen );
            memset( &md_ctx, 0, sizeof( md_context_t ) );

            md_init_ctx( &md_ctx, md_info );

            msb = mpi_msb( &ctx->N ) - 1;

            // Generate salt of length slen
            //
            for( i = 0; i < slen; ++i )
                salt[i] = (unsigned char) f_rng( p_rng ); 

            // Note: EMSA-PSS encoding is over the length of N - 1 bits
            //
            msb = mpi_msb( &ctx->N ) - 1;
            p += olen - hlen * 2 - 2;
            *p++ = 0x01;
            memcpy( p, salt, slen );
            p += slen;

            // Generate H = Hash( M' )
            //
            md_starts( &md_ctx );
            md_update( &md_ctx, p, 8 );
            md_update( &md_ctx, hash, hashlen );
            md_update( &md_ctx, salt, slen );
            md_finish( &md_ctx, p );

            // Compensate for boundary condition when applying mask
            //
            if( msb % 8 == 0 )
                offset = 1;

            // maskedDB: Apply dbMask to DB
            //
            mgf_mask( sig + offset, olen - hlen - 1 - offset, p, hlen, &md_ctx );

            msb = mpi_msb( &ctx->N ) - 1;
            sig[0] &= 0xFF >> ( olen * 8 - msb );

            p += hlen;
            *p++ = 0xBC;
            break;
#endif

        default:

            return( POLARSSL_ERR_RSA_INVALID_PADDING );
    }

    return( ( mode == RSA_PUBLIC )
            ? rsa_public(  ctx, sig, sig )
            : rsa_private( ctx, sig, sig ) );
}