Exemple #1
0
/*
    Generate an RSA keypair
 */
int rsa_gen_key(rsa_context *ctx, int nbits, int exponent)
{
    mpi     P1, Q1, H, G;
    int     ret;

    if (ctx->f_rng == NULL || nbits < 128 || exponent < 3) {
        return EST_ERR_RSA_BAD_INPUT_DATA;
    }
    mpi_init(&P1, &Q1, &H, &G, NULL);

    /*
        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, ctx->f_rng, ctx->p_rng));

        MPI_CHK(mpi_gen_prime(&ctx->Q, (nbits + 1) >> 1, 0, ctx->f_rng, ctx->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(&G, &H, &Q1, &P1, NULL);
    if (ret != 0) {
        rsa_free(ctx);
        return EST_ERR_RSA_KEY_GEN_FAILED | ret;
    }
    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, DP, DQ, QP;

    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_init( &DP ); mpi_init( &DQ );
    mpi_init( &QP );

    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  ) );

    MPI_CHK( mpi_mod_mpi( &DP, &ctx->D, &P1 ) );
    MPI_CHK( mpi_mod_mpi( &DQ, &ctx->D, &Q1 ) );
    MPI_CHK( mpi_inv_mod( &QP, &ctx->Q, &ctx->P ) );
    /*
     * Check for a valid PKCS1v2 private key
     */
    if( mpi_cmp_mpi( &PQ, &ctx->N ) != 0 ||
        mpi_cmp_mpi( &DP, &ctx->DP ) != 0 ||
        mpi_cmp_mpi( &DQ, &ctx->DQ ) != 0 ||
        mpi_cmp_mpi( &QP, &ctx->QP ) != 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 ); mpi_free( &DP ); mpi_free( &DQ );
    mpi_free( &QP );

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

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

    return( 0 );
}
Exemple #3
0
/*
 * Perform an RSA public key operation
 */
int rsa_public( rsa_context   *ctx,
                unsigned char *input,  int ilen,
                unsigned char *output, int *olen )
{
    int ret;
    mpi T;

   // if( ilen != ctx->len || olen != ctx->len )
   //    return( ERR_RSA_BAD_INPUT_DATA );


    mpi_init( &T, NULL );

    CHK( mpi_import( &T, input, ilen ) );

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

    CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
    CHK( mpi_export( &T, output, olen ) );

cleanup:

    mpi_free( &T, NULL );

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

    return( 0 );
}
Exemple #4
0
/*
 * Create own private value X and export G^X
 */
int dhm_make_public( dhm_context *ctx, int x_size,
                     unsigned char *output, size_t olen,
                     int (*f_rng)(void *, unsigned char *, size_t),
                     void *p_rng )
{
    int ret, n;

    if( ctx == NULL || olen < 1 || olen > ctx->len )
        return( POLARSSL_ERR_DHM_BAD_INPUT_DATA );

    /*
     * generate X and calculate GX = G^X mod P
     */
    n = x_size / sizeof( t_uint ) + 1;

    mpi_fill_random( &ctx->X, n, f_rng, p_rng );

    while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
           mpi_shift_r( &ctx->X, 1 );

    MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
                          &ctx->P , &ctx->RP ) );

    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
        return( ret );

    MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) );

cleanup:

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

    return( 0 );
}
Exemple #5
0
int rsa_calc_str(const char* n, const char* e, const unsigned char* data, unsigned char* output)
{
    int ret = 0;
    mpi N = {0,0,0};
    mpi E = {0,0,0};
    mpi V = {0,0,0};
    mpi RN = {0,0,0};
    size_t l = 128;
    int j;
    MPI_CHK(mpi_read_string(&N,16,n));
    for(j=N.n;j>=0;j--){
        if(N.p[j-1])break;
    }
    l = j * sizeof(t_uint);
    MPI_CHK(mpi_read_string(&E,16,e));
    MPI_CHK(mpi_read_binary(&V,data, l));
    if( mpi_cmp_mpi( &V, &N ) >= 0 ){
        ret = POLARSSL_ERR_RSA_BAD_INPUT_DATA;
        goto cleanup;
    }
    printf("===========================>>>>>>>\n");
    MPI_CHK(mpi_exp_mod( &V, &V, &E, &N, &RN ));
    printf("<<<<<<<===========================\n");
    MPI_CHK(mpi_write_binary( &V, output, l ));
cleanup:
    mpi_free( &N );
    mpi_free( &E );
    mpi_free( &RN );
    mpi_free( &V );
    return ret;
}
/*
 * Create own private value X and export G^X
 */
