Skip to content

Commit

Permalink
Implement EVP_PKEY_derive_SKEY
Browse files Browse the repository at this point in the history
  • Loading branch information
beldmit committed Jan 6, 2025
1 parent 1e80ef9 commit 460f5e1
Show file tree
Hide file tree
Showing 8 changed files with 65 additions and 5 deletions.
1 change: 1 addition & 0 deletions crypto/evp/evp_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ struct evp_keyexch_st {
OSSL_FUNC_keyexch_settable_ctx_params_fn *settable_ctx_params;
OSSL_FUNC_keyexch_get_ctx_params_fn *get_ctx_params;
OSSL_FUNC_keyexch_gettable_ctx_params_fn *gettable_ctx_params;
OSSL_FUNC_keyexch_derive_opaque_fn *derive_opaque;
} /* EVP_KEYEXCH */;

struct evp_signature_st {
Expand Down
37 changes: 37 additions & 0 deletions crypto/evp/exchange.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,15 @@ static void *evp_keyexch_from_algorithm(int name_id,
= OSSL_FUNC_keyexch_settable_ctx_params(fns);
sparamfncnt++;
break;
case OSSL_FUNC_KEYEXCH_DERIVE_OPAQUE:
if (exchange->derive_opaque != NULL)
break;
exchange->derive_opaque = OSSL_FUNC_keyexch_derive_opaque(fns);
derive_found = 1;
break;
}
}
fncnt += derive_found;
if (fncnt != 4
|| (gparamfncnt != 0 && gparamfncnt != 2)
|| (sparamfncnt != 0 && sparamfncnt != 2)) {
Expand Down Expand Up @@ -534,6 +541,36 @@ int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen)
return ctx->pmeth->derive(ctx, key, pkeylen);
}

int EVP_PKEY_derive_SKEY(EVP_PKEY_CTX *ctx, EVP_SKEY *skey)
{
if (ctx == NULL || skey == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}

if (!EVP_PKEY_CTX_IS_DERIVE_OP(ctx)) {
ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_INITIALIZED);
return 0;
}

if (ctx->op.kex.algctx == NULL || ctx->op.kex.exchange->derive_opaque == NULL) {
ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED);
return 0;
}

if (skey->skeymgmt->prov != ctx->op.kex.exchange->prov) {
ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED);
return 0;
}

if (skey->keydata != NULL) {
ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED);
return 0;
}

return ctx->op.kex.exchange->derive_opaque(ctx->op.kex.algctx, &(skey->keydata));
}

