Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions include/wolfprovider/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,9 +233,14 @@ int wp_hash_copy(wc_HashAlg* src, wc_HashAlg* dst, enum wc_HashType hashType);
int wp_cipher_from_params(const OSSL_PARAM params[], int* cipher,
const char** cipherName);

int wp_encrypt_key(WOLFPROV_CTX* provCtx, const char* cipherName,
unsigned char* keyData, size_t* keyLen, word32 pkcs8Len,
OSSL_PASSPHRASE_CALLBACK *pwCb, void *pwCbArg, byte** cipherInfo);
int wp_encrypt_key_pkcs8_size(WOLFPROV_CTX* provCtx, int cipher,
word32 plainLen, size_t* outLen);
int wp_encrypt_key_pkcs8(WOLFPROV_CTX* provCtx, int cipher,
const unsigned char* plain, word32 plainLen,
unsigned char* out, size_t* outLen,
OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg);
int wp_decrypt_key_pkcs8(unsigned char* data, word32* len,
OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg);

int wp_read_der_bio(WOLFPROV_CTX* provCtx, OSSL_CORE_BIO *coreBio, unsigned char** data, word32* len);
int wp_read_pem_bio(WOLFPROV_CTX *provctx, OSSL_CORE_BIO *coreBio,
Expand Down
105 changes: 84 additions & 21 deletions src/wp_dh_kmgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -2284,6 +2284,43 @@ static int wp_dh_dec_send_params(wp_Dh* dh, OSSL_CALLBACK *dataCb,
return ok;
}

#ifdef WOLFSSL_ENCRYPTED_KEYS
/**
* Decode an encrypted PKCS#8 DER DH private key into the DH key object.
*
* @param [in, out] dh DH key object.
* @param [in] data DER encoding (decrypted in place).
* @param [in] len Length, in bytes, of DER encoding.
* @param [in] pwCb Password callback.
* @param [in] pwCbArg Argument to pass to password callback.
* @return 1 on success.
* @return 0 on failure.
*/
static int wp_dh_decode_enc_pki(wp_Dh* dh, unsigned char* data, word32 len,
OSSL_PASSPHRASE_CALLBACK* pwCb, void* pwCbArg)
{
int ok = 1;

WOLFPROV_ENTER_SILENT(WP_LOG_COMP_DH, WOLFPROV_FUNC_NAME);

if (!wolfssl_prov_is_running()) {
ok = 0;
}
/* Decrypt the PBES2 EncryptedPrivateKeyInfo in place. */
if (ok && (!wp_decrypt_key_pkcs8(data, &len, pwCb, pwCbArg))) {
ok = 0;
}
if (ok) {
/* Decode the recovered plaintext private key. */
ok = wp_dh_decode_pki(dh, data, len);
}

WOLFPROV_LEAVE_SILENT(WP_LOG_COMP_DH, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__),
ok);
return ok;
}
#endif