int dhm_make_public (dhm_context * ctx, int x_size, unsigned char* output, int olen, int (*f_rng) (void* ), void* p_rng)
{
    int ret, i, n;
    unsigned char* p;

    if (ctx == NULL || olen < 1 || olen > ctx->len)
        return (POLARSSL_ERR_DHM_BAD_INPUT_DATA);

    /*
     * generate X and calculate GX = G^X mod P
     */
    n = x_size / sizeof (t_int);
    MPI_CHK (mpi_grow (&ctx->X, n));
    MPI_CHK (mpi_lset (&ctx->X, 0));

    n = x_size - 1;
    p = (unsigned char *) ctx->X.p;
    for (i = 0; i < n; i++)
        *p++ = (unsigned char) f_rng (p_rng);

    while (mpi_cmp_mpi (&ctx->X, &ctx->P) >= 0)
        mpi_shift_r (&ctx->X, 1);

    MPI_CHK (mpi_exp_mod (&ctx->GX, &ctx->G, &ctx->X, &ctx->P, &ctx->RP));

    MPI_CHK (mpi_write_binary (&ctx->GX, output, olen));

  cleanup:

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

    return (0);
}
Exemple #7
0
/*
 * Check a private RSA key
 */
int rsa_check_privkey( rsa_context *ctx )
{
    int ret;
    mpi PQ, DE, P1, Q1, H, I, G;

    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, &DE, &P1, &Q1, &H, &I, &G, NULL );

    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_mod_mpi( &I, &DE, &H  ) );
    MPI_CHK( mpi_gcd( &G, &ctx->E, &H  ) );

    if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
        mpi_cmp_int( &I, 1 ) == 0 &&
        mpi_cmp_int( &G, 1 ) == 0 )
    {
        mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
        return( 0 );
    }

cleanup:

    mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
    return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
}
Exemple #8
0
/*
 * Do an RSA public key operation
 */
int rsa_public( rsa_context *ctx,
                unsigned char *input,
                unsigned char *output )
{
    int ret, olen;
    mpi T;

    mpi_init( &T, NULL );

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

    if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
    {
        mpi_free( &T, NULL );
        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, NULL );

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

    return( 0 );
}
Exemple #9
0
static int Bcompare(lua_State *L)
{
    mpi *a=Bget(L,1);
    mpi *b=Bget(L,2);
    lua_pushinteger(L,mpi_cmp_mpi(a,b));
    return 1;
}
Exemple #10
0
static int Blt(lua_State *L)
{
    mpi *a=Bget(L,1);
    mpi *b=Bget(L,2);
    lua_pushboolean(L, mpi_cmp_mpi(a,b)<0);
    return 1;
}
Exemple #11
0
/*
 * Check if contexts holding a public and private key match
 */
int rsa_check_pub_priv( const rsa_context *pub, const rsa_context *prv )
{
    if( rsa_check_pubkey( pub ) != 0 ||
        rsa_check_privkey( prv ) != 0 )
    {
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
    }

    if( mpi_cmp_mpi( &pub->N, &prv->N ) != 0 ||
        mpi_cmp_mpi( &pub->E, &prv->E ) != 0 )
    {
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
    }

    return( 0 );
}
Exemple #12
0
/*
 * Check if the private key is valid
 */
