Init SoftHSMv2 support

- wolfSSL_EVP_PKEY_set1_DH: If both private and public present, output private key
- ToTraditionalInline_ex2: Add DH checking
- wc_ecc_get_curve_id: check index is not negative
- Fix i2d_PKCS8_PRIV_KEY_INFO to actually output pkcs8 instead of just der
- wolfSSL_EVP_PKEY2PKCS8: Create duplicate to avoid double free
- wolfSSL_DH_generate_key: Fix case where not enough buffer was allocated for 128 bit case
- pkcs8_encode: Add DSA and DH support
- wolfSSL_d2i_PKCS8_PKEY: Correctly advance buffer
- RSA_LOW_MEM: export all integers in compat layer
- Add softhsm action
- Define
  - OPENSSL_DH_MAX_MODULUS_BITS
  - OPENSSL_DSA_MAX_MODULUS_BITS
  - OPENSSL_RSA_MAX_MODULUS_BITS
- Implement
  - BN_mul_word
  - i2d_ECPKParameters
  - PEM_write_bio_PKCS8_PRIV_KEY_INFO
  - PEM_read_bio_PKCS8_PRIV_KEY_INFO
  - i2d_PKCS8_PRIV_KEY_INFO
  - RSA_padding_add_PKCS1_PSS_mgf1
  - RSA_verify_PKCS1_PSS_mgf1
This commit is contained in:
Juliusz Sosinowicz
2024-08-27 15:26:46 +02:00
parent ef063aac2f
commit 901384e704
19 changed files with 569 additions and 73 deletions

234
src/pk.c
View File

