Skip to content

Commit

Permalink
Init SoftHSMv2 support
Browse files Browse the repository at this point in the history
- 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
- 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
  • Loading branch information
julek-wolfssl committed Aug 19, 2024
1 parent b693127 commit 0327b50
Show file tree
Hide file tree
Showing 16 changed files with 366 additions and 46 deletions.
176 changes: 147 additions & 29 deletions src/pk.c

Large diffs are not rendered by default.

87 changes: 77 additions & 10 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -7144,29 +7144,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 = 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 */
}
}
Expand All @@ -7177,21 +7199,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;
}
Expand All @@ -7204,6 +7229,48 @@ WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_d2i_PKCS8_PKEY(
return pkcs8;
}

int wolfSSL_i2d_PKCS8_PKEY(WOLFSSL_PKCS8_PRIV_KEY_INFO* key, unsigned char** pp)
{
word32 keySz = 0;
unsigned char* out;
int len;
int err;

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 ((err = 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;
}


#ifndef NO_BIO
/* put SSL type in extra for now, not very common */
Expand Down
81 changes: 80 additions & 1 deletion src/ssl_bn.c
Original file line number Diff line number Diff line change
Expand Up @@ -1305,7 +1305,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;
}
Expand Down Expand Up @@ -1412,6 +1412,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
Expand Down
4 changes: 3 additions & 1 deletion tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -54555,6 +54555,7 @@ static int test_wolfSSL_PKCS8_Compat(void)
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM) && defined(HAVE_ECC) && \
!defined(NO_BIO)
PKCS8_PRIV_KEY_INFO* pt = NULL;
PKCS8_PRIV_KEY_INFO* pt2 = NULL;
BIO* bio = NULL;
XFILE f = XBADFILE;
int bytes;
Expand All @@ -54577,13 +54578,14 @@ static int test_wolfSSL_PKCS8_Compat(void)
ExpectIntEQ(EVP_PKEY_type(pkey->type), EVP_PKEY_EC);

/* gets PKCS8 pointer to pkey */
ExpectNotNull(EVP_PKEY2PKCS8(pkey));
ExpectNotNull(pt2 = EVP_PKEY2PKCS8(pkey));

EVP_PKEY_free(pkey);
#endif

BIO_free(bio);
PKCS8_PRIV_KEY_INFO_free(pt);
PKCS8_PRIV_KEY_INFO_free(pt2);
#endif
return EXPECT_RESULT();
}
Expand Down
9 changes: 9 additions & 0 deletions wolfcrypt/src/asn.c
Original file line number Diff line number Diff line change
Expand Up @@ -7104,6 +7104,15 @@ int ToTraditionalInline_ex2(const byte* input, word32* inOutIdx, word32 sz,
ret = ASN_PARSE_E;
}
break;
#endif
#ifndef NO_DH
case DHk:
/* Neither NULL item nor OBJECT_ID item allowed. */
if ((dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_NULL].tag != 0) ||
(dataASN[PKCS8KEYASN_IDX_PKEY_ALGO_OID_CURVE].tag != 0)) {
ret = ASN_PARSE_E;
}
break;
#endif
/* DSAk not supported. */
/* Falcon, Dilithium and Sphincs not supported. */
Expand Down
2 changes: 1 addition & 1 deletion wolfcrypt/src/ecc.c
Original file line number Diff line number Diff line change
Expand Up @@ -4250,7 +4250,7 @@ int wc_ecc_get_curve_idx(int curve_id)

