/*
 *  The RSA public-key cryptosystem
 *
 *  Copyright (C) 2006-2010, Brainspark B.V.
 *
 *  This file is part of PolarSSL (http://www.polarssl.org)
 *  Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
 *
 *  All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
/*
 *  RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
 *
 *  http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
 *  http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
 */

#include "polarssl/config.h"

#if defined(POLARSSL_RSA_C)

#include "polarssl/rsa.h"
#include "polarssl/md.h"

#include <stdlib.h>
#include <stdio.h>

/*
 * Initialize an RSA context
 */
void rsa_init( rsa_context *ctx,
               int padding,
               int hash_id )
{
    memset( ctx, 0, sizeof( rsa_context ) );

    ctx->padding = padding;
    ctx->hash_id = hash_id;
}

#if defined(POLARSSL_GENPRIME)

/*
 * Generate an RSA keypair
 */
int rsa_gen_key( rsa_context *ctx,
        int (*f_rng)(void *),
        void *p_rng,
        unsigned int nbits, int exponent )
{
    int ret;
    mpi P1, Q1, H, G;

    if( f_rng == NULL || nbits < 128 || exponent < 3 )
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );

    mpi_init( &P1 ); mpi_init( &Q1 ); mpi_init( &H ); mpi_init( &G );

    /*
     * find primes P and Q with Q < P so that:
     * GCD( E, (P-1)*(Q-1) ) == 1
     */
    MPI_CHK( mpi_lset( &ctx->E, exponent ) );

    do
    {
        MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0, 
                                f_rng, p_rng ) );

        MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
                                f_rng, p_rng ) );

        if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
            mpi_swap( &ctx->P, &ctx->Q );

        if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
            continue;

        MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
        if( mpi_msb( &ctx->N ) != nbits )
            continue;

        MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
        MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
        MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
        MPI_CHK( mpi_gcd( &G, &ctx->E, &H  ) );
    }
    while( mpi_cmp_int( &G, 1 ) != 0 );

    /*
     * D  = E^-1 mod ((P-1)*(Q-1))
     * DP = D mod (P - 1)
     * DQ = D mod (Q - 1)
     * QP = Q^-1 mod P
     */
    MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H  ) );
    MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
    MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
    MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );

    ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;

cleanup:

    mpi_free( &P1 ); mpi_free( &Q1 ); mpi_free( &H ); mpi_free( &G );

    if( ret != 0 )
    {
        rsa_free( ctx );
        return( POLARSSL_ERR_RSA_KEY_GEN_FAILED + ret );
    }

    return( 0 );   
}

#endif

/*
 * Check a public RSA key
 */
int rsa_check_pubkey( const rsa_context *ctx )
{
    if( !ctx->N.p || !ctx->E.p )
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );

    if( ( ctx->N.p[0] & 1 ) == 0 || 
        ( ctx->E.p[0] & 1 ) == 0 )
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );

    if( mpi_msb( &ctx->N ) < 128 ||
        mpi_msb( &ctx->N ) > 4096 )
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );

    if( mpi_msb( &ctx->E ) < 2 ||
        mpi_msb( &ctx->E ) > 64 )
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );

    return( 0 );
}

/*
 * Check a private RSA key
 */
int rsa_check_privkey( const rsa_context *ctx )
{
    int ret;
    mpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2;

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

    if( !ctx->P.p || !ctx->Q.p || !ctx->D.p )
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );

    mpi_init( &PQ ); mpi_init( &DE ); mpi_init( &P1 ); mpi_init( &Q1 );
    mpi_init( &H  ); mpi_init( &I  ); mpi_init( &G  ); mpi_init( &G2 );
    mpi_init( &L1 ); mpi_init( &L2 );

    MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
    MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
    MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
    MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
    MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
    MPI_CHK( mpi_gcd( &G, &ctx->E, &H  ) );

    MPI_CHK( mpi_gcd( &G2, &P1, &Q1 ) );
    MPI_CHK( mpi_div_mpi( &L1, &L2, &H, &G2 ) );  
    MPI_CHK( mpi_mod_mpi( &I, &DE, &L1  ) );

    /*
     * Check for a valid PKCS1v2 private key
     */
    if( mpi_cmp_mpi( &PQ, &ctx->N ) != 0 ||
        mpi_cmp_int( &L2, 0 ) != 0 ||
        mpi_cmp_int( &I, 1 ) != 0 ||
        mpi_cmp_int( &G, 1 ) != 0 )
    {
        ret = POLARSSL_ERR_RSA_KEY_CHECK_FAILED;
    }

    