int rsa_check_privkey( rsa_context *ctx )
{
    int ret = 0;
    mpi TN, P1, Q1, H, G;

    mpi_init( &TN, &P1, &Q1, &H, &G, NULL );

    CHK( mpi_mul_mpi( &TN, &ctx->P, &ctx->Q ) );
    CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
    CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
    CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
    CHK( mpi_gcd( &G, &ctx->E, &H  ) );

    if( mpi_cmp_mpi( &TN, &ctx->N ) == 0 &&
        mpi_cmp_int( &G, 1 ) == 0 )
    {
        mpi_free( &TN, &P1, &Q1, &H, &G, NULL );
        return( 0 );
    }

cleanup:

    mpi_free( &TN, &P1, &Q1, &H, &G, NULL );
    return( ERR_RSA_KEY_CHK_FAILED | ret );
}
/*
 * Do an RSA private key operation
 */
int rsa_private( rsa_context *ctx,
                 unsigned char *input,
                 unsigned char *output )
{
    int ret, olen;
    mpi T, T1, T2;

    //printf("RSA private key operation start\n");

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

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

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

#if 0
    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, &T1, &T2, NULL );

    //printf("RSA private key operation end\n");

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

    return( 0 );
}
Exemple #14
0
/*
 * Generate an RSA keypair
 */
int rsa_gen_key( rsa_context *ctx, int nbits, int exponent,
                 ulong (*rng_fn)(void *), void *rng_st )
{
    int ret;
    mpi P1, Q1, H, G;

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

    memset( ctx, 0, sizeof( rsa_context ) );

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

    nbits >>= 1;

    do
    {
        CHK( mpi_gen_prime( &ctx->P, nbits, 0, rng_fn, rng_st ) );
        CHK( mpi_gen_prime( &ctx->Q, nbits, 0, rng_fn, rng_st ) );

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

        CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
        CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
        CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
        CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
        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
     */
    CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H  ) );
    CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
    CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
    CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );

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

cleanup:

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

    if( ret != 0 )
    {
        rsa_free( ctx );
        return( ERR_RSA_KEYGEN_FAILED | ret );
    }

    return( 0 );   
}
Exemple #15
0
/*
 * Perform an RSA private key operation
 */
int rsa_private( rsa_context   *ctx,
                 unsigned char *input,  int ilen,
                 unsigned char *output, int *olen )
{
    int ret;
    mpi T, T1, T2;

   //if( ilen != ctx->len || olen != ctx->len )
   //    return( ERR_RSA_BAD_INPUT_DATA );

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

    CHK( mpi_import( &T, input, ilen ) );

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

#if 0
    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
     */
    CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
    CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );

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

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

    CHK( mpi_export( &T, output, olen ) );

cleanup:

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

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

    return( 0 );
}
Exemple #16
0
/*
 * Setup and write the ServerKeyExchange parameters
 */
int dhm_make_params( dhm_context *ctx, int x_size,
                     unsigned char *output, size_t *olen,
                     int (*f_rng)(void *, unsigned char *, size_t),
                     void *p_rng )
{
    int ret, n;
    size_t n1, n2, n3;
    unsigned char *p;

    /*
     * Generate X as large as possible ( < P )
     */
    n = x_size / sizeof( t_uint ) + 1;

    mpi_fill_random( &ctx->X, n, f_rng, p_rng );

    while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
           mpi_shift_r( &ctx->X, 1 );

    /*
     * Calculate GX = G^X mod P
     */
    MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
                          &ctx->P , &ctx->RP ) );

    if( ( ret = dhm_check_range( &ctx->GX, &ctx->P ) ) != 0 )
        return( ret );

    /*
     * export P, G, GX
     */
#define DHM_MPI_EXPORT(X,n)                     \
    MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \
    *p++ = (unsigned char)( n >> 8 );           \
    *p++ = (unsigned char)( n      ); p += n;

    n1 = mpi_size( &ctx->P  );
    n2 = mpi_size( &ctx->G  );
    n3 = mpi_size( &ctx->GX );

    p = output;
    DHM_MPI_EXPORT( &ctx->P , n1 );
    DHM_MPI_EXPORT( &ctx->G , n2 );
    DHM_MPI_EXPORT( &ctx->GX, n3 );

    *olen  = p - output;

    ctx->len = n1;