int evp_keyexch_get_number(const EVP_KEYEXCH *keyexch)
{
return keyexch->name_id;
Expand Down
4 changes: 3 additions & 1 deletion crypto/evp/kdf_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,10 @@ int EVP_KDF_derive(EVP_KDF_CTX *ctx, unsigned char *key, size_t keylen,
int EVP_KDF_derive_SKEY(EVP_KDF_CTX *ctx, EVP_SKEY *skey,
const OSSL_PARAM params[])
{
if (ctx == NULL || skey == NULL)
if (ctx == NULL || skey == NULL) {
ERR_raise(ERR_LIB_EVP, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}

if (ctx->meth->derive_opaque == NULL) {
ERR_raise(ERR_R_EVP_LIB, ERR_R_UNSUPPORTED);
Expand Down
13 changes: 10 additions & 3 deletions doc/man3/EVP_PKEY_derive.pod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
=head1 NAME

EVP_PKEY_derive_init, EVP_PKEY_derive_init_ex,
EVP_PKEY_derive_set_peer_ex, EVP_PKEY_derive_set_peer, EVP_PKEY_derive
EVP_PKEY_derive_set_peer_ex, EVP_PKEY_derive_set_peer, EVP_PKEY_derive,
EVP_PKEY_derive_SKEY
- derive public key algorithm shared secret

=head1 SYNOPSIS
Expand All @@ -16,6 +17,7 @@ EVP_PKEY_derive_set_peer_ex, EVP_PKEY_derive_set_peer, EVP_PKEY_derive
int validate_peer);
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
int EVP_PKEY_derive_SKEY(EVP_PKEY_CTX *ctx, EVP_SKEY *skey);

=head1 DESCRIPTION

Expand All @@ -42,6 +44,9 @@ parameter should contain the length of the I<key> buffer, if the call is
successful the shared secret is written to I<key> and the amount of data
written to I<keylen>.

EVP_PKEY_derive_SKEY() is similar to EVP_PKEY_derive() but accepts an B<EVP_SKEY>
object that would store an opaque data for the derived key.

=head1 NOTES

After the call to EVP_PKEY_derive_init(), algorithm
Expand All @@ -53,7 +58,7 @@ context if several operations are performed using the same parameters.

=head1 RETURN VALUES

EVP_PKEY_derive_init() and EVP_PKEY_derive() return 1
EVP_PKEY_derive_init(), EVP_PKEY_derive(), and EVP_PKEY_derive_SKEY() return 1
for success and 0 or a negative value for failure.
In particular a return value of -2 indicates the operation is not supported by
the public key algorithm.
Expand Down Expand Up @@ -112,9 +117,11 @@ functions were originally added in OpenSSL 1.0.0.
The EVP_PKEY_derive_init_ex() and EVP_PKEY_derive_set_peer_ex() functions were
added in OpenSSL 3.0.

The EVP_PKEY_derive_SKEY() function was added in OpenSSL 3.5.

=head1 COPYRIGHT

Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved.
Copyright 2006-2024 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use
this file except in compliance with the License. You can obtain a copy
Expand Down
11 changes: 10 additions & 1 deletion doc/man7/provider-keyexch.pod
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ provider-keyexch - The keyexch library E<lt>-E<gt> provider functions
int OSSL_FUNC_keyexch_set_peer(void *ctx, void *provkey);
int OSSL_FUNC_keyexch_derive(void *ctx, unsigned char *secret, size_t *secretlen,
size_t outlen);
int OSSL_FUNC_keyexch_derive_opaque(void *ctx, void *secret);

/* Key Exchange parameters */
int OSSL_FUNC_keyexch_set_ctx_params(void *ctx, const OSSL_PARAM params[]);
Expand Down Expand Up @@ -73,6 +74,7 @@ macros in L<openssl-core_dispatch.h(7)>, as follows:
OSSL_FUNC_keyexch_init OSSL_FUNC_KEYEXCH_INIT
OSSL_FUNC_keyexch_set_peer OSSL_FUNC_KEYEXCH_SET_PEER
OSSL_FUNC_keyexch_derive OSSL_FUNC_KEYEXCH_DERIVE
OSSL_FUNC_keyexch_derive_opaque OSSL_FUNC_KEYEXCH_DERIVE_OPAQUE

OSSL_FUNC_keyexch_set_ctx_params OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS
OSSL_FUNC_keyexch_settable_ctx_params OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS
Expand All @@ -81,7 +83,8 @@ macros in L<openssl-core_dispatch.h(7)>, as follows:

A key exchange algorithm implementation may not implement all of these functions.
In order to be a consistent set of functions a provider must implement
OSSL_FUNC_keyexch_newctx, OSSL_FUNC_keyexch_freectx, OSSL_FUNC_keyexch_init and OSSL_FUNC_keyexch_derive.
OSSL_FUNC_keyexch_newctx, OSSL_FUNC_keyexch_freectx, OSSL_FUNC_keyexch_init and at least one
of OSSL_FUNC_keyexch_derive and OSSL_FUNC_keyexch_derive_opaque.
All other functions are optional.

A key exchange algorithm must also implement some mechanism for generating,
Expand Down Expand Up @@ -133,6 +136,9 @@ The length of the shared secret should be written to I<*secretlen>.
If I<secret> is NULL then the maximum length of the shared secret should be
written to I<*secretlen>.

OSSL_FUNC_keyexch_derive_opaque() is similar to OSSL_FUNC_keyexch_derive() but works
with an opaque provider-specific object instead of raw bytes buffer.

=head2 Key Exchange Parameters Functions

OSSL_FUNC_keyexch_set_ctx_params() sets key exchange parameters associated with the
Expand Down Expand Up @@ -242,6 +248,7 @@ OSSL_FUNC_keyexch_newctx() and OSSL_FUNC_keyexch_dupctx() should return the newl
provider side key exchange context, or NULL on failure.

OSSL_FUNC_keyexch_init(), OSSL_FUNC_keyexch_set_peer(), OSSL_FUNC_keyexch_derive(),
OSSL_FUNC_keyexch_derive_opaque(),
OSSL_FUNC_keyexch_set_params(), and OSSL_FUNC_keyexch_get_params() should return 1 for success
or 0 on error.

Expand All @@ -259,6 +266,8 @@ The provider KEYEXCH interface was introduced in OpenSSL 3.0.
The Key Exchange Parameters "fips-indicator", "key-check" and "digest-check"
were added in OpenSSL 3.4.

The OSSL_FUNC_keyexch_derive_opaque() function was added in OpenSSL 3.5.

=head1 COPYRIGHT

Copyright 2019-2024 The OpenSSL Project Authors. All Rights Reserved.
Expand Down
2 changes: 2 additions & 0 deletions include/openssl/core_dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,7 @@ OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keymgmt_export_types_ex,
# define OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS 8
# define OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS 9
# define OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS 10
# define OSSL_FUNC_KEYEXCH_DERIVE_OPAQUE 11

OSSL_CORE_MAKE_FUNC(void *, keyexch_newctx, (void *provctx))
OSSL_CORE_MAKE_FUNC(int, keyexch_init, (void *ctx, void *provkey,
Expand All @@ -729,6 +730,7 @@ OSSL_CORE_MAKE_FUNC(int, keyexch_get_ctx_params, (void *ctx,
OSSL_PARAM params[]))
OSSL_CORE_MAKE_FUNC(const OSSL_PARAM *, keyexch_gettable_ctx_params,
(void *ctx, void *provctx))
OSSL_CORE_MAKE_FUNC(int, keyexch_derive_opaque, (void *ctx, void *secret))

/* Signature */

Expand Down
1 change: 1 addition & 0 deletions include/openssl/evp.h
Original file line number Diff line number Diff line change
Expand Up @@ -1998,6 +1998,7 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
int validate_peer);
int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer);
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
int EVP_PKEY_derive_SKEY(EVP_PKEY_CTX *ctx, EVP_SKEY *skey);

int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]);
int EVP_PKEY_auth_encapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpriv,
Expand Down
1 change: 1 addition & 0 deletions util/libcrypto.num
Original file line number Diff line number Diff line change
Expand Up @@ -5758,3 +5758,4 @@ EVP_SKEY_export ? 3_5_0 EXIST::FUNCTION:
EVP_SKEY_up_ref ? 3_5_0 EXIST::FUNCTION:
EVP_SKEY_free ? 3_5_0 EXIST::FUNCTION:
EVP_KDF_derive_SKEY ? 3_5_0 EXIST::FUNCTION:
EVP_PKEY_derive_SKEY ? 3_5_0 EXIST::FUNCTION:

0 comments on commit 460f5e1

Please sign in to comment.