/* * 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 ); }
static int Bpowmod(lua_State *L) { mpi *a=Bget(L,1); mpi *b=Bget(L,2); mpi *m=Bget(L,3); mpi RR; mpi *rr=&RR; mpi_init(rr); mpi *c=Bnew(L); mpi_exp_mod(c,a,b,m,rr); mpi_free(rr); return 1; }
/* * Generate or update blinding values, see section 10 of: * KOCHER, Paul C. Timing attacks on implementations of Diffie-Hellman, RSA, * DSS, and other systems. In : Advances in Cryptology—CRYPTO’96. Springer * Berlin Heidelberg, 1996. p. 104-113. */ static int rsa_prepare_blinding( rsa_context *ctx, mpi *Vi, mpi *Vf, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret, count = 0; #if defined(POLARSSL_THREADING_C) polarssl_mutex_lock( &ctx->mutex ); #endif if( ctx->Vf.p != NULL ) { /* We already have blinding values, just update them by squaring */ MPI_CHK( mpi_mul_mpi( &ctx->Vi, &ctx->Vi, &ctx->Vi ) ); MPI_CHK( mpi_mod_mpi( &ctx->Vi, &ctx->Vi, &ctx->N ) ); MPI_CHK( mpi_mul_mpi( &ctx->Vf, &ctx->Vf, &ctx->Vf ) ); MPI_CHK( mpi_mod_mpi( &ctx->Vf, &ctx->Vf, &ctx->N ) ); goto done; } /* Unblinding value: Vf = random number, invertible mod N */ do { if( count++ > 10 ) return( POLARSSL_ERR_RSA_RNG_FAILED ); MPI_CHK( mpi_fill_random( &ctx->Vf, ctx->len - 1, f_rng, p_rng ) ); MPI_CHK( mpi_gcd( &ctx->Vi, &ctx->Vf, &ctx->N ) ); } while( mpi_cmp_int( &ctx->Vi, 1 ) != 0 ); /* Blinding value: Vi = Vf^(-e) mod N */ MPI_CHK( mpi_inv_mod( &ctx->Vi, &ctx->Vf, &ctx->N ) ); MPI_CHK( mpi_exp_mod( &ctx->Vi, &ctx->Vi, &ctx->E, &ctx->N, &ctx->RN ) ); done: if( Vi != &ctx->Vi ) { MPI_CHK( mpi_copy( Vi, &ctx->Vi ) ); MPI_CHK( mpi_copy( Vf, &ctx->Vf ) ); } cleanup: #if defined(POLARSSL_THREADING_C) polarssl_mutex_unlock( &ctx->mutex ); #endif return( ret ); }
/* * 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, count = 0; if( ctx == NULL || olen < 1 || olen > ctx->len ) return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); if( mpi_cmp_int( &ctx->P, 0 ) == 0 ) return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); /* * generate X and calculate GX = G^X mod P */ do { mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) mpi_shift_r( &ctx->X, 1 ); if( count++ > 10 ) return( POLARSSL_ERR_DHM_MAKE_PUBLIC_FAILED ); } while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); 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 ); }
/* * Derive and export the shared secret (G^Y)^X mod P */ int dhm_calc_secret_no_export(dhm_context *ctx) { int ret; if( ctx == NULL ) return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); MPI_CHK( mpi_exp_mod( &ctx->K, &ctx->GY, &ctx->X, &ctx->P, &ctx->RP ) ); if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) return( ret ); cleanup: if( ret != 0 ) return( POLARSSL_ERR_DHM_CALC_SECRET_FAILED + ret ); return( 0 ); }
/* * Derive and export the shared secret (G^Y)^X mod P */ int dhm_calc_secret (dhm_context * ctx, unsigned char* output, int* olen) { int ret; if (ctx == NULL || *olen < ctx->len) return (POLARSSL_ERR_DHM_BAD_INPUT_DATA); MPI_CHK (mpi_exp_mod (&ctx->K, &ctx->GY, &ctx->X, &ctx->P, &ctx->RP)); *olen = mpi_size (&ctx->K); MPI_CHK (mpi_write_binary (&ctx->K, output, *olen)); cleanup: if (ret != 0) return (POLARSSL_ERR_DHM_CALC_SECRET_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 ); } #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 ); }
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; }
/* * 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( XYSSL_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 >> 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 ) ); MPI_CHK( mpi_write_binary( &ctx->GX, output, olen ) ); cleanup: if( ret != 0 ) return( XYSSL_ERR_DHM_MAKE_PUBLIC_FAILED | ret ); return( 0 ); }
/* Do an RSA public key operation */ int rsa_public(rsa_context *ctx, uchar *input, uchar *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 EST_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 EST_ERR_RSA_PUBLIC_FAILED | ret; } return 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 ); }
/* * 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, count = 0; size_t n1, n2, n3; unsigned char *p; if( mpi_cmp_int( &ctx->P, 0 ) == 0 ) return( POLARSSL_ERR_DHM_BAD_INPUT_DATA ); /* * Generate X as large as possible ( < P ) */ do { mpi_fill_random( &ctx->X, x_size, f_rng, p_rng ); while( mpi_cmp_mpi( &ctx->X, &ctx->P ) >= 0 ) mpi_shift_r( &ctx->X, 1 ); if( count++ > 10 ) return( POLARSSL_ERR_DHM_MAKE_PARAMS_FAILED ); } while( dhm_check_range( &ctx->X, &ctx->P ) != 0 ); /* * 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 ); }
/** * 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 ); }
/* * 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 ); }
/* * 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( void ) { int ret; mpi E, P, Q, N, H, D, X, Y, Z; mpi_init( &E ); mpi_init( &P ); mpi_init( &Q ); mpi_init( &N ); mpi_init( &H ); mpi_init( &D ); mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z ); MPI_CHK( mpi_read_string( &P, 10, "2789" ) ); MPI_CHK( mpi_read_string( &Q, 10, "3203" ) ); MPI_CHK( mpi_read_string( &E, 10, "257" ) ); MPI_CHK( mpi_mul_mpi( &N, &P, &Q ) ); polarssl_printf( "\n Public key:\n\n" ); MPI_CHK( mpi_write_file( " N = ", &N, 10, NULL ) ); MPI_CHK( mpi_write_file( " E = ", &E, 10, NULL ) ); polarssl_printf( "\n Private key:\n\n" ); MPI_CHK( mpi_write_file( " P = ", &P, 10, NULL ) ); MPI_CHK( mpi_write_file( " Q = ", &Q, 10, NULL ) ); #if defined(POLARSSL_GENPRIME) MPI_CHK( mpi_sub_int( &P, &P, 1 ) ); MPI_CHK( mpi_sub_int( &Q, &Q, 1 ) ); MPI_CHK( mpi_mul_mpi( &H, &P, &Q ) ); MPI_CHK( mpi_inv_mod( &D, &E, &H ) ); mpi_write_file( " D = E^-1 mod (P-1)*(Q-1) = ", &D, 10, NULL ); #else polarssl_printf("\nTest skipped (POLARSSL_GENPRIME not defined).\n\n"); #endif MPI_CHK( mpi_read_string( &X, 10, "55555" ) ); MPI_CHK( mpi_exp_mod( &Y, &X, &E, &N, NULL ) ); MPI_CHK( mpi_exp_mod( &Z, &Y, &D, &N, NULL ) ); polarssl_printf( "\n RSA operation:\n\n" ); MPI_CHK( mpi_write_file( " X (plaintext) = ", &X, 10, NULL ) ); MPI_CHK( mpi_write_file( " Y (ciphertext) = X^E mod N = ", &Y, 10, NULL ) ); MPI_CHK( mpi_write_file( " Z (decrypted) = Y^D mod N = ", &Z, 10, NULL ) ); polarssl_printf( "\n" ); cleanup: mpi_free( &E ); mpi_free( &P ); mpi_free( &Q ); mpi_free( &N ); mpi_free( &H ); mpi_free( &D ); mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z ); if( ret != 0 ) { polarssl_printf( "\nAn error occurred.\n" ); ret = 1; } #if defined(_WIN32) polarssl_printf( " Press Enter to exit this program.\n" ); fflush( stdout ); getchar(); #endif return( ret ); }