cleanup:

    mpi_free( &PQ ); mpi_free( &DE ); mpi_free( &P1 ); mpi_free( &Q1 );
    mpi_free( &H  ); mpi_free( &I  ); mpi_free( &G  ); mpi_free( &G2 );
    mpi_free( &L1 ); mpi_free( &L2 );

    if( ret == POLARSSL_ERR_RSA_KEY_CHECK_FAILED )
        return( ret );

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

    return( 0 );
}

/*
 * Do an RSA public key operation
 */
int rsa_public( rsa_context *ctx,
                const unsigned char *input,
                unsigned char *output )
{
    int ret;
    size_t olen;
    mpi T;

    mpi_init( &T );

    MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );

    if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
    {
        mpi_free( &T );
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

    olen = ctx->len;
    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
    MPI_CHK( mpi_write_binary( &T, output, olen ) );

cleanup:

    mpi_free( &T );

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

    return( 0 );
}

/*
 * Do an RSA private key operation
 */
int rsa_private( rsa_context *ctx,
                 const unsigned char *input,
                 unsigned char *output )
{
    int ret;
    size_t olen;
    mpi T, T1, T2;

    mpi_init( &T ); mpi_init( &T1 ); mpi_init( &T2 );

    MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );

    if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
    {
        mpi_free( &T );
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }

#if defined(POLARSSL_RSA_NO_CRT)
    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
#else
    /*
     * faster decryption using the CRT
     *
     * T1 = input ^ dP mod P
     * T2 = input ^ dQ mod Q
     */
    MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
    MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );

    /*
     * T = (T1 - T2) * (Q^-1 mod P) mod P
     */
    MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
    MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
    MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );

    /*
     * output = T2 + T * Q
     */
    MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
    MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
#endif

    olen = ctx->len;
    MPI_CHK( mpi_write_binary( &T, output, olen ) );

cleanup:

    mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );

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

    return( 0 );
}

#if defined(POLARSSL_PKCS1_V21)
/**
 * Generate and apply the MGF1 operation (from PKCS#1 v2.1) to a buffer.
 *
 * @param dst       buffer to mask
 * @param dlen      length of destination buffer
 * @param src       source of the mask generation
 * @param slen      length of the source buffer
 * @param md_ctx    message digest context to use
 */
static void mgf_mask( unsigned char *dst, size_t dlen, unsigned char *src, size_t slen,  
                       md_context_t *md_ctx )
{
    unsigned char mask[POLARSSL_MD_MAX_SIZE];
    unsigned char counter[4];
    unsigned char *p;
    unsigned int hlen;
    size_t i, use_len;

    memset( mask, 0, POLARSSL_MD_MAX_SIZE );
    memset( counter, 0, 4 );

    hlen = md_ctx->md_info->size;

    // Generate and apply dbMask
    //
    p = dst;

    while( dlen > 0 )
    {
        use_len = hlen;
        if( dlen < hlen )
            use_len = dlen;

        md_starts( md_ctx );
        md_update( md_ctx, src, slen );
        md_update( md_ctx, counter, 4 );
        md_finish( md_ctx, mask );

        for( i = 0; i < use_len; ++i )
            *p++ ^= mask[i];

        counter[3]++;

        dlen -= use_len;
    }
}
#endif

/*
 * 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 ) );
}

/*
 * 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 > 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 - (p - buf) > output_max_len)
        return( POLARSSL_ERR_RSA_OUTPUT_TOO_LARGE );

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

    return( 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 ) );
}

/*
 * 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 > 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 - ( 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 );
}

/*
 * Free the components of an RSA key
 */
void rsa_free( rsa_context *ctx )
{
    mpi_free( &ctx->RQ ); mpi_free( &ctx->RP ); mpi_free( &ctx->RN );
    mpi_free( &ctx->QP ); mpi_free( &ctx->DQ ); mpi_free( &ctx->DP );
    mpi_free( &ctx->Q  ); mpi_free( &ctx->P  ); mpi_free( &ctx->D );
    mpi_free( &ctx->E  ); mpi_free( &ctx->N  );
}

#if defined(POLARSSL_SELF_TEST)

#include "polarssl/sha1.h"

/*
 * Example RSA-1024 keypair, for test purposes
 */
#define KEY_LEN 128

#define RSA_N   "9292758453063D803DD603D5E777D788" \
                "8ED1D5BF35786190FA2F23EBC0848AEA" \
                "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
                "7130B9CED7ACDF54CFC7555AC14EEBAB" \
                "93A89813FBF3C4F8066D2D800F7C38A8" \
                "1AE31942917403FF4946B0A83D3D3E05" \
                "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
                "5E94BB77B07507233A0BC7BAC8F90F79"