@@ -2598,6 +2598,7 @@ int SetRsaExternal(WOLFSSL_RSA* rsa)
}
if (key->type == RSA_PRIVATE) {
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
if (ret == 1) {
/* Copy private exponent. */
ret = wolfssl_bn_set_value(&rsa->d, &key->d);
@@ -2619,7 +2620,8 @@ int SetRsaExternal(WOLFSSL_RSA* rsa)
WOLFSSL_ERROR_MSG("rsa q error");
}
}
#ifndef RSA_LOW_MEM
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || \
!defined(RSA_LOW_MEM)
if (ret == 1) {
/* Copy d mod p-1. */
ret = wolfssl_bn_set_value(&rsa->dmp1, &key->dP);
@@ -2641,7 +2643,11 @@ int SetRsaExternal(WOLFSSL_RSA* rsa)
WOLFSSL_ERROR_MSG("rsa u error");
}
}
#endif /* !RSA_LOW_MEM */
#endif
#else
WOLFSSL_ERROR_MSG("rsa private key not compiled in ");
ret = 0;
#endif /* !WOLFSSL_RSA_PUBLIC_ONLY */
}
}
if (ret == 1) {
@@ -2696,6 +2702,7 @@ int SetRsaInternal(WOLFSSL_RSA* rsa)
/* Enough numbers for public key */
key->type = RSA_PUBLIC;
#ifndef WOLFSSL_RSA_PUBLIC_ONLY
/* Copy down private exponent if available. */
if ((ret == 1) && (rsa->d != NULL)) {
if (wolfssl_bn_get_value(rsa->d, &key->d) != 1) {
@@ -2722,7 +2729,7 @@ int SetRsaInternal(WOLFSSL_RSA* rsa)
ret = WOLFSSL_FATAL_ERROR;
}
#ifndef RSA_LOW_MEM
#if defined(WOLFSSL_KEY_GEN) || defined(OPENSSL_EXTRA) || !defined(RSA_LOW_MEM)
/* Copy down d mod p-1 if available. */
if ((ret == 1) && (rsa->dmp1 != NULL) &&
(wolfssl_bn_get_value(rsa->dmp1, &key->dP) != 1)) {
@@ -2743,7 +2750,8 @@ int SetRsaInternal(WOLFSSL_RSA* rsa)
WOLFSSL_ERROR_MSG("rsa u key error");
ret = WOLFSSL_FATAL_ERROR;
}
#endif /* !RSA_LOW_MEM */
#endif
#endif
if (ret == 1) {
/* All available numbers have been set down. */
@@ -3523,12 +3531,15 @@ int wolfSSL_RSA_generate_key_ex(WOLFSSL_RSA* rsa, int bits, WOLFSSL_BIGNUM* e,
* @param [out] em Encoded message.
* @param [in[ mHash Message hash.
* @param [in] hashAlg Hash algorithm.
* @param [in] mgf1Hash MGF algorithm.
* @param [in] saltLen Length of salt to generate.
* @return 1 on success.
* @return 0 on failure.
*/
int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg, int saltLen)
int wolfSSL_RSA_padding_add_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa, unsigned char *em,
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg,
const WOLFSSL_EVP_MD *mgf1Hash, int saltLen)
{
int ret = 1;
enum wc_HashType hashType;
@@ -3551,6 +3562,9 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
ret = 0;
}
if (mgf1Hash == NULL)
mgf1Hash = hashAlg;
if (ret == 1) {
/* Get/create an RNG. */
rng = WOLFSSL_RSA_GetRNG(rsa, (WC_RNG**)&tmpRng, &initTmpRng);
@@ -3576,7 +3590,7 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
}
if (ret == 1) {
/* Get the wolfCrypt MGF algorithm from hash algorithm. */
mgf = wc_hash2mgf(hashType);
mgf = wc_hash2mgf(EvpMd2MacType(mgf1Hash));
if (mgf == WC_MGF1NONE) {
WOLFSSL_ERROR_MSG("wc_hash2mgf error");
ret = 0;
@@ -3647,6 +3661,13 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
return ret;
}
int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg, int saltLen)
{
return wolfSSL_RSA_padding_add_PKCS1_PSS_mgf1(rsa, em, mHash, hashAlg, NULL,
saltLen);
}
/* Checks that the hash is valid for the RSA PKCS#1 PSS encoded message.
*
* Refer to wolfSSL_RSA_padding_add_PKCS1_PSS for a diagram.
@@ -3654,14 +3675,15 @@ int wolfSSL_RSA_padding_add_PKCS1_PSS(WOLFSSL_RSA *rsa, unsigned char *em,
* @param [in] rsa RSA key.
* @param [in[ mHash Message hash.
* @param [in] hashAlg Hash algorithm.
* @param [in] mgf1Hash MGF algorithm.
* @param [in] em Encoded message.
* @param [in] saltLen Length of salt to generate.
* @return 1 on success.
* @return 0 on failure.
*/
int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
const WOLFSSL_EVP_MD *hashAlg,
const unsigned char *em, int saltLen)
int wolfSSL_RSA_verify_PKCS1_PSS_mgf1(WOLFSSL_RSA *rsa,
const unsigned char *mHash, const WOLFSSL_EVP_MD *hashAlg,
const WOLFSSL_EVP_MD *mgf1Hash, const unsigned char *em, int saltLen)
{
int ret = 1;
int hashLen = 0;
@@ -3679,6 +3701,9 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
ret = 0;
}
if (mgf1Hash == NULL)
mgf1Hash = hashAlg;
/* TODO: use wolfCrypt RSA key to get emLen and bits? */
/* Set the external data from the wolfCrypt RSA key if not done. */
if ((ret == 1) && (!rsa->exSet)) {
@@ -3741,7 +3766,7 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
if (ret == 1) {
/* Get the wolfCrypt MGF algorithm from hash algorithm. */
if ((mgf = wc_hash2mgf(hashType)) == WC_MGF1NONE) {
if ((mgf = wc_hash2mgf(EvpMd2MacType(mgf1Hash))) == WC_MGF1NONE) {
WOLFSSL_ERROR_MSG("wc_hash2mgf error");
ret = 0;
}
@@ -3784,6 +3809,14 @@ int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return ret;
}
int wolfSSL_RSA_verify_PKCS1_PSS(WOLFSSL_RSA *rsa, const unsigned char *mHash,
const WOLFSSL_EVP_MD *hashAlg,
const unsigned char *em, int saltLen)
{
return wolfSSL_RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, hashAlg, NULL, em,
saltLen);
}
#endif /* !HAVE_FIPS || FIPS_VERSION_GT(2,0) */
#endif /* WC_RSA_PSS && (OPENSSL_ALL || WOLFSSL_ASIO || WOLFSSL_HAPROXY ||
* WOLFSSL_NGINX) */
@@ -5434,11 +5467,11 @@ WOLFSSL_DSA_SIG* wolfSSL_d2i_DSA_SIG(WOLFSSL_DSA_SIG **sig,
return ret;
}
#endif /* HAVE_SELFTEST */
/* return 1 on success, < 0 otherwise */
int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
WOLFSSL_DSA* dsa)
#endif /* !HAVE_SELFTEST */
static int dsa_do_sign(const unsigned char* d, int dLen, unsigned char* sigRet,
WOLFSSL_DSA* dsa)
{
int ret = WC_NO_ERR_TRACE(WOLFSSL_FATAL_ERROR);
int initTmpRng = 0;
@@ -5449,8 +5482,6 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
WC_RNG tmpRng[1];
#endif
WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
if (d == NULL || sigRet == NULL || dsa == NULL) {
WOLFSSL_MSG("Bad function arguments");
return WOLFSSL_FATAL_ERROR;
@@ -5486,10 +5517,18 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
}
if (rng) {
if (wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
WOLFSSL_MSG("DsaSign failed");
#ifdef HAVE_SELFTEST
if (dLen != WC_SHA_DIGEST_SIZE ||
wc_DsaSign(d, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
WOLFSSL_MSG("wc_DsaSign failed or dLen wrong length");
ret = WOLFSSL_FATAL_ERROR;
}
#else
if (wc_DsaSign_ex(d, dLen, sigRet, (DsaKey*)dsa->internal, rng) < 0) {
WOLFSSL_MSG("wc_DsaSign_ex failed");
ret = WOLFSSL_FATAL_ERROR;
}
#endif
else
ret = WOLFSSL_SUCCESS;
}
@@ -5503,6 +5542,15 @@ int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
return ret;
}
/* return 1 on success, < 0 otherwise */
int wolfSSL_DSA_do_sign(const unsigned char* d, unsigned char* sigRet,
WOLFSSL_DSA* dsa)
{
WOLFSSL_ENTER("wolfSSL_DSA_do_sign");
return dsa_do_sign(d, WC_SHA_DIGEST_SIZE, sigRet, dsa);
}
#ifndef HAVE_SELFTEST
WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
int inLen, WOLFSSL_DSA* dsa)
@@ -5513,12 +5561,12 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
WOLFSSL_ENTER("wolfSSL_DSA_do_sign_ex");
if (!digest || !dsa || inLen != WC_SHA_DIGEST_SIZE) {
if (!digest || !dsa) {
WOLFSSL_MSG("Bad function arguments");
return NULL;
}
if (wolfSSL_DSA_do_sign(digest, sigBin, dsa) != 1) {
if (dsa_do_sign(digest, inLen, sigBin, dsa) != 1) {
WOLFSSL_MSG("wolfSSL_DSA_do_sign error");
return NULL;
}
@@ -5537,15 +5585,13 @@ WOLFSSL_DSA_SIG* wolfSSL_DSA_do_sign_ex(const unsigned char* digest,
/* 2 * sigLen for the two points r and s */
return wolfSSL_d2i_DSA_SIG(NULL, &tmp, 2 * sigLen);
}
#endif /* !HAVE_SELFTEST */
#endif
int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
static int dsa_do_verify(const unsigned char* d, int dLen, unsigned char* sig,
WOLFSSL_DSA* dsa, int *dsacheck)
{
int ret;
WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
if (d == NULL || sig == NULL || dsa == NULL) {
WOLFSSL_MSG("Bad function arguments");
return WOLFSSL_FATAL_ERROR;
@@ -5560,13 +5606,30 @@ int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
}
}
ret = DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck);
if (ret != 0 || *dsacheck != 1) {
#ifdef HAVE_SELFTEST
ret = dLen == WC_SHA_DIGEST_SIZE ?
wc_DsaVerify(d, sig, (DsaKey*)dsa->internal, dsacheck) : BAD_FUNC_ARG;
#else
ret = wc_DsaVerify_ex(d, dLen, sig, (DsaKey*)dsa->internal, dsacheck);
#endif
if (ret != 0) {
WOLFSSL_MSG("DsaVerify failed");
return ret;
return WOLFSSL_FATAL_ERROR;
}
if (*dsacheck != 1) {
WOLFSSL_MSG("DsaVerify sig failed");
return WOLFSSL_FAILURE;
}
return 1;
return WOLFSSL_SUCCESS;
}
int wolfSSL_DSA_do_verify(const unsigned char* d, unsigned char* sig,
WOLFSSL_DSA* dsa, int *dsacheck)
{
WOLFSSL_ENTER("wolfSSL_DSA_do_verify");
return dsa_do_verify(d, WC_SHA_DIGEST_SIZE, sig, dsa, dsacheck);
}
@@ -5591,7 +5654,7 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
WOLFSSL_ENTER("wolfSSL_DSA_do_verify_ex");
if (!digest || !sig || !dsa || digest_len != WC_SHA_DIGEST_SIZE) {
if (!digest || !sig || !dsa) {
WOLFSSL_MSG("Bad function arguments");
return 0;
}
@@ -5643,14 +5706,14 @@ int wolfSSL_DSA_do_verify_ex(const unsigned char* digest, int digest_len,
if (wolfSSL_BN_bn2bin(sig->s, sigBinPtr) == -1)
return 0;
if ((wolfSSL_DSA_do_verify(digest, sigBin, dsa, &dsacheck)
if ((dsa_do_verify(digest, digest_len, sigBin, dsa, &dsacheck)
!= 1) || dsacheck != 1) {
return 0;
}
return 1;
}
#endif /* !HAVE_SELFTEST */
#endif
int wolfSSL_i2d_DSAparams(const WOLFSSL_DSA* dsa,
unsigned char** out)
@@ -8606,6 +8669,10 @@ int wolfSSL_DH_generate_key(WOLFSSL_DH* dh)
/* Private key size can be as much as the size of the prime. */
if (dh->length) {
privSz = (word32)(dh->length / 8); /* to bytes */
/* Special case where priv key is larger than dh->length / 8
* See GeneratePrivateDh */
if (dh->length == 128)
privSz = 21;
}
else {
privSz = pubSz;
@@ -9373,6 +9440,47 @@ WOLFSSL_EC_GROUP *wolfSSL_d2i_ECPKParameters(WOLFSSL_EC_GROUP **out,
{
return wolfssl_ec_group_d2i(out, in, len);
}
int wolfSSL_i2d_ECPKParameters(const WOLFSSL_EC_GROUP* grp, unsigned char** pp)
{
unsigned char* out = NULL;
int len = 0;
int idx;
const byte* oid = NULL;
word32 oidSz = 0;
if (grp == NULL || !wc_ecc_is_valid_idx(grp->curve_idx) ||
grp->curve_idx < 0)
return WOLFSSL_FATAL_ERROR;
/* Get the actual DER encoding of the OID. ecc_sets[grp->curve_idx].oid
* is just the numerical representation. */
if (wc_ecc_get_oid(grp->curve_oid, &oid, &oidSz) < 0)
return WOLFSSL_FATAL_ERROR;
len = SetObjectId(oidSz, NULL) + oidSz;
if (pp == NULL)
return len;
if (*pp == NULL) {
out = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
if (out == NULL)
return WOLFSSL_FATAL_ERROR;
}
else {
out = *pp;
}
idx = SetObjectId(oidSz, out);
XMEMCPY(out + idx, oid, oidSz);
if (*pp == NULL)
*pp = out;
else
*pp += len;
return len;
}
#endif /* !NO_BIO */
#if defined(OPENSSL_ALL) && !defined(NO_CERTS)
@@ -9663,6 +9771,12 @@ int wolfSSL_EC_GROUP_get_order(const WOLFSSL_EC_GROUP *group,
ret = 0;
}
if (ret == 1 &&
(group->curve_idx < 0 || !wc_ecc_is_valid_idx(group->curve_idx))) {
WOLFSSL_MSG("wolfSSL_EC_GROUP_get_order Bad group idx");
ret = 0;
}
if (ret == 1) {
mp = (mp_int*)order->internal;
}
@@ -15645,6 +15759,13 @@ WOLFSSL_EVP_PKEY* wolfSSL_PEM_read_bio_PrivateKey(WOLFSSL_BIO* bio,
return pkey;
}
PKCS8_PRIV_KEY_INFO* wolfSSL_PEM_read_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
PKCS8_PRIV_KEY_INFO** key, wc_pem_password_cb* cb, void* arg)
{
return wolfSSL_PEM_read_bio_PrivateKey(bio, key, cb, arg);
}
#endif /* !NO_BIO */
#if !defined(NO_FILESYSTEM)
@@ -16278,8 +16399,6 @@ int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
#ifdef OPENSSL_ALL
#if !defined(NO_PWDBASED) && defined(HAVE_PKCS8)
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
!defined(NO_STDIO_FILESYSTEM))
/* Encrypt the key into a buffer using PKCS$8 and a password.
*
* @param [in] pkey Private key to encrypt.
@@ -16292,7 +16411,7 @@ int wolfSSL_PEM_do_header(EncryptedInfo* cipher, unsigned char* data, long* len,
* @return 0 on success.
* @return BAD_FUNC_ARG when EVP cipher not supported.
*/
static int pem_pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
word32* keySz)
{
@@ -16356,7 +16475,7 @@ static int pem_pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
* @param On out, size of encoded key in bytes.
* @return 0 on success.
*/
static int pem_pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
{
int ret = 0;
int algId;
@@ -16379,6 +16498,34 @@ static int pem_pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
curveOid = NULL;
oidSz = 0;
}
else if (pkey->type == EVP_PKEY_DSA) {
/* DSA has no curve information. */
algId = DSAk;
curveOid = NULL;
oidSz = 0;
}
else if (pkey->type == EVP_PKEY_DH) {
if (pkey->dh == NULL)
return BAD_FUNC_ARG;
if (pkey->dh->priv_key != NULL || pkey->dh->pub_key != NULL) {
/* Special case. DH buffer is always in PKCS8 format */
if (keySz == NULL)
return BAD_FUNC_ARG;
*keySz = pkey->pkey_sz;
if (key == NULL)
return LENGTH_ONLY_E;
XMEMCPY(key, pkey->pkey.ptr, pkey->pkey_sz);
return pkey->pkey_sz;
}
/* DH has no curve information. */
algId = DHk;
curveOid = NULL;
oidSz = 0;
}
else {
ret = NOT_COMPILED_IN;
}
@@ -16392,6 +16539,8 @@ static int pem_pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key, word32* keySz)
return ret;
}
#if !defined(NO_BIO) || (!defined(NO_FILESYSTEM) && \
!defined(NO_STDIO_FILESYSTEM))
/* Write PEM encoded, PKCS#8 formatted private key to BIO.
*
* @param [out] pem Buffer holding PEM encoding.
@@ -16424,7 +16573,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
if (res == 1) {
/* Guestimate key size and PEM size. */
if (pem_pkcs8_encode(pkey, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
if (pkcs8_encode(pkey, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E)) {
res = 0;
}
}
@@ -16472,7 +16621,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
if (res == 1) {
/* Encrypt the private key. */
ret = pem_pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
ret = pkcs8_encrypt(pkey, enc, passwd, passwdSz, key, &keySz);
if (ret <= 0) {
res = 0;
}
@@ -16488,7 +16637,7 @@ static int pem_write_mem_pkcs8privatekey(byte** pem, int* pemSz,
type = PKCS8_PRIVATEKEY_TYPE;
/* Encode private key in PKCS#8 format. */
ret = pem_pkcs8_encode(pkey, key, &keySz);
ret = pkcs8_encode(pkey, key, &keySz);
if (ret < 0) {
res = 0;
}
@@ -16554,6 +16703,13 @@ int wolfSSL_PEM_write_bio_PKCS8PrivateKey(WOLFSSL_BIO* bio,
XFREE(pem, NULL, DYNAMIC_TYPE_TMP_BUFFER);
return res;
}
int wolfSSL_PEM_write_bio_PKCS8_PRIV_KEY_INFO(WOLFSSL_BIO* bio,
PKCS8_PRIV_KEY_INFO* keyInfo)
{
return wolfSSL_PEM_write_bio_PKCS8PrivateKey(bio, keyInfo, NULL, NULL, 0,
NULL, NULL);
}
#endif /* !NO_BIO */
#if !defined(NO_FILESYSTEM) && !defined(NO_STDIO_FILESYSTEM)

View File

@@ -7241,29 +7241,51 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
WOLFSSL_PKCS8_PRIV_KEY_INFO* pkcs8 = NULL;
#ifdef WOLFSSL_PEM_TO_DER
int ret;
DerBuffer* der = NULL;
DerBuffer* pkcs8Der = NULL;
DerBuffer rawDer;
EncryptedInfo info;
int advanceLen = 0;
XMEMSET(&info, 0, sizeof(info));
XMEMSET(&rawDer, 0, sizeof(rawDer));
if (keyBuf == NULL || *keyBuf == NULL || keyLen <= 0) {
WOLFSSL_MSG("Bad key PEM/DER args");
return NULL;
}
ret = PemToDer(*keyBuf, keyLen, PRIVATEKEY_TYPE, &der, NULL, NULL, NULL);
ret = PemToDer(*keyBuf, keyLen, PRIVATEKEY_TYPE, &pkcs8Der, NULL, &info,
NULL);
if (ret < 0) {
WOLFSSL_MSG("Not PEM format");
ret = AllocDer(&der, (word32)keyLen, PRIVATEKEY_TYPE, NULL);
ret = AllocDer(&pkcs8Der, (word32)keyLen, PRIVATEKEY_TYPE, NULL);
if (ret == 0) {
XMEMCPY(der->buffer, *keyBuf, keyLen);
XMEMCPY(pkcs8Der->buffer, *keyBuf, keyLen);
}
}
else {
advanceLen = (int)info.consumed;
}
if (ret == 0) {
/* Verify this is PKCS8 Key */
word32 inOutIdx = 0;
word32 algId;
ret = ToTraditionalInline_ex(der->buffer, &inOutIdx, der->length,
&algId);
ret = ToTraditionalInline_ex(pkcs8Der->buffer, &inOutIdx,
pkcs8Der->length, &algId);
if (ret >= 0) {
if (advanceLen == 0) /* Set only if not PEM */
advanceLen = inOutIdx + ret;
if (algId == DHk) {
/* Special case for DH as we expect the DER buffer to be always
* be in PKCS8 format */
rawDer.buffer = pkcs8Der->buffer;
rawDer.length = inOutIdx + ret;
}
else {
rawDer.buffer = pkcs8Der->buffer + inOutIdx;
rawDer.length = ret;
}
ret = 0; /* good DER */
}
}
@@ -7274,21 +7296,24 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
ret = MEMORY_E;
}
if (ret == 0) {
pkcs8->pkey.ptr = (char*)XMALLOC(der->length, NULL,
pkcs8->pkey.ptr = (char*)XMALLOC(rawDer.length, NULL,
DYNAMIC_TYPE_PUBLIC_KEY);
if (pkcs8->pkey.ptr == NULL)
ret = MEMORY_E;
}
if (ret == 0) {
XMEMCPY(pkcs8->pkey.ptr, der->buffer, der->length);
pkcs8->pkey_sz = (int)der->length;
XMEMCPY(pkcs8->pkey.ptr, rawDer.buffer, rawDer.length);
pkcs8->pkey_sz = (int)rawDer.length;
}
FreeDer(&der);
FreeDer(&pkcs8Der);
if (ret != 0) {
wolfSSL_EVP_PKEY_free(pkcs8);
pkcs8 = NULL;
}
else {
*keyBuf += advanceLen;
}
if (pkey != NULL) {
*pkey = pkcs8;
}
@@ -7301,6 +7326,48 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
return pkcs8;
}
#ifdef OPENSSL_ALL
int wolfSSL_i2d_PKCS8_PKEY(WOLFSSL_PKCS8_PRIV_KEY_INFO* key, unsigned char** pp)
{
word32 keySz = 0;
unsigned char* out;
int len;
WOLFSSL_ENTER("wolfSSL_i2d_PKCS8_PKEY");
if (key == NULL)
return WOLFSSL_FATAL_ERROR;
if (pkcs8_encode(key, NULL, &keySz) != WC_NO_ERR_TRACE(LENGTH_ONLY_E))
return WOLFSSL_FATAL_ERROR;
len = (int)keySz;
if (pp == NULL)
return len;
if (*pp == NULL) {
out = (unsigned char*)XMALLOC(len, NULL, DYNAMIC_TYPE_ASN1);
if (out == NULL)
return WOLFSSL_FATAL_ERROR;
}
else {
out = *pp;
}
if (pkcs8_encode(key, out, &keySz) != len) {
if (*pp == NULL)
XFREE(out, NULL, DYNAMIC_TYPE_ASN1);
return WOLFSSL_FATAL_ERROR;
}
if (*pp == NULL)
*pp = out;
else
*pp += len;
return len;
}
#endif
#ifndef NO_BIO
/* put SSL type in extra for now, not very common */

View File

@@ -1312,7 +1312,7 @@ static int wolfssl_bn_add_word_int(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w,
#endif
/* Validate parameters. */
if (BN_IS_NULL(bn)) {
if (ret == 1 && BN_IS_NULL(bn)) {
WOLFSSL_MSG("bn NULL error");
ret = 0;
}
@@ -1419,6 +1419,85 @@ int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w)
return ret;
}
int wolfSSL_BN_mul_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w)
{
int ret = 1;
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
#ifdef WOLFSSL_SMALL_STACK
mp_int* w_mp = NULL;
#else
mp_int w_mp[1];
#endif /* WOLFSSL_SMALL_STACK */
#endif
WOLFSSL_ENTER("wolfSSL_BN_mul_word");
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
#ifdef WOLFSSL_SMALL_STACK
/* Allocate temporary MP integer. */
w_mp = (mp_int*)XMALLOC(sizeof(*w_mp), NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (w_mp == NULL) {
ret = 0;
}
else
#endif /* WOLFSSL_SMALL_STACK */
{
/* Clear out MP integer so it can be freed. */
XMEMSET(w_mp, 0, sizeof(*w_mp));
}
#endif
/* Validate parameters. */
if (ret == 1 && BN_IS_NULL(bn)) {
WOLFSSL_MSG("bn NULL error");
ret = 0;
}
if (ret == 1) {
int rc = 0;
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
if (w > (WOLFSSL_BN_ULONG)MP_MASK) {
/* Initialize temporary MP integer. */
if (mp_init(w_mp) != MP_OKAY) {
ret = 0;
}
/* Set value into temporary MP integer. */
if ((ret == 1) && (mp_set_int(w_mp, w) != MP_OKAY)) {
ret = 0;
}
if (ret == 1) {
rc = mp_mul((mp_int*)bn->internal, w_mp,
(mp_int*)bn->internal);
if (rc != MP_OKAY) {
WOLFSSL_MSG("mp_mul error");
ret = 0;
}
}
}
else
#endif
{
rc = mp_mul_d((mp_int*)bn->internal, (mp_digit)w,
(mp_int*)bn->internal);
if (rc != MP_OKAY) {
WOLFSSL_MSG("mp_mul_d error");
ret = 0;
}
}
}
#if DIGIT_BIT < (SIZEOF_LONG * CHAR_BIT)
mp_free(w_mp);
#ifdef WOLFSSL_SMALL_STACK
XFREE(w_mp, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif /* WOLFSSL_SMALL_STACK */
#endif
WOLFSSL_LEAVE("wolfSSL_BN_mul_word", ret);
return ret;
}
#if defined(WOLFSSL_KEY_GEN) && (!defined(NO_RSA) || !defined(NO_DH) || \
!defined(NO_DSA))
/* Calculate bn modulo word w. bn % w