cleanup:

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

    return( 0 );
}
Exemple #17
0
/*
 * Verify sanity of parameter with regards to P
 *
 * Parameter should be: 2 <= public_param <= P - 2
 *
 * For more information on the attack, see:
 *  http://www.cl.cam.ac.uk/~rja14/Papers/psandqs.pdf
 *  http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2005-2643
 */
static int dhm_check_range( const mpi *param, const mpi *P )
{
    mpi L, U;
    int ret = POLARSSL_ERR_DHM_BAD_INPUT_DATA;

    mpi_init( &L ); mpi_init( &U );
    mpi_lset( &L, 2 );
    mpi_sub_int( &U, P, 2 );

    if( mpi_cmp_mpi( param, &L ) >= 0 &&
        mpi_cmp_mpi( param, &U ) <= 0 )
    {
        ret = 0;
    }

    mpi_free( &L ); mpi_free( &U );

    return( ret );
}
Exemple #18
0
/*
 * Setup and write the ServerKeyExchange parameters
 */
int dhm_make_params( dhm_context *ctx, int x_size,
                     unsigned char *output, int *olen,
                     int (*f_rng)(void *), void *p_rng )
{
    int i, ret, n, n1, n2, n3;
    unsigned char *p;

    /*
     * generate X and calculate GX = G^X mod P
     */
    n = x_size / sizeof( t_int );
    MPI_CHK( mpi_grow( &ctx->X, n ) );
    MPI_CHK( mpi_lset( &ctx->X, 0 ) );

    n = x_size >> 3;
    p = (unsigned char *) ctx->X.p;
    for( i = 0; i < n; i++ )
        *p++ = (unsigned char) f_rng( p_rng );

    while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 )
           mpi_shift_r( &ctx->X, 1 );

    MPI_CHK( mpi_exp_mod( &ctx->GX, &ctx->G, &ctx->X,
                          &ctx->P , &ctx->RP ) );

    /*
     * export P, G, GX
     */
#define DHM_MPI_EXPORT(X,n)                     \
    MPI_CHK( mpi_write_binary( X, p + 2, n ) ); \
    *p++ = (unsigned char)( n >> 8 );           \
    *p++ = (unsigned char)( n      ); p += n;

    n1 = mpi_size( &ctx->P  );
    n2 = mpi_size( &ctx->G  );
    n3 = mpi_size( &ctx->GX );

    p = output;
    DHM_MPI_EXPORT( &ctx->P , n1 );
    DHM_MPI_EXPORT( &ctx->G , n2 );
    DHM_MPI_EXPORT( &ctx->GX, n3 );

    *olen  = p - output;

    ctx->len = n1;

cleanup:

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

    return( 0 );
}
Exemple #19
0
/*
    Do an RSA private key operation
 */
