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
1 change: 1 addition & 0 deletions include/wolfprovider/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ int wp_init_cast(int algo);
int wolfssl_prov_get_capabilities(void *provctx, const char *capability,
OSSL_CALLBACK *cb, void *arg);

unsigned char* wp_octet_dup(const unsigned char* data, size_t len);
int wp_name_to_nid(OSSL_LIB_CTX* libCtx, const char* name, const char* propQ);
enum wc_HashType wp_name_to_wc_hash_type(OSSL_LIB_CTX* libCtx, const char* name,
const char* propQ);
Expand Down
62 changes: 62 additions & 0 deletions src/wp_hkdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,66 @@ static void wp_kdf_hkdf_reset(wp_HkdfCtx* ctx)
}
}

/**
* Duplicate the HKDF context object.
*
* Deep copies the configured key material so the copy derives identically.
*
* @param [in] src HKDF context object.
* @return New HKDF context object on success.
* @return NULL on failure.
*/
static wp_HkdfCtx* wp_kdf_hkdf_dup(wp_HkdfCtx* src)
{
wp_HkdfCtx* dst = NULL;

if (wolfssl_prov_is_running()) {
dst = wp_kdf_hkdf_new(src->provCtx);
}
if (dst != NULL) {
int ok = 1;

dst->mode = src->mode;
dst->mdType = src->mdType;
dst->mdLen = src->mdLen;
dst->keySz = src->keySz;
dst->saltSz = src->saltSz;
dst->infoSz = src->infoSz;
dst->prefixLen = src->prefixLen;
dst->labelLen = src->labelLen;
dst->dataLen = src->dataLen;
XMEMCPY(dst->info, src->info, src->infoSz);

if (ok && (src->key != NULL)) {
dst->key = wp_octet_dup(src->key, src->keySz);
ok = dst->key != NULL;
}
if (ok && (src->salt != NULL)) {
dst->salt = wp_octet_dup(src->salt, src->saltSz);
ok = dst->salt != NULL;
}
if (ok && (src->prefix != NULL)) {
dst->prefix = wp_octet_dup(src->prefix, src->prefixLen);
ok = dst->prefix != NULL;
}
if (ok && (src->label != NULL)) {
dst->label = wp_octet_dup(src->label, src->labelLen);
ok = dst->label != NULL;
}
if (ok && (src->data != NULL)) {
dst->data = wp_octet_dup(src->data, src->dataLen);
ok = dst->data != NULL;
}

if (!ok) {
wp_kdf_hkdf_free(dst);
dst = NULL;
}
}

return dst;
}

/**
* Derive a key using HKDF.
*
Expand Down Expand Up @@ -528,6 +588,7 @@ static const OSSL_PARAM* wp_kdf_hkdf_gettable_ctx_params(wp_HkdfCtx* ctx,
/** Dispatch table for HKDF functions implemented using wolfSSL. */
const OSSL_DISPATCH wp_kdf_hkdf_functions[] = {
{ OSSL_FUNC_KDF_NEWCTX, (DFUNC)wp_kdf_hkdf_new },
{ OSSL_FUNC_KDF_DUPCTX, (DFUNC)wp_kdf_hkdf_dup },
{ OSSL_FUNC_KDF_FREECTX, (DFUNC)wp_kdf_hkdf_free },
{ OSSL_FUNC_KDF_RESET, (DFUNC)wp_kdf_hkdf_reset },
{ OSSL_FUNC_KDF_DERIVE, (DFUNC)wp_kdf_hkdf_derive },
Expand Down Expand Up @@ -795,6 +856,7 @@ static const OSSL_PARAM* wp_kdf_tls1_3_settable_ctx_params(wp_HkdfCtx* ctx,
/** Dispatch table for TLS 1.3 HKDF functions implemented using wolfSSL. */
const OSSL_DISPATCH wp_kdf_tls1_3_kdf_functions[] = {
{ OSSL_FUNC_KDF_NEWCTX, (DFUNC)wp_kdf_hkdf_new },
{ OSSL_FUNC_KDF_DUPCTX, (DFUNC)wp_kdf_hkdf_dup },
{ OSSL_FUNC_KDF_FREECTX, (DFUNC)wp_kdf_hkdf_free },
{ OSSL_FUNC_KDF_RESET, (DFUNC)wp_kdf_hkdf_reset },
{ OSSL_FUNC_KDF_DERIVE, (DFUNC)wp_kdf_tls1_3_derive },
Expand Down
28 changes: 28 additions & 0 deletions src/wp_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,34 @@ int wp_unlock(wolfSSL_Mutex* mutex)
}


/**
* Duplicate a configured octet buffer.
*
* OPENSSL_memdup() returns NULL for a zero length, so a 1-byte buffer is
* allocated for the empty case. This preserves the non-NULL, zero-length
* state that consumers may distinguish from a NULL (absent) buffer.
*
* @param [in] data Buffer to duplicate. May be NULL.
* @param [in] len Length of buffer in bytes.
* @return Allocated copy on success.
* @return NULL when data is NULL, or on allocation failure.
*/
unsigned char* wp_octet_dup(const unsigned char* data, size_t len)
{
unsigned char* ret;

if (data == NULL) {
ret = NULL;
}
else if (len == 0) {
ret = OPENSSL_zalloc(1);
}
else {
ret = OPENSSL_memdup(data, len);
}
return ret;
}

/**
* Convert the string name of an object to an OpenSSL Numeric ID (NID).
*
Expand Down
Loading
Loading