int rsa_decrypt (const uint8_t *input, uint8_t *output, int msg_len, struct key_data *kd) { mpi P1, Q1, H; int r; int output_len; DEBUG_INFO ("RSA decrypt:"); DEBUG_WORD ((uint32_t)&output_len); mpi_init (&P1, &Q1, &H, NULL); rsa_init (&rsa_ctx, RSA_PKCS_V15, 0); rsa_ctx.len = msg_len; DEBUG_WORD (msg_len); mpi_lset (&rsa_ctx.E, 0x10001); mpi_read_binary (&rsa_ctx.P, &kd->data[0], KEY_CONTENT_LEN / 2); mpi_read_binary (&rsa_ctx.Q, &kd->data[KEY_CONTENT_LEN/2], KEY_CONTENT_LEN / 2); #if 0 /* Using CRT, we don't use N */ mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q); #endif mpi_sub_int (&P1, &rsa_ctx.P, 1); mpi_sub_int (&Q1, &rsa_ctx.Q, 1); mpi_mul_mpi (&H, &P1, &Q1); mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H); mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1); mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1); mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P); mpi_free (&P1, &Q1, &H, NULL); DEBUG_INFO ("RSA decrypt ..."); r = rsa_pkcs1_decrypt (&rsa_ctx, RSA_PRIVATE, &output_len, input, output, MAX_RES_APDU_DATA_SIZE); rsa_free (&rsa_ctx); if (r < 0) { DEBUG_INFO ("fail:"); DEBUG_SHORT (r); return r; } else { res_APDU_size = output_len; DEBUG_INFO ("done.\r\n"); GPG_SUCCESS (); return 0; } }
int EsSign::RsaVerify(const u8* hash, const u8* modulus, const u8* signature) { static const u8 public_exponent[3] = { 0x01, 0x00, 0x01 }; int ret; EsSignType type; rsa_context rsa; int hash_id = 0; int hash_len = 0; rsa_init(&rsa, RSA_PKCS_V15, hash_id); if (hash == NULL || modulus == NULL || signature == NULL) return 1; // get signature type type = (EsSignType)be_word(*((u32*)(signature))); switch (type) { case(ES_SIGN_RSA4096_SHA1) : case(ES_SIGN_RSA4096_SHA256) : { rsa.len = Crypto::kRsa4096Size; hash_id = (type == ES_SIGN_RSA4096_SHA1) ? SIG_RSA_SHA1 : SIG_RSA_SHA256; hash_len = (type == ES_SIGN_RSA4096_SHA1) ? Crypto::kSha1HashLen : Crypto::kSha256HashLen; break; } case(ES_SIGN_RSA2048_SHA1) : case(ES_SIGN_RSA2048_SHA256) : { rsa.len = Crypto::kRsa2048Size; hash_id = (type == ES_SIGN_RSA2048_SHA1) ? SIG_RSA_SHA1 : SIG_RSA_SHA256; hash_len = (type == ES_SIGN_RSA2048_SHA1) ? Crypto::kSha1HashLen : Crypto::kSha256HashLen; break; } default: return 1; } mpi_read_binary(&rsa.E, public_exponent, sizeof(public_exponent)); mpi_read_binary(&rsa.N, modulus, rsa.len); ret = rsa_rsassa_pkcs1_v15_verify(&rsa, RSA_PRIVATE, hash_id, hash_len, hash, signature + 4); rsa_free(&rsa); return ret; }
int rsa_verify (const uint8_t *pubkey, const uint8_t *hash, const uint8_t *sig) { int r; rsa_init (&rsa_ctx, RSA_PKCS_V15, 0); rsa_ctx.len = KEY_CONTENT_LEN; mpi_lset (&rsa_ctx.E, 0x10001); mpi_read_binary (&rsa_ctx.N, pubkey, KEY_CONTENT_LEN); DEBUG_INFO ("RSA verify..."); r = rsa_pkcs1_verify (&rsa_ctx, RSA_PUBLIC, SIG_RSA_SHA256, 32, hash, sig); rsa_free (&rsa_ctx); if (r < 0) { DEBUG_INFO ("fail:"); DEBUG_SHORT (r); return r; } else { DEBUG_INFO ("verified.\r\n"); return 0; } }
int Crypto::SignRsa2048Sha256(const u8 modulus[kRsa2048Size], const u8 private_exponent[kRsa2048Size], const u8 hash[kSha256HashLen], u8 signature[kRsa2048Size]) { int ret; rsa_context ctx; rsa_init(&ctx, RSA_PKCS_V15, 0); ctx.len = kRsa2048Size; mpi_read_binary(&ctx.D, private_exponent, ctx.len); mpi_read_binary(&ctx.N, modulus, ctx.len); ret = rsa_rsassa_pkcs1_v15_sign(&ctx, RSA_PRIVATE, SIG_RSA_SHA256, kSha256HashLen, hash, signature); rsa_free(&ctx); return ret; }
result_t X509Cert::get_serial(std::string &retVal) { x509_crt *crt = get_crt(); if (!crt) return CHECK_ERROR(CALL_E_INVALID_CALL); int ret; mpi serial; mpi_init(&serial); ret = mpi_read_binary(&serial, crt->serial.p, crt->serial.len); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(8192); size_t sz = retVal.length(); ret = mpi_write_string(&serial, 10, &retVal[0], &sz); mpi_free(&serial); if (ret != 0) return CHECK_ERROR(_ssl::setError(ret)); retVal.resize(sz - 1); return 0; }
char * backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) { char *buf = NULL; size_t buflen = 0; mpi serial_mpi = { 0 }; /* Transform asn1 integer serial into PolarSSL MPI */ mpi_init(&serial_mpi); if (!polar_ok(mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len))) { msg(M_WARN, "Failed to retrieve serial from certificate."); return NULL; } /* Determine decimal representation length, allocate buffer */ mpi_write_string(&serial_mpi, 10, buf, &buflen); buf = gc_malloc(buflen, true, gc); /* Write MPI serial as decimal string into buffer */ if (!polar_ok(mpi_write_string(&serial_mpi, 10, buf, &buflen))) { msg(M_WARN, "Failed to write serial to string."); return NULL; } return buf; }
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; }
/* * 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_sign (const uint8_t *raw_message, uint8_t *output, int msg_len, struct key_data *kd) { mpi P1, Q1, H; int r; unsigned char temp[RSA_SIGNATURE_LENGTH]; mpi_init (&P1, &Q1, &H, NULL); rsa_init (&rsa_ctx, RSA_PKCS_V15, 0); rsa_ctx.len = KEY_CONTENT_LEN; mpi_lset (&rsa_ctx.E, 0x10001); mpi_read_binary (&rsa_ctx.P, &kd->data[0], rsa_ctx.len / 2); mpi_read_binary (&rsa_ctx.Q, &kd->data[KEY_CONTENT_LEN/2], rsa_ctx.len / 2); #if 0 /* Using CRT, we don't use N */ mpi_mul_mpi (&rsa_ctx.N, &rsa_ctx.P, &rsa_ctx.Q); #endif mpi_sub_int (&P1, &rsa_ctx.P, 1); mpi_sub_int (&Q1, &rsa_ctx.Q, 1); mpi_mul_mpi (&H, &P1, &Q1); mpi_inv_mod (&rsa_ctx.D , &rsa_ctx.E, &H); mpi_mod_mpi (&rsa_ctx.DP, &rsa_ctx.D, &P1); mpi_mod_mpi (&rsa_ctx.DQ, &rsa_ctx.D, &Q1); mpi_inv_mod (&rsa_ctx.QP, &rsa_ctx.Q, &rsa_ctx.P); mpi_free (&P1, &Q1, &H, NULL); DEBUG_INFO ("RSA sign..."); r = rsa_pkcs1_sign (&rsa_ctx, RSA_PRIVATE, SIG_RSA_RAW, msg_len, raw_message, temp); memcpy (output, temp, RSA_SIGNATURE_LENGTH); rsa_free (&rsa_ctx); if (r < 0) { DEBUG_INFO ("fail:"); DEBUG_SHORT (r); return r; } else { res_APDU_size = RSA_SIGNATURE_LENGTH; DEBUG_INFO ("done.\r\n"); GPG_SUCCESS (); return 0; } }
int EsSign::RsaSign(EsSignType type, const u8* hash, const u8* modulus, const u8* priv_exp, u8* signature) { int ret; rsa_context rsa; int hash_id = 0; int hash_len = 0; rsa_init(&rsa, RSA_PKCS_V15, hash_id); if (hash == NULL || modulus == NULL || priv_exp == NULL || signature == NULL) return 1; switch (type) { case(ES_SIGN_RSA4096_SHA1) : case(ES_SIGN_RSA4096_SHA256) : { rsa.len = Crypto::kRsa4096Size; hash_id = (type == ES_SIGN_RSA4096_SHA1) ? SIG_RSA_SHA1 : SIG_RSA_SHA256; hash_len = (type == ES_SIGN_RSA4096_SHA1) ? Crypto::kSha1HashLen : Crypto::kSha256HashLen; memset(signature, 0, sizeof(kRsa4096SignLen)); break; } case(ES_SIGN_RSA2048_SHA1) : case(ES_SIGN_RSA2048_SHA256) : { rsa.len = Crypto::kRsa2048Size; hash_id = (type == ES_SIGN_RSA2048_SHA1) ? SIG_RSA_SHA1 : SIG_RSA_SHA256; hash_len = (type == ES_SIGN_RSA2048_SHA1) ? Crypto::kSha1HashLen : Crypto::kSha256HashLen; memset(signature, 0, sizeof(kRsa2048SignLen)); break; } default: return 1; } mpi_read_binary(&rsa.D, priv_exp, rsa.len); mpi_read_binary(&rsa.N, modulus, rsa.len); // set signature id *((u32*)(signature)) = be_word(type); ret = rsa_rsassa_pkcs1_v15_sign(&rsa, RSA_PRIVATE, hash_id, hash_len, hash, (signature + 4)); rsa_free(&rsa); 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 ); }
// Initialize peripheral UART upgrade procedure int ws_upgrade_ota_init(void) { ws_upgrade_state = WS_UPGRADE_STATE_IDLE; // register memory management function brcmcryptoglue_set_allocator(cfa_mm_Alloc); brcmcryptoglue_set_deallocator(cfa_mm_Free); // initialize padding scheme and hash algorithm rsa_init(&rsaCtx, RSA_PKCS_V21, POLARSSL_MD_SHA256); mpi_read_binary( &rsaCtx.E, &rsa_pub_key[0], 3); mpi_read_binary( &rsaCtx.N, &rsa_pub_key[3], WS_UPGRADE_RSA_SIGNATURE_LEN + 1); ws_upgrade_init(); return TRUE; }
static int Btext(lua_State *L) { size_t l; const char *s=luaL_checklstring(L,1,&l); mpi *a=Bnew(L); mpi_read_binary(a, (unsigned char *) s, l); return 1; }
int Crypto::VerifyRsa2048Sha256(const u8 modulus[kRsa2048Size], const u8 hash[kSha256HashLen], const u8 signature[kRsa2048Size]) { static const u8 public_exponent[3] = { 0x01, 0x00, 0x01 }; int ret; rsa_context ctx; rsa_init(&ctx, RSA_PKCS_V15, 0); ctx.len = kRsa2048Size; mpi_read_binary(&ctx.E, public_exponent, sizeof(public_exponent)); mpi_read_binary(&ctx.N, modulus, ctx.len); ret = rsa_rsassa_pkcs1_v15_verify(&ctx, RSA_PUBLIC, SIG_RSA_SHA256, kSha256HashLen, hash, signature); rsa_free(&ctx); return ret; }
void init_rsa_context_with_public_key(rsa_context *rsa, const unsigned char *pubkey) { rsa_init(rsa, RSA_PKCS_V15, RSA_RAW, NULL, NULL); rsa->len = 256; mpi_read_binary(&rsa->N, pubkey + 33, 256); mpi_read_string(&rsa->E, 16, "10001"); }
/* * 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; }
void crypto_rsa_encrypt(int len, uint8 * in, uint8 * out, uint32 modulus_size, uint8 * modulus, uint8 * exponent) { rsa_context ctx; rsa_init(&ctx, 0, 0); ctx.len = modulus_size; mpi_init(&ctx.N, &ctx.E, NULL); mpi_read_binary(&ctx.N, modulus, modulus_size); mpi_read_binary(&ctx.E, exponent, SEC_EXPONENT_SIZE); ASSERT(!rsa_check_pubkey( &ctx )); ASSERT(modulus_size <= SEC_MAX_MODULUS_SIZE); uint8 in2[SEC_MAX_MODULUS_SIZE]; memset(in2, 0, modulus_size - len); memcpy(in2 + modulus_size - len, in, len); int err = rsa_public(&ctx, in2, out); ASSERT(!err); mpi_free(&ctx.N, &ctx.E, NULL); rsa_free(&ctx); }
bool RsaKeyInit(rsa_context* ctx, u8 *modulus, u8 *private_exp, u8 *exponent, u8 rsa_type) { // Sanity Check if(!ctx) return false; rsa_init(ctx, RSA_PKCS_V15, 0); u16 n_size = 0; u16 d_size = 0; u16 e_size = 0; switch(rsa_type){ case RSA_2048: ctx->len = 0x100; n_size = 0x100; d_size = 0x100; e_size = 3; break; case RSA_4096: ctx->len = 0x200; n_size = 0x200; d_size = 0x200; e_size = 3; break; default: return false; } if (modulus && mpi_read_binary(&ctx->N, modulus, n_size)) goto clean; if (exponent && mpi_read_binary(&ctx->E, exponent, e_size)) goto clean; if (private_exp && mpi_read_binary(&ctx->D, private_exp, d_size)) goto clean; return true; clean: rsa_free(ctx); return false; }
/* * Import the peer's public value G^Y */ int dhm_read_public (dhm_context * ctx, unsigned char* input, int ilen) { int ret; if (ctx == NULL || ilen < 1 || ilen > ctx->len) return (POLARSSL_ERR_DHM_BAD_INPUT_DATA); if ((ret = mpi_read_binary (&ctx->GY, input, ilen)) != 0) return (POLARSSL_ERR_DHM_READ_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; }
/* 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; }
static int asn1_get_mpi( unsigned char **p, const unsigned char *end, mpi *X ) { int ret, len; if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) return( ret ); ret = mpi_read_binary( X, *p, len ); *p += len; return( ret ); }
void init_rsa_context_with_public_key(rsa_context *rsa, const unsigned char *pubkey) { #ifdef USE_MBEDTLS mbedtls_rsa_init(rsa, MBEDTLS_RSA_PKCS_V15, 0); #else rsa_init(rsa, RSA_PKCS_V15, RSA_RAW, NULL, NULL); #endif #if !defined(USE_MBEDTLS) && (PLATFORM_ID == 6 || PLATFORM_ID == 8) rsa->length = 256; #else rsa->len = 256; #endif mpi_read_binary(&rsa->N, pubkey + 33, 256); mpi_read_string(&rsa->E, 16, "10001"); }
SSL_ROM_TEXT_SECTION int asn1_get_mpi( unsigned char **p, const unsigned char *end, mpi *X ) { int ret; size_t len; if( ( ret = asn1_get_tag( p, end, &len, ASN1_INTEGER ) ) != 0 ) return( ret ); ret = mpi_read_binary( X, *p, len ); *p += len; return( ret ); }
/* * helper to validate the mpi size and import it */ static int dhm_read_bignum (mpi * X, unsigned char** p, unsigned char* end) { int ret, n; if (end - *p < 2) return (POLARSSL_ERR_DHM_BAD_INPUT_DATA); n = ((*p)[0] << 8) | (*p)[1]; (*p) += 2; if ((int) (end - *p) < n) return (POLARSSL_ERR_DHM_BAD_INPUT_DATA); if ((ret = mpi_read_binary (X, *p, n)) != 0) return (POLARSSL_ERR_DHM_READ_PARAMS_FAILED | ret); (*p) += n; return (0); }
int ctr_rsa_init(ctr_rsa_context* ctx, rsakey2048* key) { rsa_init(&ctx->rsa, RSA_PKCS_V15, 0); ctx->rsa.len = 0x100; if (key->keytype == RSAKEY_INVALID) goto clean; if (mpi_read_binary(&ctx->rsa.N, key->n, sizeof(key->n))) goto clean; if (mpi_read_binary(&ctx->rsa.E, key->e, sizeof(key->e))) goto clean; if (rsa_check_pubkey(&ctx->rsa)) goto clean; if (key->keytype == RSAKEY_PRIV) { if (mpi_read_binary(&ctx->rsa.D, key->d, sizeof(key->d))) goto clean; if (mpi_read_binary(&ctx->rsa.P, key->p, sizeof(key->p))) goto clean; if (mpi_read_binary(&ctx->rsa.Q, key->q, sizeof(key->q))) goto clean; if (mpi_read_binary(&ctx->rsa.DP, key->dp, sizeof(key->dp))) goto clean; if (mpi_read_binary(&ctx->rsa.DQ, key->dq, sizeof(key->dq))) goto clean; if (mpi_read_binary(&ctx->rsa.QP, key->qp, sizeof(key->qp))) goto clean; if (rsa_check_privkey(&ctx->rsa)) goto clean; } return 1; clean: 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 ); }
char * backend_x509_get_serial (openvpn_x509_cert_t *cert, struct gc_arena *gc) { char *buf = NULL; size_t buflen = 0; mpi serial_mpi = { 0 }; int retval = 0; /* Transform asn1 integer serial into PolarSSL MPI */ mpi_init(&serial_mpi); retval = mpi_read_binary(&serial_mpi, cert->serial.p, cert->serial.len); if (retval < 0) { char errbuf[128]; polarssl_strerror(retval, errbuf, sizeof(errbuf)); msg(M_WARN, "Failed to retrieve serial from certificate: %s.", errbuf); return NULL; } /* Determine decimal representation length, allocate buffer */ mpi_write_string(&serial_mpi, 10, buf, &buflen); buf = gc_malloc(buflen, true, gc); /* Write MPI serial as decimal string into buffer */ retval = mpi_write_string(&serial_mpi, 10, buf, &buflen); if (retval < 0) { char errbuf[128]; polarssl_strerror(retval, errbuf, sizeof(errbuf)); msg(M_WARN, "Failed to write serial to string: %s.", errbuf); return NULL; } return buf; }
/* * 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 ); }
/** * 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 ); }