#define RSA_E   "10001"

#define RSA_D   "24BF6185468786FDD303083D25E64EFC" \
                "66CA472BC44D253102F8B4A9D3BFA750" \
                "91386C0077937FE33FA3252D28855837" \
                "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
                "DF79C5CE07EE72C7F123142198164234" \
                "CABB724CF78B8173B9F880FC86322407" \
                "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
                "071513A1E85B5DFA031F21ECAE91A34D"

#define RSA_P   "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
                "2C01CAD19EA484A87EA4377637E75500" \
                "FCB2005C5C7DD6EC4AC023CDA285D796" \
                "C3D9E75E1EFC42488BB4F1D13AC30A57"

#define RSA_Q   "C000DF51A7C77AE8D7C7370C1FF55B69" \
                "E211C2B9E5DB1ED0BF61D0D9899620F4" \
                "910E4168387E3C30AA1E00C339A79508" \
                "8452DD96A9A5EA5D9DCA68DA636032AF"

#define RSA_DP  "C1ACF567564274FB07A0BBAD5D26E298" \
                "3C94D22288ACD763FD8E5600ED4A702D" \
                "F84198A5F06C2E72236AE490C93F07F8" \
                "3CC559CD27BC2D1CA488811730BB5725"

#define RSA_DQ  "4959CBF6F8FEF750AEE6977C155579C7" \
                "D8AAEA56749EA28623272E4F7D0592AF" \
                "7C1F1313CAC9471B5C523BFE592F517B" \
                "407A1BD76C164B93DA2D32A383E58357"

#define RSA_QP  "9AE7FBC99546432DF71896FC239EADAE" \
                "F38D18D2B2F0E2DD275AA977E2BF4411" \
                "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
                "A74206CEC169D74BF5A8C50D6F48EA08"

#define PT_LEN  24
#define RSA_PT  "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
                "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"

static int myrand( void *rng_state )
{
    if( rng_state != NULL )
        rng_state  = NULL;

    return( rand() );
}

/*
 * Checkup routine
 */
int rsa_self_test( int verbose )
{
    size_t len;
    rsa_context rsa;
    unsigned char rsa_plaintext[PT_LEN];
    unsigned char rsa_decrypted[PT_LEN];
    unsigned char rsa_ciphertext[KEY_LEN];
#if defined(POLARSSL_SHA1_C)
    unsigned char sha1sum[20];
#endif

    rsa_init( &rsa, RSA_PKCS_V15, 0 );

    rsa.len = KEY_LEN;
    mpi_read_string( &rsa.N , 16, RSA_N  );
    mpi_read_string( &rsa.E , 16, RSA_E  );
    mpi_read_string( &rsa.D , 16, RSA_D  );
    mpi_read_string( &rsa.P , 16, RSA_P  );
    mpi_read_string( &rsa.Q , 16, RSA_Q  );
    mpi_read_string( &rsa.DP, 16, RSA_DP );
    mpi_read_string( &rsa.DQ, 16, RSA_DQ );
    mpi_read_string( &rsa.QP, 16, RSA_QP );

    if( verbose != 0 )
        printf( "  RSA key validation: " );

    if( rsa_check_pubkey(  &rsa ) != 0 ||
        rsa_check_privkey( &rsa ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n  PKCS#1 encryption : " );

    memcpy( rsa_plaintext, RSA_PT, PT_LEN );

    if( rsa_pkcs1_encrypt( &rsa, &myrand, NULL, RSA_PUBLIC, PT_LEN,
                           rsa_plaintext, rsa_ciphertext ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n  PKCS#1 decryption : " );

    if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
                           rsa_ciphertext, rsa_decrypted,
                           sizeof(rsa_decrypted) ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

#if defined(POLARSSL_SHA1_C)
    if( verbose != 0 )
        printf( "passed\n  PKCS#1 data sign  : " );

    sha1( rsa_plaintext, PT_LEN, sha1sum );

    if( rsa_pkcs1_sign( &rsa, NULL, NULL, RSA_PRIVATE, SIG_RSA_SHA1, 20,
                        sha1sum, rsa_ciphertext ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n  PKCS#1 sig. verify: " );

    if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, SIG_RSA_SHA1, 20,
                          sha1sum, rsa_ciphertext ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n\n" );
#endif /* POLARSSL_SHA1_C */

    rsa_free( &rsa );

    return( 0 );
}

#endif

#endif