int wc_ecc_get_curve_id(int curve_idx)
{
if (wc_ecc_is_valid_idx(curve_idx)) {
if (wc_ecc_is_valid_idx(curve_idx) && curve_idx >= 0) {
return ecc_sets[curve_idx].id;
}
return ECC_CURVE_INVALID;
Expand Down
11 changes: 8 additions & 3 deletions wolfcrypt/src/evp.c
Original file line number Diff line number Diff line change
Expand Up @@ -9045,7 +9045,7 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key)
/* Get size of DER buffer only */
if (havePublic && !havePrivate) {
ret = wc_DhPubKeyToDer(dhkey, NULL, &derSz);
} else if (havePrivate && !havePublic) {
} else if (havePrivate) {
ret = wc_DhPrivKeyToDer(dhkey, NULL, &derSz);
} else {
ret = wc_DhParamsToDer(dhkey,NULL,&derSz);
Expand All @@ -9065,7 +9065,7 @@ int wolfSSL_EVP_PKEY_set1_DH(WOLFSSL_EVP_PKEY *pkey, WOLFSSL_DH *key)
/* Fill DER buffer */
if (havePublic && !havePrivate) {
ret = wc_DhPubKeyToDer(dhkey, derBuf, &derSz);
} else if (havePrivate && !havePublic) {
} else if (havePrivate) {
ret = wc_DhPrivKeyToDer(dhkey, derBuf, &derSz);
} else {
ret = wc_DhParamsToDer(dhkey,derBuf,&derSz);
Expand Down Expand Up @@ -9764,7 +9764,12 @@ WOLFSSL_EVP_PKEY* wolfSSL_EVP_PKCS82PKEY(const WOLFSSL_PKCS8_PRIV_KEY_INFO* p8)
/* this function just casts and returns pointer */
WOLFSSL_PKCS8_PRIV_KEY_INFO* wolfSSL_EVP_PKEY2PKCS8(const WOLFSSL_EVP_PKEY* pkey)
{
return (WOLFSSL_PKCS8_PRIV_KEY_INFO*)pkey;
if (pkey == NULL || pkey->pkey.ptr == NULL) {
return NULL;
}

return wolfSSL_d2i_PrivateKey_EVP(NULL, (unsigned char**)&pkey->pkey.ptr,
pkey->pkey_sz);
}
#endif

Expand Down
6 changes: 6 additions & 0 deletions wolfssl/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6941,6 +6941,12 @@ WOLFSSL_LOCAL int wolfssl_asn1_obj_set(WOLFSSL_ASN1_OBJECT* obj,
const byte* der, word32 len, int addHdr);
#endif

WOLFSSL_LOCAL int pkcs8_encode(WOLFSSL_EVP_PKEY* pkey, byte* key,
word32* keySz);
WOLFSSL_LOCAL int pkcs8_encrypt(WOLFSSL_EVP_PKEY* pkey,
const WOLFSSL_EVP_CIPHER* enc, char* passwd, int passwdSz, byte* key,
word32* keySz);

#ifdef __cplusplus
} /* extern "C" */
#endif
Expand Down
2 changes: 2 additions & 0 deletions wolfssl/openssl/bn.h
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ WOLFSSL_API int wolfSSL_BN_lshift(WOLFSSL_BIGNUM* r, const WOLFSSL_BIGNUM* bn,
int n);
WOLFSSL_API int wolfSSL_BN_add_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w);
WOLFSSL_API int wolfSSL_BN_sub_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w);
WOLFSSL_API int wolfSSL_BN_mul_word(WOLFSSL_BIGNUM *bn, WOLFSSL_BN_ULONG w);
WOLFSSL_API int wolfSSL_BN_set_bit(WOLFSSL_BIGNUM* bn, int n);
WOLFSSL_API int wolfSSL_BN_clear_bit(WOLFSSL_BIGNUM* bn, int n);
WOLFSSL_API int wolfSSL_BN_set_word(WOLFSSL_BIGNUM* bn, WOLFSSL_BN_ULONG w);
Expand Down Expand Up @@ -254,6 +255,7 @@ typedef WOLFSSL_BN_GENCB BN_GENCB;

#define BN_lshift wolfSSL_BN_lshift
#define BN_add_word wolfSSL_BN_add_word
#define BN_mul_word wolfSSL_BN_mul_word
#define BN_sub_word wolfSSL_BN_sub_word
#define BN_add wolfSSL_BN_add
#define BN_mod_add wolfSSL_BN_mod_add
Expand Down
3 changes: 3 additions & 0 deletions wolfssl/openssl/dh.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define WOLFSSL_DH_H_

#include <wolfssl/openssl/bn.h>
#include <wolfssl/openssl/ssl.h>
#include <wolfssl/openssl/opensslv.h>

#ifdef __cplusplus
Expand Down Expand Up @@ -98,6 +99,8 @@ typedef WOLFSSL_DH DH;
#define DH_set0_key wolfSSL_DH_set0_key
#define DH_bits(x) (BN_num_bits((x)->p))

#define OPENSSL_DH_MAX_MODULUS_BITS DH_MAX_SIZE

#define DH_GENERATOR_2 2
#define DH_CHECK_P_NOT_PRIME 0x01
#define DH_CHECK_P_NOT_SAFE_PRIME 0x02
Expand Down
3 changes: 3 additions & 0 deletions wolfssl/openssl/dsa.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define WOLFSSL_DSA_H_

#include <wolfssl/openssl/bn.h>
#include <wolfssl/openssl/compat_types.h>

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -119,6 +120,8 @@ WOLFSSL_API WOLFSSL_DSA* wolfSSL_d2i_DSAparams(

typedef WOLFSSL_DSA DSA;

#define OPENSSL_DSA_MAX_MODULUS_BITS 3072

#define WOLFSSL_DSA_LOAD_PRIVATE 1
#define WOLFSSL_DSA_LOAD_PUBLIC 2

Expand Down
2 changes: 2 additions & 0 deletions wolfssl/openssl/ec.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define WOLFSSL_EC_H_

#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/openssl/compat_types.h>
#include <wolfssl/openssl/bn.h>
#include <wolfssl/wolfcrypt/asn.h>
#include <wolfssl/wolfcrypt/ecc.h>
Expand Down Expand Up @@ -425,6 +426,7 @@ typedef WOLFSSL_EC_KEY_METHOD EC_KEY_METHOD;
#define EC_KEY_set_conv_form wolfSSL_EC_KEY_set_conv_form
#define EC_KEY_get_conv_form wolfSSL_EC_KEY_get_conv_form
#define d2i_ECPKParameters wolfSSL_d2i_ECPKParameters
#define i2d_ECPKParameters wolfSSL_i2d_ECPKParameters

#define EC_POINT_point2hex wolfSSL_EC_POINT_point2hex
#define EC_POINT_hex2point wolfSSL_EC_POINT_hex2point
Expand Down
Loading

0 comments on commit 0327b50

Please sign in to comment.