uint8_t * rsa_genkey (void) { int r; uint8_t index = 0; uint8_t *p_q_modulus = (uint8_t *)malloc (KEY_CONTENT_LEN*2); uint8_t *p = p_q_modulus; uint8_t *q = p_q_modulus + KEY_CONTENT_LEN/2; uint8_t *modulus = p_q_modulus + KEY_CONTENT_LEN; if (p_q_modulus == NULL) return NULL; rsa_init (&rsa_ctx, RSA_PKCS_V15, 0); r = rsa_gen_key (&rsa_ctx, random_byte, &index, KEY_CONTENT_LEN * 8, RSA_EXPONENT); if (r < 0) { free (p_q_modulus); rsa_free (&rsa_ctx); return NULL; } mpi_write_binary (&rsa_ctx.P, p, KEY_CONTENT_LEN/2); mpi_write_binary (&rsa_ctx.Q, q, KEY_CONTENT_LEN/2); mpi_write_binary (&rsa_ctx.N, modulus, KEY_CONTENT_LEN); rsa_free (&rsa_ctx); return p_q_modulus; }
/* * 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 ); }
/* * Derive and export the shared secret (G^Y)^X mod P */ int dhm_calc_secret( dhm_context *ctx, unsigned char *output, size_t *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 ) ); if( ( ret = dhm_check_range( &ctx->GY, &ctx->P ) ) != 0 ) return( ret ); *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, 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 ); }
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); }
int asn1_write_mpi( unsigned char **p, unsigned char *start, mpi *X ) { int ret; size_t len = 0; // Write the MPI // len = mpi_size( X ); if( *p - start < (int) len ) return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); (*p) -= len; MPI_CHK( mpi_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 ); }
/* * 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 ); }
void cmd_genkey(char *bits) { // generate RSA key pair int key_bits; size_t key_bytes; key_bits = atoi(bits); key_bytes = key_bits >> 3; if ((key_bits & 0x7) > 0) key_bytes++; uint8_t pubkey[key_bytes]; uint8_t seckey[key_bytes]; rsa_context rsa; rsa_key_generate(pubkey, seckey, &rsa, key_bits); uint8_t P[key_bytes]; uint8_t Q[key_bytes]; uint8_t E[key_bytes]; mpi_write_binary(&rsa.P, P, key_bytes); mpi_write_binary(&rsa.Q, Q, key_bytes); mpi_write_binary(&rsa.E, E, key_bytes); char *pubkey_str = fmt_bytes(pubkey, key_bytes); char *seckey_str = fmt_bytes(seckey, key_bytes); char *p_str = fmt_bytes(P, key_bytes); char *q_str = fmt_bytes(Q, key_bytes); char *e_str = fmt_bytes(E, key_bytes); printf("# generated config\n"); printf("PUBKEY: %s\n", pubkey_str); printf("SECKEY: %s\n", seckey_str); printf("P: %s\n", p_str); printf("Q: %s\n", q_str); printf("E: %s\n", e_str); free(pubkey_str); free(seckey_str); free(p_str); free(q_str); free(e_str); }
static int Btotext(lua_State *L) { mpi *a = Bget(L,1); int n = mpi_size(a); unsigned char *s = (unsigned char *) malloc(n); if (s == NULL) return 0; mpi_write_binary(a, s, n); lua_pushlstring(L, (const char *) s, n); free(s); return 1; }
// func. to ECDSA sign the SPP sections int sign_spp(u8* pInSpp) { u8 *r, *s = NULL; u8 hash[20] = {0}; u64 sig_len = 0; mpi r1; mpi s1; int retval = -1; // validate input params if (pInSpp == NULL) goto exit; // init the mpi mpi_init(&r1); mpi_init(&s1); // setup the 'signature len' sig_len = be64(pInSpp + 0x60); r = pInSpp + sig_len; s = r + 21; // sha1 the hash sha1(pInSpp, (size_t)sig_len, hash); // ecdsa sign the hash if ( ecdsa_sign(&ecdsa_ctx.grp, (mpi*)&r1, (mpi*)&s1, &ecdsa_ctx.d, hash, ECDSA_KEYSIZE_PRIV, get_random_char, NULL) == STATUS_SUCCESS ) { mpi_write_binary(&r1, (unsigned char*)r, ECDSA_KEYSIZE_PRIV); mpi_write_binary(&s1, (unsigned char*)s, ECDSA_KEYSIZE_PRIV); // status success retval = STATUS_SUCCESS; } exit: return retval; }
/* 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; }
/* * LEN: length in byte */ uint8_t * modulus_calc (const uint8_t *p, int len) { mpi P, Q, N; uint8_t *modulus; modulus = malloc (len); if (modulus == NULL) return NULL; mpi_init (&P, &Q, &N, NULL); mpi_read_binary (&P, p, len / 2); mpi_read_binary (&Q, p + len / 2, len / 2); mpi_mul_mpi (&N, &P, &Q); mpi_write_binary (&N, modulus, len); mpi_free (&P, &Q, &N, NULL); return modulus; }
/* * Derive and export the shared secret */ int ecdh_calc_secret( ecdh_context *ctx, size_t *olen, unsigned char *buf, size_t blen, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng ) { int ret; if( ctx == NULL ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); if( ( ret = ecdh_compute_shared( &ctx->grp, &ctx->z, &ctx->Qp, &ctx->d, f_rng, p_rng ) ) != 0 ) { return( ret ); } if( mpi_size( &ctx->z ) > blen ) return( POLARSSL_ERR_ECP_BAD_INPUT_DATA ); *olen = ctx->grp.pbits / 8 + ( ( ctx->grp.pbits % 8 ) != 0 ); return mpi_write_binary( &ctx->z, buf, *olen ); }
/* * 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; }
void cmd_sign(char *conf, char *key) { rsa_sig_t sign; rsa_key_t pubkey; rsa_key_t seckey; rsa_context *ctx; sigstruct_t *sigstruct; // Load sigstruct from file sigstruct = load_sigstruct(conf); // Ignore fields don't need to sign memset(sigstruct->modulus, 0, 384); sigstruct->exponent = 0; memset(sigstruct->signature, 0, 384); memset(sigstruct->q1, 0, 384); memset(sigstruct->q2, 0, 384); // Load rsa keys from file ctx = load_rsa_keys(key, pubkey, seckey, KEY_LENGTH_BITS); #if 0 { char *pubkey_str = fmt_bytes(pubkey, KEY_LENGTH); char *seckey_str = fmt_bytes(seckey, KEY_LENGTH); printf("PUBKEY: %.40s..\n", pubkey_str); printf("SECKEY: %.40s..\n", seckey_str); free(pubkey_str); free(seckey_str); } #endif // Generate rsa sign on sigstruct with private key rsa_sign(ctx, sign, (unsigned char *)sigstruct, sizeof(sigstruct_t)); // Compute q1, q2 unsigned char *q1, *q2; q1 = malloc(384); q2 = malloc(384); memset(q1, 0, 384); memset(q2, 0, 384); mpi Q1, Q2, S, M, T1, T2, R; mpi_init(&Q1); mpi_init(&Q2); mpi_init(&S); mpi_init(&M); mpi_init(&T1); mpi_init(&T2); mpi_init(&R); // q1 = signature ^ 2 / modulus mpi_read_binary(&S, sign, 384); mpi_read_binary(&M, pubkey, 384); mpi_mul_mpi(&T1, &S, &S); mpi_div_mpi(&Q1, &R, &T1, &M); // q2 = (signature ^ 3 - q1 * signature * modulus) / modulus mpi_init(&R); mpi_mul_mpi(&T1, &T1, &S); mpi_mul_mpi(&T2, &Q1, &S); mpi_mul_mpi(&T2, &T2, &M); mpi_sub_mpi(&Q2, &T1, &T2); mpi_div_mpi(&Q2, &R, &Q2, &M); mpi_write_binary(&Q1, q1, 384); mpi_write_binary(&Q2, q2, 384); mpi_free(&Q1); mpi_free(&Q2); mpi_free(&S); mpi_free(&M); mpi_free(&T1); mpi_free(&T2); mpi_free(&R); sigstruct = load_sigstruct(conf); sigstruct->exponent = 3; memcpy(sigstruct->modulus, pubkey, 384); memcpy(sigstruct->signature, sign, 384); memcpy(sigstruct->q1, q1, 384); memcpy(sigstruct->q2, q2, 384); char *msg = dump_sigstruct(sigstruct); printf("# SIGSTRUCT START\n"); printf("%s\n", msg); printf("# SIGSTRUCT END\n"); /*unsigned char exp[4] = { 0x00, 0x00, 0x00, 0x03 }; char *mod_str = fmt_bytes(pubkey, 384); char *exp_str = fmt_bytes(exp, 4); char *sign_str = fmt_bytes(sign, 384); char *q1_str = fmt_bytes(q1, 384); char *q2_str = fmt_bytes(q2, 384); printf("# sign information\n"); printf("MODULUS : %s\n", mod_str); printf("EXPONENT : %s\n", exp_str); printf("SIGNATURE : %s\n", sign_str); printf("Q1 : %s\n", q1_str); printf("Q2 : %s\n", q2_str); free(mod_str); free(exp_str); free(sign_str); unsigned char signer[32]; sha256(pubkey, KEY_LENGTH, signer, 0); char *signer_str = fmt_bytes(pubkey, 32); printf("# hash of public key\n"); printf("MRSIGNER : %s\n", signer_str);*/ }
/** * 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 ); }