static void write_rsa(unsigned char **out, RSA *rsa, int ispub) { int nbyte, hnbyte; const BIGNUM *n, *d, *e, *p, *q, *iqmp, *dmp1, *dmq1; nbyte = RSA_size(rsa); hnbyte = (RSA_bits(rsa) + 15) >> 4; RSA_get0_key(rsa, &n, &e, &d); write_lebn(out, e, 4); write_lebn(out, n, nbyte); if (ispub) return; RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); write_lebn(out, p, hnbyte); write_lebn(out, q, hnbyte); write_lebn(out, dmp1, hnbyte); write_lebn(out, dmq1, hnbyte); write_lebn(out, iqmp, hnbyte); write_lebn(out, d, nbyte); }
static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) { int nbyte, hnbyte, bitlen; BIGNUM *e; RSA_get0_key(rsa, &e, NULL, NULL); if (BN_num_bits(e) > 32) goto badkey; bitlen = RSA_bits(rsa); nbyte = RSA_size(rsa); hnbyte = (bitlen + 15) >> 4; if (ispub) { *pmagic = MS_RSA1MAGIC; return bitlen; } else { BIGNUM *d, *p, *q, *iqmp, *dmp1, *dmq1; *pmagic = MS_RSA2MAGIC; /* * For private key each component must fit within nbyte or hnbyte. */ RSA_get0_key(rsa, NULL, NULL, &d); if (BN_num_bytes(d) > nbyte) goto badkey; RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if ((BN_num_bytes(iqmp) > hnbyte) || (BN_num_bytes(p) > hnbyte) || (BN_num_bytes(q) > hnbyte) || (BN_num_bytes(dmp1) > hnbyte) || (BN_num_bytes(dmq1) > hnbyte)) goto badkey; } return bitlen; badkey: PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); return 0; }
static int build_decrypt_op_buf(int flen, const unsigned char *from, unsigned char *to, RSA *rsa, int padding, CpaCyRsaDecryptOpData ** dec_op_data, CpaFlatBuffer ** output_buffer, int alloc_pad) { int rsa_len = 0; CpaCyRsaPrivateKey *cpa_prv_key = NULL; const BIGNUM *p = NULL; const BIGNUM *q = NULL; const BIGNUM *dmp1 = NULL; const BIGNUM *dmq1 = NULL; const BIGNUM *iqmp = NULL; DEBUG("- Started\n"); RSA_get0_factors((const RSA*)rsa, &p, &q); RSA_get0_crt_params((const RSA*)rsa, &dmp1, &dmq1, &iqmp); if (p == NULL || q == NULL || dmp1 == NULL || dmq1 == NULL || iqmp == NULL) { WARN("Either p %p, q %p, dmp1 %p, dmq1 %p, iqmp %p are NULL\n", p, q, dmp1, dmq1, iqmp); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_IQMP_NULL); return 0; } /* Padding check */ if ((padding != RSA_NO_PADDING) && (padding != RSA_PKCS1_PADDING)) { WARN("Unknown Padding %d\n", padding); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PADDING_UNKNOWN); return 0; } cpa_prv_key = (CpaCyRsaPrivateKey *) OPENSSL_zalloc(sizeof(CpaCyRsaPrivateKey)); if (NULL == cpa_prv_key) { WARN("Failed to allocate cpa_prv_key\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_PRIV_KEY_MALLOC_FAILURE); return 0; } DEBUG("flen =%d, padding = %d \n", flen, padding); /* output signature should have same length as RSA(128) */ rsa_len = RSA_size(rsa); /* output and input data MUST allocate memory for sign process */ /* memory allocation for DecOpdata[IN] */ *dec_op_data = OPENSSL_zalloc(sizeof(CpaCyRsaDecryptOpData)); if (NULL == *dec_op_data) { WARN("Failed to allocate dec_op_data\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_DEC_OP_DATA_MALLOC_FAILURE); OPENSSL_free(cpa_prv_key); return 0; } /* Setup the DecOpData structure */ (*dec_op_data)->pRecipientPrivateKey = cpa_prv_key; cpa_prv_key->version = CPA_CY_RSA_VERSION_TWO_PRIME; /* Setup the private key rep type 2 structure */ cpa_prv_key->privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2; if (qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime1P, p) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.prime2Q, q) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent1Dp, dmp1) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.exponent2Dq, dmq1) != 1 || qat_BN_to_FB(&cpa_prv_key->privateKeyRep2.coefficientQInv, iqmp) != 1) { WARN("Failed to convert privateKeyRep2 elements to flatbuffer\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_P_Q_DMP_DMQ_CONVERT_TO_FB_FAILURE); return 0; } if (alloc_pad) { (*dec_op_data)->inputData.pData = qat_alloc_pad((Cpa8U *) from, flen, rsa_len, 1); } else { (*dec_op_data)->inputData.pData = (Cpa8U *) copyAllocPinnedMemory((void *)from, flen, __FILE__, __LINE__); } if (NULL == (*dec_op_data)->inputData.pData) { WARN("Failed to allocate (*dec_op_data)->inputData.pData\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_INPUT_DATA_MALLOC_FAILURE); return 0; } if (alloc_pad) (*dec_op_data)->inputData.dataLenInBytes = rsa_len; else (*dec_op_data)->inputData.dataLenInBytes = flen; *output_buffer = OPENSSL_malloc(sizeof(CpaFlatBuffer)); if (NULL == *output_buffer) { WARN("Failed to allocate output_buffer\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_OUTPUT_BUF_MALLOC_FAILURE); return 0; } /* * Memory allocation for DecOpdata[IN] the size of outputBuffer * should big enough to contain RSA_size */ (*output_buffer)->pData = (Cpa8U *) qaeCryptoMemAlloc(rsa_len, __FILE__, __LINE__); if (NULL == (*output_buffer)->pData) { WARN("Failed to allocate output_buffer->pData\n"); QATerr(QAT_F_BUILD_DECRYPT_OP_BUF, QAT_R_RSA_OUTPUT_BUF_PDATA_MALLOC_FAILURE); return 0; } (*output_buffer)->dataLenInBytes = rsa_len; DEBUG("- Finished\n"); return 1; }
int RSA_get_RSAPRIVATEKEYBLOB(RSA *rsa, RSAPRIVATEKEYBLOB *blob) { const BIGNUM *n; const BIGNUM *e; const BIGNUM *d; const BIGNUM *p; const BIGNUM *q; const BIGNUM *dmp1; const BIGNUM *dmq1; const BIGNUM *iqmp; if (!rsa || !blob) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } if (RSA_bits(rsa) > sizeof(blob->Modulus) * 8 || RSA_bits(rsa) % 8 != 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, ERR_R_PASSED_NULL_PARAMETER); return 0; } RSA_get0_key(rsa, &n, &e, &d); RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if (!n || !e || !d) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } memset(blob, 0, sizeof(RSAPRIVATEKEYBLOB)); blob->AlgID = SGD_RSA; blob->BitLen = RSA_bits(rsa); if (BN_bn2bin(n, blob->Modulus + sizeof(blob->Modulus) - BN_num_bytes(n)) <= 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (BN_bn2bin(e, blob->PublicExponent + sizeof(blob->PublicExponent) - BN_num_bytes(e)) <= 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (BN_bn2bin(d, blob->PrivateExponent + sizeof(blob->PrivateExponent) - BN_num_bytes(d)) <= 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (p && BN_bn2bin(p, blob->Prime1 + sizeof(blob->Prime1) - BN_num_bytes(p)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (q && BN_bn2bin(q, blob->Prime2 + sizeof(blob->Prime2) - BN_num_bytes(q)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (dmp1 && BN_bn2bin(dmp1, blob->Prime1Exponent + sizeof(blob->Prime1Exponent) - BN_num_bytes(dmp1)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (dmq1 && BN_bn2bin(dmq1, blob->Prime2Exponent + sizeof(blob->Prime2Exponent) - BN_num_bytes(dmq1)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } if (iqmp && BN_bn2bin(iqmp, blob->Coefficient + sizeof(blob->Coefficient) - BN_num_bytes(iqmp)) < 0) { GMAPIerr(GMAPI_F_RSA_GET_RSAPRIVATEKEYBLOB, GMAPI_R_INVALID_RSA_PRIVATE_KEY); return 0; } return 1; }
static isc_result_t opensslrsa_tofile(const dst_key_t *key, const char *directory) { int i; RSA *rsa; dst_private_t priv; unsigned char *bufs[8]; isc_result_t result; const BIGNUM *n = NULL, *e = NULL, *d = NULL; const BIGNUM *p = NULL, *q = NULL; const BIGNUM *dmp1 = NULL, *dmq1 = NULL, *iqmp = NULL; #if USE_EVP if (key->keydata.pkey == NULL) return (DST_R_NULLKEY); rsa = EVP_PKEY_get1_RSA(key->keydata.pkey); if (rsa == NULL) return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); #else if (key->keydata.rsa == NULL) return (DST_R_NULLKEY); rsa = key->keydata.rsa; #endif memset(bufs, 0, sizeof(bufs)); RSA_get0_key(rsa, &n, &e, &d); RSA_get0_factors(rsa, &p, &q); RSA_get0_crt_params(rsa, &dmp1, &dmq1, &iqmp); if (key->external) { priv.nelements = 0; result = dst__privstruct_writefile(key, &priv, directory); goto fail; } for (i = 0; i < 8; i++) { bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(n)); if (bufs[i] == NULL) { result = ISC_R_NOMEMORY; goto fail; } } i = 0; priv.elements[i].tag = TAG_RSA_MODULUS; priv.elements[i].length = BN_num_bytes(n); BN_bn2bin(n, bufs[i]); priv.elements[i].data = bufs[i]; i++; priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT; priv.elements[i].length = BN_num_bytes(e); BN_bn2bin(e, bufs[i]); priv.elements[i].data = bufs[i]; i++; if (d != NULL) { priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT; priv.elements[i].length = BN_num_bytes(d); BN_bn2bin(d, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (p != NULL) { priv.elements[i].tag = TAG_RSA_PRIME1; priv.elements[i].length = BN_num_bytes(p); BN_bn2bin(p, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (q != NULL) { priv.elements[i].tag = TAG_RSA_PRIME2; priv.elements[i].length = BN_num_bytes(q); BN_bn2bin(q, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (dmp1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT1; priv.elements[i].length = BN_num_bytes(dmp1); BN_bn2bin(dmp1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (dmq1 != NULL) { priv.elements[i].tag = TAG_RSA_EXPONENT2; priv.elements[i].length = BN_num_bytes(dmq1); BN_bn2bin(dmq1, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (iqmp != NULL) { priv.elements[i].tag = TAG_RSA_COEFFICIENT; priv.elements[i].length = BN_num_bytes(iqmp); BN_bn2bin(iqmp, bufs[i]); priv.elements[i].data = bufs[i]; i++; } if (key->engine != NULL) { priv.elements[i].tag = TAG_RSA_ENGINE; priv.elements[i].length = (unsigned short)strlen(key->engine) + 1; priv.elements[i].data = (unsigned char *)key->engine; i++; } if (key->label != NULL) { priv.elements[i].tag = TAG_RSA_LABEL; priv.elements[i].length = (unsigned short)strlen(key->label) + 1; priv.elements[i].data = (unsigned char *)key->label; i++; } priv.nelements = i; result = dst__privstruct_writefile(key, &priv, directory); fail: #if USE_EVP RSA_free(rsa); #endif for (i = 0; i < 8; i++) { if (bufs[i] == NULL) break; isc_mem_put(key->mctx, bufs[i], BN_num_bytes(n)); } return (result); }
/** Sets the tag-designated key component into the established RSA context. This function sets the tag-designated RSA key component into the established RSA context from the user-specified non-negative integer (octet string format represented in RSA PKCS#1). If BigNumber is NULL, then the specified key component in RSA context is cleared. If RsaContext is NULL, then return FALSE. @param[in, out] RsaContext Pointer to RSA context being set. @param[in] KeyTag Tag of RSA key component being set. @param[in] BigNumber Pointer to octet integer buffer. If NULL, then the specified key component in RSA context is cleared. @param[in] BnSize Size of big number buffer in bytes. If BigNumber is NULL, then it is ignored. @retval TRUE RSA key component was set successfully. @retval FALSE Invalid RSA key component tag. **/ BOOLEAN EFIAPI RsaSetKey ( IN OUT VOID *RsaContext, IN RSA_KEY_TAG KeyTag, IN CONST UINT8 *BigNumber, IN UINTN BnSize ) { RSA *RsaKey; BIGNUM *BnN; BIGNUM *BnE; BIGNUM *BnD; BIGNUM *BnP; BIGNUM *BnQ; BIGNUM *BnDp; BIGNUM *BnDq; BIGNUM *BnQInv; // // Check input parameters. // if (RsaContext == NULL || BnSize > INT_MAX) { return FALSE; } BnN = NULL; BnE = NULL; BnD = NULL; BnP = NULL; BnQ = NULL; BnDp = NULL; BnDq = NULL; BnQInv = NULL; // // Retrieve the components from RSA object. // RsaKey = (RSA *) RsaContext; RSA_get0_key (RsaKey, (const BIGNUM **)&BnN, (const BIGNUM **)&BnE, (const BIGNUM **)&BnD); RSA_get0_factors (RsaKey, (const BIGNUM **)&BnP, (const BIGNUM **)&BnQ); RSA_get0_crt_params (RsaKey, (const BIGNUM **)&BnDp, (const BIGNUM **)&BnDq, (const BIGNUM **)&BnQInv); // // Set RSA Key Components by converting octet string to OpenSSL BN representation. // NOTE: For RSA public key (used in signature verification), only public components // (N, e) are needed. // switch (KeyTag) { // // RSA Public Modulus (N), Public Exponent (e) and Private Exponent (d) // case RsaKeyN: case RsaKeyE: case RsaKeyD: if (BnN == NULL) { BnN = BN_new (); } if (BnE == NULL) { BnE = BN_new (); } if (BnD == NULL) { BnD = BN_new (); } if ((BnN == NULL) || (BnE == NULL) || (BnD == NULL)) { return FALSE; } switch (KeyTag) { case RsaKeyN: BnN = BN_bin2bn (BigNumber, (UINT32)BnSize, BnN); break; case RsaKeyE: BnE = BN_bin2bn (BigNumber, (UINT32)BnSize, BnE); break; case RsaKeyD: BnD = BN_bin2bn (BigNumber, (UINT32)BnSize, BnD); break; default: return FALSE; } if (RSA_set0_key (RsaKey, BN_dup(BnN), BN_dup(BnE), BN_dup(BnD)) == 0) { return FALSE; } break; // // RSA Secret Prime Factor of Modulus (p and q) // case RsaKeyP: case RsaKeyQ: if (BnP == NULL) { BnP = BN_new (); } if (BnQ == NULL) { BnQ = BN_new (); } if ((BnP == NULL) || (BnQ == NULL)) { return FALSE; } switch (KeyTag) { case RsaKeyP: BnP = BN_bin2bn (BigNumber, (UINT32)BnSize, BnP); break; case RsaKeyQ: BnQ = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQ); break; default: return FALSE; } if (RSA_set0_factors (RsaKey, BN_dup(BnP), BN_dup(BnQ)) == 0) { return FALSE; } break; // // p's CRT Exponent (== d mod (p - 1)), q's CRT Exponent (== d mod (q - 1)), // and CRT Coefficient (== 1/q mod p) // case RsaKeyDp: case RsaKeyDq: case RsaKeyQInv: if (BnDp == NULL) { BnDp = BN_new (); } if (BnDq == NULL) { BnDq = BN_new (); } if (BnQInv == NULL) { BnQInv = BN_new (); } if ((BnDp == NULL) || (BnDq == NULL) || (BnQInv == NULL)) { return FALSE; } switch (KeyTag) { case RsaKeyDp: BnDp = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDp); break; case RsaKeyDq: BnDq = BN_bin2bn (BigNumber, (UINT32)BnSize, BnDq); break; case RsaKeyQInv: BnQInv = BN_bin2bn (BigNumber, (UINT32)BnSize, BnQInv); break; default: return FALSE; } if (RSA_set0_crt_params (RsaKey, BN_dup(BnDp), BN_dup(BnDq), BN_dup(BnQInv)) == 0) { return FALSE; } break; default: return FALSE; } return TRUE; }