Ejemplo n.º 1
0
/*
 * Check a private RSA key
 */
int shrsa_check_privkey( const shrsa_context *ctx )
{
    int ret;
    shmpi PQ, DE, P1, Q1, H, I, G, G2, L1, L2, DP, DQ, QP;

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

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

    shmpi_init( &PQ ); shmpi_init( &DE ); shmpi_init( &P1 ); shmpi_init( &Q1 );
    shmpi_init( &H  ); shmpi_init( &I  ); shmpi_init( &G  ); shmpi_init( &G2 );
    shmpi_init( &L1 ); shmpi_init( &L2 ); shmpi_init( &DP ); shmpi_init( &DQ );
    shmpi_init( &QP );

    MPI_CHK( shmpi_mul_shmpi( &PQ, &ctx->P, &ctx->Q ) );
    MPI_CHK( shmpi_mul_shmpi( &DE, &ctx->D, &ctx->E ) );
    MPI_CHK( shmpi_sub_int( &P1, &ctx->P, 1 ) );
    MPI_CHK( shmpi_sub_int( &Q1, &ctx->Q, 1 ) );
    MPI_CHK( shmpi_mul_shmpi( &H, &P1, &Q1 ) );
    MPI_CHK( shmpi_gcd( &G, &ctx->E, &H  ) );

    MPI_CHK( shmpi_gcd( &G2, &P1, &Q1 ) );
    MPI_CHK( shmpi_div_shmpi( &L1, &L2, &H, &G2 ) );
    MPI_CHK( shmpi_mod_shmpi( &I, &DE, &L1  ) );

    MPI_CHK( shmpi_mod_shmpi( &DP, &ctx->D, &P1 ) );
    MPI_CHK( shmpi_mod_shmpi( &DQ, &ctx->D, &Q1 ) );
    MPI_CHK( shmpi_inv_mod( &QP, &ctx->Q, &ctx->P ) );
    /*
     * Check for a valid PKCS1v2 private key
     */
    if( shmpi_cmp_shmpi( &PQ, &ctx->N ) != 0 ||
        shmpi_cmp_shmpi( &DP, &ctx->DP ) != 0 ||
        shmpi_cmp_shmpi( &DQ, &ctx->DQ ) != 0 ||
        shmpi_cmp_shmpi( &QP, &ctx->QP ) != 0 ||
        shmpi_cmp_int( &L2, 0 ) != 0 ||
        shmpi_cmp_int( &I, 1 ) != 0 ||
        shmpi_cmp_int( &G, 1 ) != 0 )
    {
        ret = RSA_ERR_RSA_KEY_CHECK_FAILED;
    }

cleanup:
    shmpi_free( &PQ ); shmpi_free( &DE ); shmpi_free( &P1 ); shmpi_free( &Q1 );
    shmpi_free( &H  ); shmpi_free( &I  ); shmpi_free( &G  ); shmpi_free( &G2 );
    shmpi_free( &L1 ); shmpi_free( &L2 ); shmpi_free( &DP ); shmpi_free( &DQ );
    shmpi_free( &QP );

    if( ret == RSA_ERR_RSA_KEY_CHECK_FAILED )
        return( ret );

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

    return( 0 );
}
Ejemplo n.º 2
0
/*
 * Check if contexts holding a public and private key match
 */
int shrsa_check_pub_priv( const shrsa_context *pub, const shrsa_context *prv )
{
    if( shrsa_check_pubkey( pub ) != 0 ||
        shrsa_check_privkey( prv ) != 0 )
    {
        return( RSA_ERR_RSA_KEY_CHECK_FAILED );
    }

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

    return( 0 );
}
Ejemplo n.º 3
0
/*
 * Check a public RSA key
 */
int shrsa_check_pubkey( const shrsa_context *ctx )
{
    if( !ctx->N.p || !ctx->E.p )
        return( RSA_ERR_RSA_KEY_CHECK_FAILED );

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

    if( shmpi_msb( &ctx->N ) < 128 ||
        shmpi_msb( &ctx->N ) > MPI_MPI_MAX_BITS )
        return( RSA_ERR_RSA_KEY_CHECK_FAILED );

    if( shmpi_msb( &ctx->E ) < 2 ||
        shmpi_cmp_shmpi( &ctx->E, &ctx->N ) >= 0 )
        return( RSA_ERR_RSA_KEY_CHECK_FAILED );

    return( 0 );
}
Ejemplo n.º 4
0
/*
 * Do an RSA public key operation
 */
