Exemple #1
0
int asn1_write_shmpi( unsigned char **p, unsigned char *start, shmpi *X )
{
    int ret;
    size_t len = 0;

    // Write the MPI
    //
    len = shmpi_size( X );

    if( *p - start < (int) len )
        return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );

    (*p) -= len;
    MPI_CHK( shmpi_write_binary( X, *p, len ) );

    // DER format assumes 2s complement for numbers, so the leftmost bit
    // should be 0 for positive numbers and 1 for negative numbers.
    //
    if( X->s ==1 && **p & 0x80 )
    {
        if( *p - start < 1 )
            return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );

        *--(*p) = 0x00;
        len += 1;
    }

    ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
    ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_INTEGER ) );

    ret = (int) len;

cleanup:
    return( ret );
}
Exemple #2
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 );
}
Exemple #3
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 );
}