int rsa_private(rsa_context *ctx, uchar *input, uchar *output)
{
    int ret, olen;
    mpi T, T1, T2;

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

    MPI_CHK(mpi_read_binary(&T, input, ctx->len));
    if (mpi_cmp_mpi(&T, &ctx->N) >= 0) {
        mpi_free(&T, NULL);
        return EST_ERR_RSA_BAD_INPUT_DATA;
    }
    //  MOB - why ?
#if 0
    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, &T1, &T2, NULL);
    if (ret != 0)
        return EST_ERR_RSA_PRIVATE_FAILED | ret;

    return 0;
}
Exemple #20
0
/*
 * 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 ) > POLARSSL_MPI_MAX_BITS )
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );

    if( mpi_msb( &ctx->E ) < 2 ||
        mpi_cmp_mpi( &ctx->E, &ctx->N ) >= 0 )
        return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );

    return( 0 );
}
Exemple #21
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, &DE, &P1, &Q1, &H, &I, &G, &G2, &L1, &L2, NULL );

    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 )
    {
        mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
        return( 0 );
    }

    
cleanup:

    mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, &G2, &L1, &L2, NULL );
    return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
}
Exemple #22
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 );
    }

#if defined(POLARSSL_THREADING_C)
    polarssl_mutex_lock( &ctx->mutex );
#endif

    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:
#if defined(POLARSSL_THREADING_C)
    polarssl_mutex_unlock( &ctx->mutex );
#endif

    mpi_free( &T );

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

    return( 0 );
}
Exemple #23
0
int rsa_calc(const unsigned char* n, const unsigned char* e, const unsigned char* data, size_t bits, size_t e_len, unsigned char* output)
{
    int ret = 0;
    mpi N = {0,0,0};
    mpi E = {0,0,0};
    mpi V = {0,0,0};
    mpi RN = {0,0,0};
    MPI_CHK(mpi_read_binary(&N,n,bits/8));
    MPI_CHK(mpi_read_binary(&E,e,e_len));
    MPI_CHK(mpi_read_binary(&V,data,bits/8));
    if( mpi_cmp_mpi( &V, &N ) >= 0 ){
        ret = POLARSSL_ERR_RSA_BAD_INPUT_DATA;
        goto cleanup;
    }
    MPI_CHK(mpi_exp_mod( &V, &V, &E, &N, &RN ));
    MPI_CHK(mpi_write_binary( &V, output, bits/8 ));
cleanup:
    mpi_free( &N );
    mpi_free( &E );
    mpi_free( &RN );
    mpi_free( &V );
    return ret;
}
Exemple #24
0
/*
 * Find the group id associated with an (almost filled) group as generated by
 * pk_group_from_specified(), or return an error if unknown.
 */
static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id )
{
    int ret = 0;
    ecp_group ref;
    const ecp_group_id *id;

    ecp_group_init( &ref );

    for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ )
    {
        /* Load the group associated to that id */
        ecp_group_free( &ref );
        MPI_CHK( ecp_use_known_dp( &ref, *id ) );

        /* Compare to the group we were given, starting with easy tests */
        if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
            mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
            mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
            mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
            mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
            mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
            mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
            /* For Y we may only know the parity bit, so compare only that */
            mpi_get_bit( &grp->G.Y, 0 ) == mpi_get_bit( &ref.G.Y, 0 ) )
        {
            break;
        }

    }