int shrsa_public( shrsa_context *ctx,
                const unsigned char *input,
                unsigned char *output )
{
    int ret;
    size_t olen;
    shmpi T;

    shmpi_init( &T );

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

    if( shmpi_cmp_shmpi( &T, &ctx->N ) >= 0 )
    {
        shmpi_free( &T );
        return( RSA_ERR_RSA_BAD_INPUT_DATA );
    }

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

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

cleanup:
#if defined(RSA_THREADING_C)
    polarssl_mutex_unlock( &ctx->mutex );
#endif

    shmpi_free( &T );

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

    return( 0 );
}
Ejemplo n.º 5
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 &&
            shmpi_cmp_shmpi( &grp->P, &ref.P ) == 0 &&
            shmpi_cmp_shmpi( &grp->A, &ref.A ) == 0 &&
            shmpi_cmp_shmpi( &grp->B, &ref.B ) == 0 &&
            shmpi_cmp_shmpi( &grp->N, &ref.N ) == 0 &&
            shmpi_cmp_shmpi( &grp->G.X, &ref.G.X ) == 0 &&
            shmpi_cmp_shmpi( &grp->G.Z, &ref.G.Z ) == 0 &&
            /* For Y we may only know the parity bit, so compare only that */
            shmpi_get_bit( &grp->G.Y, 0 ) == shmpi_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 );
}
Ejemplo n.º 6
0
/*
 * Generate an RSA keypair
 */
int shrsa_gen_key( shrsa_context *ctx,
                 int (*f_rng)(void *, unsigned char *, size_t),
                 void *p_rng,
                 unsigned int nbits, int exponent )
{
    int ret;
    shmpi P1, Q1, H, G;

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

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

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

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

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

        if( shmpi_cmp_shmpi( &ctx->P, &ctx->Q ) < 0 )
            shmpi_swap( &ctx->P, &ctx->Q );

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

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

        MPI_CHK( shmpi_sub_int( &P1, &ctx->P, 1 ) );
        MPI_CHK( shmpi_sub_int( &Q1, &ctx->Q, 1 ) );
        MPI_CHK( shmpi_mul_shmpi( &H, &P1, &Q1 ) );
        MPI_CHK( shmpi_gcd( &G, &ctx->E, &H  ) );
    }
    while( shmpi_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( shmpi_inv_mod( &ctx->D , &ctx->E, &H  ) );
    MPI_CHK( shmpi_mod_shmpi( &ctx->DP, &ctx->D, &P1 ) );
    MPI_CHK( shmpi_mod_shmpi( &ctx->DQ, &ctx->D, &Q1 ) );
    MPI_CHK( shmpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );

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

cleanup:

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

    if( ret != 0 )
    {
        shrsa_free( ctx );
        return( RSA_ERR_RSA_KEY_GEN_FAILED + ret );
    }

    return( 0 );
}
Ejemplo n.º 7
0
/*
 * Do an RSA private key operation
 */
int shrsa_private( shrsa_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;
    shmpi T, T1, T2;
    shmpi *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(RSA_THREADING_C)
    shmpi Vi_copy, Vf_copy;

    shmpi_init( &Vi_copy ); shmpi_init( &Vf_copy );
    Vi = &Vi_copy;
    Vf = &Vf_copy;
#else
    Vi = &ctx->Vi;
    Vf = &ctx->Vf;
#endif

    shmpi_init( &T ); shmpi_init( &T1 ); shmpi_init( &T2 );

    MPI_CHK( shmpi_read_binary( &T, input, ctx->len ) );
    if( shmpi_cmp_shmpi( &T, &ctx->N ) >= 0 )
    {
        shmpi_free( &T );
        return( RSA_ERR_RSA_BAD_INPUT_DATA );
    }

    if( f_rng != NULL )
    {
        /*
         * Blinding
         * T = T * Vi mod N
         */
        MPI_CHK( shrsa_prepare_blinding( ctx, Vi, Vf, f_rng, p_rng ) );
        MPI_CHK( shmpi_mul_shmpi( &T, &T, Vi ) );
        MPI_CHK( shmpi_mod_shmpi( &T, &T, &ctx->N ) );
    }

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

#if defined(RSA_RSA_NO_CRT)
    MPI_CHK( shmpi_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( shmpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
    MPI_CHK( shmpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );

    /*
     * T = (T1 - T2) * (Q^-1 mod P) mod P
     */
    MPI_CHK( shmpi_sub_shmpi( &T, &T1, &T2 ) );
    MPI_CHK( shmpi_mul_shmpi( &T1, &T, &ctx->QP ) );
    MPI_CHK( shmpi_mod_shmpi( &T, &T1, &ctx->P ) );

    /*
     * T = T2 + T * Q
     */
    MPI_CHK( shmpi_mul_shmpi( &T1, &T, &ctx->Q ) );
    MPI_CHK( shmpi_add_shmpi( &T, &T2, &T1 ) );
#endif /* RSA_RSA_NO_CRT */

    if( f_rng != NULL )
    {
        /*
         * Unblind
         * T = T * Vf mod N
         */
        MPI_CHK( shmpi_mul_shmpi( &T, &T, Vf ) );
        MPI_CHK( shmpi_mod_shmpi( &T, &T, &ctx->N ) );
    }

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

cleanup:
#if defined(RSA_THREADING_C)
    polarssl_mutex_unlock( &ctx->mutex );
    shmpi_free( &Vi_copy ); shmpi_free( &Vf_copy );
#endif
    shmpi_free( &T ); shmpi_free( &T1 ); shmpi_free( &T2 );

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

    return( 0 );
}