Skip to content

Commit

Permalink
Add EVP_KDF_CTX_set_SKEY
Browse files Browse the repository at this point in the history
This allows to use a SKEY as input to a KDF derive operation.

Signed-off-by: Simo Sorce <[email protected]>
  • Loading branch information
simo5 authored and beldmit committed Feb 5, 2025
1 parent 286b142 commit 45683b9
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 7 deletions.
61 changes: 61 additions & 0 deletions crypto/evp/kdf_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "internal/numbers.h"
#include "internal/provider.h"
#include "evp_local.h"
#include "internal/param_build_set.h"

EVP_KDF_CTX *EVP_KDF_CTX_new(EVP_KDF *kdf)
{
Expand Down Expand Up @@ -144,6 +145,66 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen,
return ctx->meth->derive(ctx->algctx, key, keylen, params);
}

struct convert_key {
const char *name;
OSSL_PARAM *param;
};

static int convert_key_cb(const OSSL_PARAM params[], void *arg)
{
struct convert_key *ckey = arg;
const OSSL_PARAM *raw_bytes;
unsigned char *data;
size_t len;

raw_bytes = OSSL_PARAM_locate_const(params, OSSL_SKEY_PARAM_RAW_BYTES);
if (raw_bytes == NULL)
return 0;

if (!OSSL_PARAM_get_octet_string_ptr(raw_bytes, (const void **)&data, &len))
return 0;

*ckey->param = OSSL_PARAM_construct_octet_string(ckey->name, data, len);
return 1;
}

int EVP_KDF_CTX_set_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *key, const char *paramname)
{
struct convert_key ckey;

if (ctx == NULL)
return 0;

ckey.name = (paramname != NULL) ? paramname : OSSL_KDF_PARAM_KEY;

if (ctx->meth->set_skey != NULL) {
if (ctx->meth->prov != key->skeymgmt->prov) {
/* TODO: export/import dance */
return 0;
}
return ctx->meth->set_skey(ctx->algctx, key->keydata, ckey.name);
} else {
/*
* Provider does not support opaque keys, try to export and
* set params.
*/
OSSL_PARAM params[2] = {
OSSL_PARAM_END,
OSSL_PARAM_END,
};
ckey.param = &params[0];

if (!ctx->meth->set_ctx_params)
return 0;

if (EVP_SKEY_export(key, OSSL_SKEYMGMT_SELECT_SECRET_KEY,
convert_key_cb, &ckey))
return ctx->meth->set_ctx_params(ctx->algctx, params);

return 0;
}
}

EVP_SKEY *EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, const char *key_type,
size_t keylen, const OSSL_PARAM params[])
{
Expand Down
5 changes: 5 additions & 0 deletions crypto/evp/kdf_meth.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ static void *evp_kdf_from_algorithm(int name_id,
break;
kdf->set_ctx_params = OSSL_FUNC_kdf_set_ctx_params(fns);
break;
case OSSL_FUNC_KDF_SET_SKEY:
if (kdf->set_skey != NULL)
break;
kdf->set_skey = OSSL_FUNC_kdf_set_skey(fns);
break;
case OSSL_FUNC_KDF_DERIVE_SKEY:
if (kdf->derive_skey != NULL)
break;
Expand Down
15 changes: 12 additions & 3 deletions doc/man3/EVP_KDF.pod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

EVP_KDF, EVP_KDF_fetch, EVP_KDF_free, EVP_KDF_up_ref,
EVP_KDF_CTX, EVP_KDF_CTX_new, EVP_KDF_CTX_free, EVP_KDF_CTX_dup,
EVP_KDF_CTX_reset, EVP_KDF_derive, EVP_KDF_derive_SKEY,
EVP_KDF_CTX_reset, EVP_KDF_derive,
EVP_KDF_CTX_set_SKEY, EVP_KDF_derive_SKEY,
EVP_KDF_CTX_get_kdf_size,
EVP_KDF_get0_provider, EVP_KDF_CTX_kdf, EVP_KDF_is_a,
EVP_KDF_get0_name, EVP_KDF_names_do_all, EVP_KDF_get0_description,
Expand All @@ -28,6 +29,7 @@ EVP_KDF_CTX_gettable_params, EVP_KDF_CTX_settable_params - EVP KDF routines
size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx);
int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[]);
int EVP_KDF_CTX_set_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *key, const char *paramname);
EVP_SKEY *EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, EVP_SKEYMGMT *skeymgmt,
const OSSL_PARAM params[]);
int EVP_KDF_up_ref(EVP_KDF *kdf);
Expand Down Expand Up @@ -62,8 +64,8 @@ algorithms and should be used instead of algorithm-specific functions.
After creating a B<EVP_KDF_CTX> for the required algorithm using
EVP_KDF_CTX_new(), inputs to the algorithm are supplied either by passing them
as part of the EVP_KDF_derive() or EVP_KDF_derive_SKEY() call or using calls to
EVP_KDF_CTX_set_params() before calling EVP_KDF_derive() or
EVP_KDF_derive_SKEY() to derive the key.
EVP_KDF_CTX_set_params() or EVP_KDF_CTX_set_SKEY() before calling
EVP_KDF_derive() or EVP_KDF_derive_SKEY() to derive the key.