cleanup:
    ecp_group_free( &ref );

    *grp_id = *id;

    if( ret == 0 && *id == POLARSSL_ECP_DP_NONE )
        ret = POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE;

    return( ret );
}
Exemple #25
0
int
main(void)
{
    int ret;
    mpi A, E, N, X, Y, U, V;

    mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );

    MPI_CHK( mpi_read_string( &A, 16,
        "EFE021C2645FD1DC586E69184AF4A31E" \
        "D5F53E93B5F123FA41680867BA110131" \
        "944FE7952E2517337780CB0DB80E61AA" \
        "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );

    MPI_CHK( mpi_read_string( &E, 16,
        "B2E7EFD37075B9F03FF989C7C5051C20" \
        "34D2A323810251127E7BF8625A4F49A5" \
        "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
        "5B5C25763222FEFCCFC38B832366C29E" ) );

    MPI_CHK( mpi_read_string( &N, 16,
        "0066A198186C18C10B2F5ED9B522752A" \
        "9830B69916E535C8F047518A889A43A5" \
        "94B6BED27A168D31D4A52F88925AA8F5" ) );

    MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );

    MPI_CHK( mpi_read_string( &U, 16,
        "602AB7ECA597A3D6B56FF9829A5E8B85" \
        "9E857EA95A03512E2BAE7391688D264A" \
        "A5663B0341DB9CCFD2C4C5F421FEC814" \
        "8001B72E848A38CAE1C65F78E56ABDEF" \
        "E12D3C039B8A02D6BE593F0BBBDA56F1" \
        "ECF677152EF804370C1A305CAF3B5BF1" \
        "30879B56C61DE584A0F53A2447A51E" ) );

    if( verbose != 0 )
        printf( "  MPI test #1 (mul_mpi): " );

    if( mpi_cmp_mpi( &X, &U ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n" );

    MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );

    MPI_CHK( mpi_read_string( &U, 16,
        "256567336059E52CAE22925474705F39A94" ) );

    MPI_CHK( mpi_read_string( &V, 16,
        "6613F26162223DF488E9CD48CC132C7A" \
        "0AC93C701B001B092E4E5B9F73BCD27B" \
        "9EE50D0657C77F374E903CDFA4C642" ) );

    if( verbose != 0 )
        printf( "  MPI test #2 (div_mpi): " );

    if( mpi_cmp_mpi( &X, &U ) != 0 ||
        mpi_cmp_mpi( &Y, &V ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n" );

    MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );

    MPI_CHK( mpi_read_string( &U, 16,
        "36E139AEA55215609D2816998ED020BB" \
        "BD96C37890F65171D948E9BC7CBAA4D9" \
        "325D24D6A3C12710F10A09FA08AB87" ) );

    if( verbose != 0 )
        printf( "  MPI test #3 (exp_mod): " );

    if( mpi_cmp_mpi( &X, &U ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n" );

    MPI_CHK( mpi_inv_mod( &X, &A, &N ) );

    MPI_CHK( mpi_read_string( &U, 16,
        "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
        "C3DBA76456363A10869622EAC2DD84EC" \
        "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );

    if( verbose != 0 )
        printf( "  MPI test #4 (inv_mod): " );

    if( mpi_cmp_mpi( &X, &U ) != 0 )
    {
        if( verbose != 0 )
            printf( "failed\n" );

        return( 1 );
    }

    if( verbose != 0 )
        printf( "passed\n" );

cleanup:

    if( ret != 0 && verbose != 0 )
        printf( "Unexpected error, return code = %08X\n", ret );

    mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );

    if( verbose != 0 )
        printf( "\n" );

    return( ret );
}
Exemple #26
0
/*
 * Do an RSA private key operation
 */
int rsa_private( rsa_context *ctx,
                 int (*f_rng)(void *, unsigned char *, size_t),
                 void *p_rng,
                 const unsigned char *input,
                 unsigned char *output )
{
    int ret;
    size_t olen;
    mpi T, T1, T2;
#if !defined(POLARSSL_RSA_NO_CRT)
    mpi *Vi, *Vf;

    /*
     * When using the Chinese Remainder Theorem, we use blinding values.
     * Without threading, we just read them directly from the context,
     * otherwise we make a local copy in order to reduce locking contention.
     */
#if defined(POLARSSL_THREADING_C)
    mpi Vi_copy, Vf_copy;

    mpi_init( &Vi_copy ); mpi_init( &Vf_copy );
    Vi = &Vi_copy;
    Vf = &Vf_copy;
#else
    Vi = &ctx->Vi;
    Vf = &ctx->Vf;
#endif
#endif /* !POLARSSL_RSA_NO_CRT */

    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)
    ((void) f_rng);
    ((void) p_rng);
    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
#else
    if( f_rng != NULL )
    {
        /*
         * Blinding
         * T = T * Vi mod N
         */
        MPI_CHK( rsa_prepare_blinding( ctx, Vi, Vf, f_rng, p_rng ) );
        MPI_CHK( mpi_mul_mpi( &T, &T, Vi ) );
        MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
    }

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

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

    if( f_rng != NULL )
    {
        /*
         * Unblind
         * T = T * Vf mod N
         */
        MPI_CHK( mpi_mul_mpi( &T, &T, Vf ) );
        MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
    }
#endif /* POLARSSL_RSA_NO_CRT */

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

cleanup:
    mpi_free( &T ); mpi_free( &T1 ); mpi_free( &T2 );
#if !defined(POLARSSL_RSA_NO_CRT) && defined(POLARSSL_THREADING_C)
    mpi_free( &Vi_copy ); mpi_free( &Vf_copy );
#endif

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

    return( 0 );
}
int main( int argc, char *argv[] )
{
    int ret, i;
    x509_crt cacert;
    x509_crl crl;
    char buf[10240];

    ((void) argc);
    ((void) argv);

    x509_crt_init( &cacert );
    x509_crl_init( &crl );

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

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

    printf( " ok\n" );

    x509_crt_info( buf, 1024, "CRT: ", &cacert );
    printf("%s\n", buf );

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

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

    printf( " ok\n" );

    x509_crl_info( buf, 1024, "CRL: ", &crl );
    printf("%s\n", buf );

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

        x509_crt_init( &clicert );
        pk_init( &pk );

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

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

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

        printf( " ok\n" );

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

        ret = x509_crt_verify( &clicert, &cacert, &crl, NULL, &flags, NULL,
                               NULL );
        if( ret != 0 )
        {
            if( ret == POLARSSL_ERR_X509_CERT_VERIFY_FAILED )
            {
                if( flags & BADCERT_CN_MISMATCH )
                    printf( " CN_MISMATCH " );
                if( flags & BADCERT_EXPIRED )
                    printf( " EXPIRED " );
                if( flags & BADCERT_REVOKED )
                    printf( " REVOKED " );
                if( flags & BADCERT_NOT_TRUSTED )
                    printf( " NOT_TRUSTED " );
                if( flags & BADCRL_NOT_TRUSTED )
                    printf( " CRL_NOT_TRUSTED " );
                if( flags & BADCRL_EXPIRED )
                    printf( " CRL_EXPIRED " );
            } else {
                printf( " failed\n  !  x509_crt_verify returned %d\n\n", ret );
                goto exit;
            }
        }

        printf( " ok\n" );

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

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

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

        printf( " ok\n" );

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


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

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

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

        ret = rsa_check_privkey( pk_rsa( pk ) );
        if( ret != 0 )
        {
            printf( " failed\n  !  rsa_check_privkey returned %d\n\n", ret );
            goto exit;
        }

        printf( " ok\n" );

        x509_crt_free( &clicert );
        pk_free( &pk );
    }

exit:
    x509_crt_free( &cacert );
    x509_crl_free( &crl );

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

    return( ret );
}
Exemple #28
0
/*
 * Do an RSA private key operation
 */
int rsa_private( rsa_context *ctx,
                 int (*f_rng)(void *, unsigned char *, size_t),
                 void *p_rng,
                 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)
    ((void) f_rng);
    ((void) p_rng);
    MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
#else
    if( f_rng != NULL )
    {
        /*
         * Blinding
         * T = T * Vi mod N
         */
        MPI_CHK( rsa_prepare_blinding( ctx, f_rng, p_rng ) );
        MPI_CHK( mpi_mul_mpi( &T, &T, &ctx->Vi ) );
        MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
    }

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

    if( f_rng != NULL )
    {
        /*
         * Unblind
         * T = T * Vf mod N
         */
        MPI_CHK( mpi_mul_mpi( &T, &T, &ctx->Vf ) );
        MPI_CHK( mpi_mod_mpi( &T, &T, &ctx->N ) );
    }
#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 );
}
Exemple #29
0
/*
 * Generate an RSA keypair
 */
int rsa_gen_key( rsa_context *ctx,
        int (*f_rng)(void *),
        void *p_rng,
        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, &Q1, &H, &G, NULL );

    /*
     * 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( &G, &H, &Q1, &P1, NULL );

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

    return( 0 );   
}
Exemple #30
0
/**
*  Hacked from rsa.c, polarssl doesn't like generating signatures when only D and N are present
**/
int ctr_rsa_rsassa_pkcs1_v15_sign( rsa_context *ctx,
                               int mode,
                               int hash_id,
                               unsigned int hashlen,
                               const unsigned char *hash,
                               unsigned char *sig )
{
    size_t nb_pad, olen, ret;
    unsigned char *p = sig;

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

    olen = ctx->len;

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

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

    mpi T, T1, T2;

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

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

    if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
    {
        mpi_free( &T );
        return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
    }	
	
	MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
	
    MPI_CHK( mpi_write_binary( &T, sig, olen ) );

cleanup:

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

    return( 0 );
}