/**
* Decode the data in the core BIO.
*
Expand Down Expand Up @@ -2364,8 +2401,13 @@ static int wp_dh_decode(wp_DhEncDecCtx* ctx, OSSL_CORE_BIO *cBio,
}
else if (ok && (ctx->format == WP_ENC_FORMAT_PKI)) {
if (!wp_dh_decode_pki(dh, data, len)) {
ok = 0;
decoded = 0;
#ifdef WOLFSSL_ENCRYPTED_KEYS
if (!wp_dh_decode_enc_pki(dh, data, len, pwCb, pwCbArg))
#endif
{
ok = 0;
decoded = 0;
}
}
}

Expand Down Expand Up @@ -2602,28 +2644,31 @@ static int wp_dh_encode_pki(const wp_Dh *dh, unsigned char* keyData,
* @return 1 on success.
* @return 0 on failure.
*/
static int wp_dh_encode_epki_size(const wp_Dh *dh, size_t* keyLen)
static int wp_dh_encode_epki_size(const wp_DhEncDecCtx* ctx, const wp_Dh *dh,
size_t* keyLen)
{
int ok = 1;
int ret;
word32 len;

WOLFPROV_ENTER(WP_LOG_COMP_DH, "wp_dh_encode_epki_size");

/* Get the plaintext PKCS #8 length. */
ret = wc_DhPrivKeyToDer((DhKey*)&dh->key, NULL, &len);
if (ret != LENGTH_ONLY_E) {
ok = 0;
}
if (ok) {
*keyLen = ((len + 15) / 16) * 16;
/* Get the size of the PBES2 EncryptedPrivateKeyInfo encoding. */
ok = wp_encrypt_key_pkcs8_size(ctx->provCtx, ctx->cipher, len, keyLen);
}

WOLFPROV_LEAVE(WP_LOG_COMP_DH, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
return ok;
}

/**
* Encode the DH key in an Encrypted PKCS#8 format.
* Encode the DH key in a PBES2 EncryptedPrivateKeyInfo format.
*
* @param [in] ctx DH encoder/decoder context object.
* @param [in] dh DH key object.
Expand All @@ -2632,28 +2677,48 @@ static int wp_dh_encode_epki_size(const wp_Dh *dh, size_t* keyLen)
* On out, length of encoding in bytes.
* @param [in] pwCb Password callback.
* @param [in] pwCbArg Argument to pass to password callback.
* @param [out] cipherInfo Information about encryption.
* @return 1 on success.
* @return 0 on failure.
*/
static int wp_dh_encode_epki(const wp_DhEncDecCtx* ctx, const wp_Dh *dh,
unsigned char* keyData, size_t* keyLen, OSSL_PASSPHRASE_CALLBACK *pwCb,
void *pwCbArg, byte** cipherInfo)
void *pwCbArg)
{
int ok = 1;
int rc;
word32 pkcs8Len = (word32)*keyLen;
word32 pkcs8Len = 0;
byte* encodedKey = NULL;

WOLFPROV_ENTER(WP_LOG_COMP_DH, "wp_dh_encode_epki");

/* Encode key. */
rc = wc_DhPrivKeyToDer((DhKey*)&dh->key, keyData, &pkcs8Len);
if (rc <= 0) {
/* Determine the plaintext PKCS #8 length. */
rc = wc_DhPrivKeyToDer((DhKey*)&dh->key, NULL, &pkcs8Len);
if (rc != LENGTH_ONLY_E) {
ok = 0;
}
if (ok && (!wp_encrypt_key(ctx->provCtx, ctx->cipherName, keyData, keyLen,
pkcs8Len, pwCb, pwCbArg, cipherInfo))) {
ok = 0;
if (ok) {
/* Allocate the plaintext buffer - must differ from the output. */
encodedKey = OPENSSL_malloc(pkcs8Len);
if (encodedKey == NULL) {
ok = 0;
}
}
if (ok) {
/* Encode the plaintext PKCS #8 key. */
rc = wc_DhPrivKeyToDer((DhKey*)&dh->key, encodedKey, &pkcs8Len);
if (rc <= 0) {
ok = 0;
}
}
if (ok) {
/* Encrypt as a PBES2 EncryptedPrivateKeyInfo. */
ok = wp_encrypt_key_pkcs8(ctx->provCtx, ctx->cipher, encodedKey,
pkcs8Len, keyData, keyLen, pwCb, pwCbArg);
}

/* encodedKey holds the plaintext PKCS#8 private key before encryption. */
if (encodedKey != NULL) {
OPENSSL_clear_free(encodedKey, pkcs8Len);
}

WOLFPROV_LEAVE(WP_LOG_COMP_DH, __FILE__ ":" WOLFPROV_STRINGIZE(__LINE__), ok);
Expand Down Expand Up @@ -2698,7 +2763,6 @@ static int wp_dh_encode(wp_DhEncDecCtx* ctx, OSSL_CORE_BIO *cBio,
size_t pemLen = 0;
int pemType = DH_PRIVATEKEY_TYPE;
int private = 0;
byte* cipherInfo = NULL;

if (out == NULL) {
ok = 0;
Expand Down Expand Up @@ -2729,7 +2793,7 @@ static int wp_dh_encode(wp_DhEncDecCtx* ctx, OSSL_CORE_BIO *cBio,
#ifdef WOLFSSL_ENCRYPTED_KEYS
else if (ok && (ctx->format == WP_ENC_FORMAT_EPKI)) {
private = 1;
if (!wp_dh_encode_epki_size(key, &derLen)) {
if (!wp_dh_encode_epki_size(ctx, key, &derLen)) {
ok = 0;
}
}
Expand Down Expand Up @@ -2764,8 +2828,8 @@ static int wp_dh_encode(wp_DhEncDecCtx* ctx, OSSL_CORE_BIO *cBio,
#ifdef WOLFSSL_ENCRYPTED_KEYS
else if (ok && (ctx->format == WP_ENC_FORMAT_EPKI)) {
private = 1;
if (!wp_dh_encode_epki(ctx, key, derData, &derLen, pwCb, pwCbArg,
(ctx->encoding == WP_FORMAT_PEM) ? &cipherInfo : NULL)) {
pemType = PKCS8_ENC_PRIVATEKEY_TYPE;
if (!wp_dh_encode_epki(ctx, key, derData, &derLen, pwCb, pwCbArg)) {
ok = 0;
}
}
Expand All @@ -2775,7 +2839,7 @@ static int wp_dh_encode(wp_DhEncDecCtx* ctx, OSSL_CORE_BIO *cBio,
keyLen = derLen;
}
else if (ok && (ctx->encoding == WP_FORMAT_PEM)) {
rc = wc_DerToPemEx(derData, (word32)derLen, NULL, 0, cipherInfo,
rc = wc_DerToPemEx(derData, (word32)derLen, NULL, 0, NULL,
pemType);
if (rc <= 0) {
ok = 0;
Expand All @@ -2789,7 +2853,7 @@ static int wp_dh_encode(wp_DhEncDecCtx* ctx, OSSL_CORE_BIO *cBio,
}
if (ok) {
rc = wc_DerToPemEx(derData, (word32)derLen, pemData, (word32)pemLen,
cipherInfo, pemType);
NULL, pemType);
if (rc <= 0) {
ok = 0;
}
Expand All @@ -2814,7 +2878,6 @@ static int wp_dh_encode(wp_DhEncDecCtx* ctx, OSSL_CORE_BIO *cBio,
OPENSSL_free(derData);
OPENSSL_free(pemData);
}
OPENSSL_free(cipherInfo);

BIO_free(out);
#else
Expand Down
Loading
Loading