=head2 Types

Expand Down Expand Up @@ -115,6 +117,13 @@ If the KDF doesn't support dealing with opaque keys or the passed
B<EVP_SKEYMGMT> is from a different provider than the KDF method, the operation
will fail.

EVP_KDF_CTX_set_SKEY() allows setting an skey object as the input key for the
derivation functions. As different KDFs may accept several parameters as key
names, we can specify the particular parameter name we set.
If null is passed, the parameter B<OSSL_KDF_PARAM_KEY> is implied.
It is used when the input key is represented by B<EVP_SKEY> rather than raw
bytes.

EVP_KDF_get_params() retrieves details about the implementation
I<kdf>.
The set of parameters given with I<params> determine exactly what
Expand Down
8 changes: 6 additions & 2 deletions doc/man7/provider-kdf.pod
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ provider-kdf - The KDF library E<lt>-E<gt> provider functions
int OSSL_FUNC_kdf_get_params(OSSL_PARAM params[]);
int OSSL_FUNC_kdf_get_ctx_params(void *kctx, OSSL_PARAM params[]);
int OSSL_FUNC_kdf_set_ctx_params(void *kctx, const OSSL_PARAM params[]);
int OSSL_FUNC_kdf_set_skey(void *kctx, void *skeydata, const char *paramname);

=head1 DESCRIPTION

Expand Down Expand Up @@ -81,6 +82,7 @@ macros in L<openssl-core_dispatch.h(7)>, as follows:
OSSL_FUNC_kdf_gettable_params OSSL_FUNC_KDF_GETTABLE_PARAMS
OSSL_FUNC_kdf_gettable_ctx_params OSSL_FUNC_KDF_GETTABLE_CTX_PARAMS
OSSL_FUNC_kdf_settable_ctx_params OSSL_FUNC_KDF_SETTABLE_CTX_PARAMS
OSSL_FUNC_kdf_set_skey OSSL_FUNC_KDF_SET_SKEY

A KDF algorithm implementation may not implement all of these functions.
In order to be a consistent set of functions, at least the following functions
Expand Down Expand Up @@ -149,6 +151,8 @@ with the provider side context I<kctx> in its current state if it is
not NULL. Otherwise, they return the parameters associated with the
provider side algorithm I<provctx>.

OSSL_FUNF_kdf_set_skey() sets the input key for KDF functions that take a
key as input.

Parameters currently recognised by built-in KDFs are as follows. Not all
parameters are relevant to, or are understood by all KDFs:
Expand Down Expand Up @@ -332,8 +336,8 @@ OSSL_FUNC_kdf_newctx() and OSSL_FUNC_kdf_dupctx() should return the newly create
provider side KDF context, or NULL on failure.

OSSL_FUNC_kdf_derive(), OSSL_FUNC_kdf_derive_skey(), OSSL_FUNC_kdf_get_params(),
OSSL_FUNC_kdf_get_ctx_params() and OSSL_FUNC_kdf_set_ctx_params() should return 1 for
success or 0 on error.
OSSL_FUNC_kdf_get_ctx_params(), OSSL_FUNC_kdf_set_ctx_params() and
OSSL_FUNC_kdf_set_skey() should return 1 for success or 0 on error.

OSSL_FUNC_kdf_gettable_params(), OSSL_FUNC_kdf_gettable_ctx_params() and
OSSL_FUNC_kdf_settable_ctx_params() should return a constant L<OSSL_PARAM(3)>
Expand Down
1 change: 1 addition & 0 deletions include/crypto/evp.h
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ struct evp_kdf_st {
OSSL_FUNC_kdf_get_params_fn *get_params;
OSSL_FUNC_kdf_get_ctx_params_fn *get_ctx_params;
OSSL_FUNC_kdf_set_ctx_params_fn *set_ctx_params;
OSSL_FUNC_kdf_set_skey_fn *set_skey;
OSSL_FUNC_kdf_derive_skey_fn *derive_skey;
};

Expand Down
8 changes: 6 additions & 2 deletions include/openssl/core_dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,8 @@ OSSL_CORE_MAKE_FUNC(int, mac_init_skey, (void *mctx, void *key, const OSSL_PARAM
# define OSSL_FUNC_KDF_GET_PARAMS 9
# define OSSL_FUNC_KDF_GET_CTX_PARAMS 10
# define OSSL_FUNC_KDF_SET_CTX_PARAMS 11
# define OSSL_FUNC_KDF_DERIVE_SKEY 12
# define OSSL_FUNC_KDF_SET_SKEY 12
# define OSSL_FUNC_KDF_DERIVE_SKEY 13

OSSL_CORE_MAKE_FUNC(void *, kdf_newctx, (void *provctx))
OSSL_CORE_MAKE_FUNC(void *, kdf_dupctx, (void *src))
Expand All @@ -495,7 +496,10 @@ OSSL_CORE_MAKE_FUNC(int, kdf_get_ctx_params,
(void *kctx, OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(int, kdf_set_ctx_params,
(void *kctx, const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(void *, kdf_derive_skey, (void *kctx, const OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(int, kdf_set_skey,
(void *kctx, void *skeydata, const char *paramname))
OSSL_CORE_MAKE_FUNC(void *, kdf_derive_skey,
(void *kctx, size_t keylen, const OSSL_PARAM params[]))

/* RAND */

Expand Down
1 change: 1 addition & 0 deletions include/openssl/kdf.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ void EVP_KDF_CTX_reset(EVP_KDF_CTX *ctx);
size_t EVP_KDF_CTX_get_kdf_size(EVP_KDF_CTX *ctx);
int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen,
const OSSL_PARAM params[]);
int EVP_KDF_CTX_set_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *key, const char *paramname);
EVP_SKEY *EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, const char *key_type,
size_t keylen, const OSSL_PARAM params[]);
int EVP_KDF_get_params(EVP_KDF *kdf, OSSL_PARAM params[]);
Expand Down
1 change: 1 addition & 0 deletions util/libcrypto.num
Original file line number Diff line number Diff line change
Expand Up @@ -5901,3 +5901,4 @@ EVP_SKEY_get0_skeymgmt_name ? 3_5_0 EXIST::FUNCTION:
EVP_SKEY_get0_provider_name ? 3_5_0 EXIST::FUNCTION:
EVP_SKEYMGMT_get0_gen_settable_params ? 3_5_0 EXIST::FUNCTION:
EVP_SKEYMGMT_get0_imp_settable_params ? 3_5_0 EXIST::FUNCTION:
EVP_KDF_CTX_set_SKEY ? 3_5_0 EXIST::FUNCTION:

0 comments on commit 45683b9

Please sign in to comment.