diff options
39 files changed, 3982 insertions, 122 deletions
diff --git a/crypto/build.info b/crypto/build.info index 35e012d5d2..1c9ca3a809 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -6,7 +6,7 @@ SUBDIRS=objects buffer bio stack lhash rand evp asn1 pem x509 conf \ siphash sm3 des aes rc2 rc4 rc5 idea aria bf cast camellia \ seed sm4 chacha modes bn ec rsa dsa dh sm2 dso engine \ err comp http ocsp cms ts srp cmac ct async ess crmf cmp encode_decode \ - ffc + ffc hpke LIBS=../libcrypto diff --git a/crypto/ec/build.info b/crypto/ec/build.info index a511e887a9..e4799ad37a 100644 --- a/crypto/ec/build.info +++ b/crypto/ec/build.info @@ -92,6 +92,7 @@ INCLUDE[ecp_nistz256-sparcv9.o]=.. INCLUDE[ecp_s390x_nistp.o]=.. INCLUDE[ecx_s390x.o]=.. INCLUDE[ecx_meth.o]=.. +INCLUDE[ecx_key.o]=.. GENERATE[ecp_nistz256-armv4.S]=asm/ecp_nistz256-armv4.pl INCLUDE[ecp_nistz256-armv4.o]=.. diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c index 1bbca360e2..44bac9afa7 100644 --- a/crypto/ec/ec_key.c +++ b/crypto/ec/ec_key.c @@ -24,6 +24,7 @@ #endif #include <openssl/self_test.h> #include "prov/providercommon.h" +#include "prov/ecx.h" #include "crypto/bn.h" static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb, @@ -350,6 +351,43 @@ err: return ok; } +#ifndef FIPS_MODULE +/* + * This is similar to ec_generate_key(), except it uses an ikm to + * derive the private key. + */ +int ossl_ec_generate_key_dhkem(EC_KEY *eckey, + const unsigned char *ikm, size_t ikmlen) +{ + int ok = 0; + + if (eckey->priv_key == NULL) { + eckey->priv_key = BN_secure_new(); + if (eckey->priv_key == NULL) + goto err; + } + if (ossl_ec_dhkem_derive_private(eckey, eckey->priv_key, ikm, ikmlen) <= 0) + goto err; + if (eckey->pub_key == NULL) { + eckey->pub_key = EC_POINT_new(eckey->group); + if (eckey->pub_key == NULL) + goto err; + } + if (!ossl_ec_key_simple_generate_public_key(eckey)) + goto err; + + ok = 1; +err: + if (!ok) { + BN_clear_free(eckey->priv_key); + eckey->priv_key = NULL; + if (eckey->pub_key != NULL) + EC_POINT_set_to_infinity(eckey->group, eckey->pub_key); + } + return ok; +} +#endif + int ossl_ec_key_simple_generate_key(EC_KEY *eckey) { return ec_generate_key(eckey, 0); diff --git a/crypto/ec/ecx_key.c b/crypto/ec/ecx_key.c index dcec26c2e9..8cf7f1708c 100644 --- a/crypto/ec/ecx_key.c +++ b/crypto/ec/ecx_key.c @@ -9,7 +9,13 @@ #include <string.h> #include <openssl/err.h> +#include <openssl/proverr.h> #include "crypto/ecx.h" +#include "internal/common.h" /* for ossl_assert() */ + +#ifdef S390X_EC_ASM +# include "s390x_arch.h" +#endif ECX_KEY *ossl_ecx_key_new(OSSL_LIB_CTX *libctx, ECX_KEY_TYPE type, int haspubkey, const char *propq) @@ -96,3 +102,61 @@ unsigned char *ossl_ecx_key_allocate_privkey(ECX_KEY *key) return key->privkey; } + +int ossl_ecx_compute_key(ECX_KEY *peer, ECX_KEY *priv, size_t keylen, + unsigned char *secret, size_t *secretlen, size_t outlen) +{ + if (priv == NULL + || priv->privkey == NULL + || peer == NULL) { + ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY); + return 0; + } + + if (!ossl_assert(keylen == X25519_KEYLEN + || keylen == X448_KEYLEN)) { + ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH); + return 0; + } + + if (secret == NULL) { + *secretlen = keylen; + return 1; + } + if (outlen < keylen) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (keylen == X25519_KEYLEN) { +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X25519)) { + if (s390x_x25519_mul(secret, peer->pubkey, priv->privkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else +#endif + if (ossl_x25519(secret, priv->privkey, peer->pubkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else { +#ifdef S390X_EC_ASM + if (OPENSSL_s390xcap_P.pcc[1] + & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_X448)) { + if (s390x_x448_mul(secret, peer->pubkey, priv->privkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } else +#endif + if (ossl_x448(secret, priv->privkey, peer->pubkey) == 0) { + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return 0; + } + } + *secretlen = keylen; + return 1; +} diff --git a/crypto/evp/evp_local.h b/crypto/evp/evp_local.h index a853174452..8c26e8fd6d 100644 --- a/crypto/evp/evp_local.h +++ b/crypto/evp/evp_local.h @@ -228,6 +228,8 @@ struct evp_kem_st { OSSL_FUNC_kem_gettable_ctx_params_fn *gettable_ctx_params; OSSL_FUNC_kem_set_ctx_params_fn *set_ctx_params; OSSL_FUNC_kem_settable_ctx_params_fn *settable_ctx_params; + OSSL_FUNC_kem_auth_encapsulate_init_fn *auth_encapsulate_init; + OSSL_FUNC_kem_auth_decapsulate_init_fn *auth_decapsulate_init; } /* EVP_KEM */; int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, diff --git a/crypto/evp/kem.c b/crypto/evp/kem.c index bd28ede7ae..8c0c35b54b 100644 --- a/crypto/evp/kem.c +++ b/crypto/evp/kem.c @@ -18,13 +18,13 @@ #include "evp_local.h" static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, - const OSSL_PARAM params[]) + const OSSL_PARAM params[], EVP_PKEY *authkey) { int ret = 0; EVP_KEM *kem = NULL; EVP_KEYMGMT *tmp_keymgmt = NULL; const OSSL_PROVIDER *tmp_prov = NULL; - void *provkey = NULL; + void *provkey = NULL, *provauthkey = NULL; const char *supported_kem = NULL; int iter; @@ -40,7 +40,10 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, ERR_raise(ERR_LIB_EVP, EVP_R_NO_KEY_SET); goto err; } - + if (authkey != NULL && authkey->type != ctx->pkey->type) { + ERR_raise(ERR_LIB_EVP, EVP_R_DIFFERENT_KEY_TYPES); + return 0; + } /* * Try to derive the supported kem from |ctx->keymgmt|. */ @@ -114,16 +117,26 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, * same property query as when fetching the kem method. * With the keymgmt we found (if we did), we try to export |ctx->pkey| * to it (evp_pkey_export_to_provider() is smart enough to only actually - * export it if |tmp_keymgmt| is different from |ctx->pkey|'s keymgmt) */ tmp_keymgmt_tofree = tmp_keymgmt = evp_keymgmt_fetch_from_prov((OSSL_PROVIDER *)tmp_prov, EVP_KEYMGMT_get0_name(ctx->keymgmt), ctx->propquery); - if (tmp_keymgmt != NULL) + if (tmp_keymgmt != NULL) { provkey = evp_pkey_export_to_provider(ctx->pkey, ctx->libctx, &tmp_keymgmt, ctx->propquery); + if (provkey != NULL && authkey != NULL) { + provauthkey = evp_pkey_export_to_provider(authkey, ctx->libctx, + &tmp_keymgmt, + ctx->propquery); + if (provauthkey == NULL) { + EVP_KEM_free(kem); + ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); + goto err; + } + } + } if (tmp_keymgmt == NULL) EVP_KEYMGMT_free(tmp_keymgmt_tofree); } @@ -144,20 +157,28 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, switch (operation) { case EVP_PKEY_OP_ENCAPSULATE: - if (kem->encapsulate_init == NULL) { + if (provauthkey != NULL && kem->auth_encapsulate_init != NULL) { + ret = kem->auth_encapsulate_init(ctx->op.encap.algctx, provkey, + provauthkey, params); + } else if (provauthkey == NULL && kem->encapsulate_init != NULL) { + ret = kem->encapsulate_init(ctx->op.encap.algctx, provkey, params); + } else { ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ret = -2; goto err; } - ret = kem->encapsulate_init(ctx->op.encap.algctx, provkey, params); break; case EVP_PKEY_OP_DECAPSULATE: - if (kem->decapsulate_init == NULL) { + if (provauthkey != NULL && kem->auth_decapsulate_init != NULL) { + ret = kem->auth_decapsulate_init(ctx->op.encap.algctx, provkey, + provauthkey, params); + } else if (provauthkey == NULL && kem->encapsulate_init != NULL) { + ret = kem->decapsulate_init(ctx->op.encap.algctx, provkey, params); + } else { ERR_raise(ERR_LIB_EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); ret = -2; goto err; } - ret = kem->decapsulate_init(ctx->op.encap.algctx, provkey, params); break; default: ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR); @@ -178,9 +199,17 @@ static int evp_kem_init(EVP_PKEY_CTX *ctx, int operation, return ret; } +int EVP_PKEY_auth_encapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpriv, + const OSSL_PARAM params[]) +{ + if (authpriv == NULL) + return 0; + return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params, authpriv); +} + int EVP_PKEY_encapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) { - return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params); + return evp_kem_init(ctx, EVP_PKEY_OP_ENCAPSULATE, params, NULL); } int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, @@ -209,7 +238,15 @@ int EVP_PKEY_encapsulate(EVP_PKEY_CTX *ctx, int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]) { - return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params); + return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params, NULL); +} + +int EVP_PKEY_auth_decapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpub, + const OSSL_PARAM params[]) +{ + if (authpub == NULL) + return 0; + return evp_kem_init(ctx, EVP_PKEY_OP_DECAPSULATE, params, authpub); } int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, @@ -288,6 +325,12 @@ static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, kem->encapsulate_init = OSSL_FUNC_kem_encapsulate_init(fns); encfncnt++; break; + case OSSL_FUNC_KEM_AUTH_ENCAPSULATE_INIT: + if (kem->auth_encapsulate_init != NULL) + break; + kem->auth_encapsulate_init = OSSL_FUNC_kem_auth_encapsulate_init(fns); + encfncnt++; + break; case OSSL_FUNC_KEM_ENCAPSULATE: if (kem->encapsulate != NULL) break; @@ -300,6 +343,12 @@ static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, kem->decapsulate_init = OSSL_FUNC_kem_decapsulate_init(fns); decfncnt++; break; + case OSSL_FUNC_KEM_AUTH_DECAPSULATE_INIT: + if (kem->auth_decapsulate_init != NULL) + break; + kem->auth_decapsulate_init = OSSL_FUNC_kem_auth_decapsulate_init(fns); + decfncnt++; + break; case OSSL_FUNC_KEM_DECAPSULATE: if (kem->decapsulate != NULL) break; @@ -348,19 +397,21 @@ static void *evp_kem_from_algorithm(int name_id, const OSSL_ALGORITHM *algodef, } } if (ctxfncnt != 2 - || (encfncnt != 0 && encfncnt != 2) - || (decfncnt != 0 && decfncnt != 2) - || (encfncnt != 2 && decfncnt != 2) + || (encfncnt != 0 && encfncnt != 2 && encfncnt != 3) + || (decfncnt != 0 && decfncnt != 2 && decfncnt != 3) + || (encfncnt != decfncnt) || (gparamfncnt != 0 && gparamfncnt != 2) || (sparamfncnt != 0 && sparamfncnt != 2)) { /* * In order to be a consistent set of functions we must have at least - * a set of context functions (newctx and freectx) as well as a pair of - * "kem" functions: (encapsulate_init, encapsulate) or - * (decapsulate_init, decapsulate). set_ctx_params and settable_ctx_params are - * optional, but if one of them is present then the other one must also - * be present. The same applies to get_ctx_params and - * gettable_ctx_params. The dupctx function is optional. + * a set of context functions (newctx and freectx) as well as a pair + * (or triplet) of "kem" functions: + * (encapsulate_init, (and/or auth_encapsulate_init), encapsulate) or + * (decapsulate_init, (and/or auth_decapsulate_init), decapsulate). + * set_ctx_params and settable_ctx_params are optional, but if one of + * them is present then the other one must also be present. The same + * applies to get_ctx_params and gettable_ctx_params. + * The dupctx function is optional. */ ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS); goto err; diff --git a/crypto/hpke/build.info b/crypto/hpke/build.info new file mode 100644 index 0000000000..f096cf170b --- /dev/null +++ b/crypto/hpke/build.info @@ -0,0 +1,5 @@ +LIBS=../../libcrypto + +$COMMON=hpke_util.c + +SOURCE[../../libcrypto]=$COMMON diff --git a/crypto/hpke/hpke_util.c b/crypto/hpke/hpke_util.c new file mode 100644 index 0000000000..92f9892a41 --- /dev/null +++ b/crypto/hpke/hpke_util.c @@ -0,0 +1,175 @@ +/* + * Copyright 2022 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 + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/core_names.h> +#include <openssl/kdf.h> +#include <openssl/params.h> +#include <openssl/err.h> +#include <openssl/proverr.h> +#include "crypto/hpke.h" +#include "internal/packet.h" + +/* + * The largest value happens inside dhkem_extract_and_expand + * Which consists of a max dkmlen of 2*privkeylen + suiteid + small label + */ +#define LABELED_EXTRACT_SIZE (10 + 12 + 2 * OSSL_HPKE_MAX_PRIVATE) + +/* + * The largest value happens inside dhkem_extract_and_expand + * Which consists of a prklen of secretlen + contextlen of 3 encoded public keys + * + suiteid + small label + */ +#define LABELED_EXPAND_SIZE (LABELED_EXTRACT_SIZE + 3 * OSSL_HPKE_MAX_PUBLIC) + +/* ASCII: "HPKE-v1", in hex for EBCDIC compatibility */ +static const char LABEL_HPKEV1[] = "\x48\x50\x4B\x45\x2D\x76\x31"; + +static int kdf_derive(EVP_KDF_CTX *kctx, + unsigned char *out, size_t outlen, int mode, + const unsigned char *salt, size_t saltlen, + const unsigned char *ikm, size_t ikmlen, + const unsigned char *info, size_t infolen) +{ + int ret; + OSSL_PARAM params[5], *p = params; + + *p++ = OSSL_PARAM_construct_int(OSSL_KDF_PARAM_MODE, &mode); + if (salt != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_SALT, + (char *)salt, saltlen); + if (ikm != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_KEY, + (char *)ikm, ikmlen); + if (info != NULL) + *p++ = OSSL_PARAM_construct_octet_string(OSSL_KDF_PARAM_INFO, + (char *)info, infolen); + *p = OSSL_PARAM_construct_end(); + ret = EVP_KDF_derive(kctx, out, outlen, params) > 0; + if (!ret) + ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_DURING_DERIVATION); + return ret; +} + +int ossl_hpke_kdf_extract(EVP_KDF_CTX *kctx, + unsigned char *prk, size_t prklen, + const unsigned char *salt, size_t saltlen, + const unsigned char *ikm, size_t ikmlen) +{ + return kdf_derive(kctx, prk, prklen, EVP_KDF_HKDF_MODE_EXTRACT_ONLY, + salt, saltlen, ikm, ikmlen, NULL, 0); +} + +/* Common code to perform a HKDF expand */ +int ossl_hpke_kdf_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + const unsigned char *prk, size_t prklen, + const unsigned char *info, size_t infolen) +{ + return kdf_derive(kctx, okm, okmlen, EVP_KDF_HKDF_MODE_EXPAND_ONLY, + NULL, 0, prk, prklen, info, infolen); +} + +/* + * See RFC 9180 Section 4 LabelExtract() + */ +int ossl_hpke_labeled_extract(EVP_KDF_CTX *kctx, + unsigned char *prk, size_t prklen, + const unsigned char *salt, size_t saltlen, + const unsigned char *suiteid, size_t suiteidlen, + const char *label, + const unsigned char *ikm, size_t ikmlen) +{ + int ret = 0; + size_t labeled_ikmlen = 0; + unsigned char labeled_ikm[LABELED_EXTRACT_SIZE]; + WPACKET pkt; + + /* labeled_ikm = concat("HPKE-v1", suiteid, label, ikm) */ + if (!WPACKET_init_static_len(&pkt, labeled_ikm, sizeof(labeled_ikm), 0) + || !WPACKET_memcpy(&pkt, LABEL_HPKEV1, strlen(LABEL_HPKEV1)) + || !WPACKET_memcpy(&pkt, suiteid, suiteidlen) + || !WPACKET_memcpy(&pkt, label, strlen(label)) + || !WPACKET_memcpy(&pkt, ikm, ikmlen) + || !WPACKET_get_total_written(&pkt, &labeled_ikmlen) + || !WPACKET_finish(&pkt)) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + goto end; + } + + ret = ossl_hpke_kdf_extract(kctx, prk, prklen, salt, saltlen, + labeled_ikm, labeled_ikmlen); +end: + WPACKET_cleanup(&pkt); + OPENSSL_cleanse(labeled_ikm, labeled_ikmlen); + return ret; +} + +/* + * See RFC 9180 Section 4 LabelExpand() + */ +int ossl_hpke_labeled_expand(EVP_KDF_CTX *kctx, + unsigned char *okm, size_t okmlen, + const unsigned char *prk, size_t prklen, + const unsigned char *suiteid, size_t suiteidlen, + const char *label, + const unsigned char *info, size_t infolen) +{ + int ret = 0; + size_t labeled_infolen = 0; + unsigned char labeled_info[LABELED_EXPAND_SIZE]; + WPACKET pkt; + + /* labeled_info = concat(okmlen, "HPKE-v1", suiteid, label, info) */ + if (!WPACKET_init_static_len(&pkt, labeled_info, sizeof(labeled_info), 0) + || !WPACKET_put_bytes_u16(&pkt, okmlen) + || !WPACKET_memcpy(&pkt, LABEL_HPKEV1, strlen(LABEL_HPKEV1)) + || !WPACKET_memcpy(&pkt, suiteid, suiteidlen) + || !WPACKET_memcpy(&pkt, label, strlen(label)) + || !WPACKET_memcpy(&pkt, info, infolen) + || !WPACKET_get_total_written(&pkt, &labeled_infolen) + || !WPACKET_finish(&pkt)) { + ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + goto end; + } + + ret = ossl_hpke_kdf_expand(kctx, okm, okmlen, + prk, prklen, labeled_info, labeled_infolen); +end: + WPACKET_cleanup(&pkt); + return ret; +} + +/* Common code to create a HKDF ctx */ +EVP_KDF_CTX *ossl_kdf_ctx_create(const char *kdfname, const char *mdname, + OSSL_LIB_CTX *libctx, const char *propq) +{ + EVP_KDF *kdf; + EVP_KDF_CTX *kctx = NULL; + + kdf = EVP_KDF_fetch(libctx, kdfname, propq); + kctx = EVP_KDF_CTX_new(kdf); + EVP_KDF_free(kdf); + if (kctx != NULL && mdname != NULL) { + OSSL_PARAM params[3], *p = params; + + if (mdname != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_DIGEST, + (char *)mdname, 0); + if (propq != NULL) + *p++ = OSSL_PARAM_construct_utf8_string(OSSL_KDF_PARAM_PROPERTIES, + (char *)propq, 0); + *p = OSSL_PARAM_construct_end(); + if (EVP_KDF_CTX_set_params(kctx, params) <= 0) { + EVP_KDF_CTX_free(kctx); + return NULL; + } + } + return kctx; +} diff --git a/doc/build.info b/doc/build.info index b90ad11eae..8b55bcdbc7 100644 --- a/doc/build.info +++ b/doc/build.info @@ -4209,10 +4209,18 @@ DEPEND[html/man7/EVP_KDF-X963.html]=man7/EVP_KDF-X963.pod GENERATE[html/man7/EVP_KDF-X963.html]=man7/EVP_KDF-X963.pod DEPEND[man/man7/EVP_KDF-X963.7]=man7/EVP_KDF-X963.pod GENERATE[man/man7/EVP_KDF-X963.7]=man7/EVP_KDF-X963.pod +DEPEND[html/man7/EVP_KEM-EC.html]=man7/EVP_KEM-EC.pod +GENERATE[html/man7/EVP_KEM-EC.html]=man7/EVP_KEM-EC.pod +DEPEND[man/man7/EVP_KEM-EC.7]=man7/EVP_KEM-EC.pod +GENERATE[man/man7/EVP_KEM-EC.7]=man7/EVP_KEM-EC.pod DEPEND[html/man7/EVP_KEM-RSA.html]=man7/EVP_KEM-RSA.pod GENERATE[html/man7/EVP_KEM-RSA.html]=man7/EVP_KEM-RSA.pod DEPEND[man/man7/EVP_KEM-RSA.7]=man7/EVP_KEM-RSA.pod GENERATE[man/man7/EVP_KEM-RSA.7]=man7/EVP_KEM-RSA.pod +DEPEND[html/man7/EVP_KEM-X25519.html]=man7/EVP_KEM-X25519.pod +GENERATE[html/man7/EVP_KEM-X25519.html]=man7/EVP_KEM-X25519.pod +DEPEND[man/man7/EVP_KEM-X25519.7]=man7/EVP_KEM-X25519.pod +GENERATE[man/man7/EVP_KEM-X25519.7]=man7/EVP_KEM-X25519.pod DEPEND[html/man7/EVP_KEYEXCH-DH.html]=man7/EVP_KEYEXCH-DH.pod GENERATE[html/man7/EVP_KEYEXCH-DH.html]=man7/EVP_KEYEXCH-DH.pod DEPEND[man/man7/EVP_KEYEXCH-DH.7]=man7/EVP_KEYEXCH-DH.pod @@ -4630,7 +4638,9 @@ html/man7/EVP_KDF-TLS1_PRF.html \ html/man7/EVP_KDF-X942-ASN1.html \ html/man7/EVP_KDF-X942-CONCAT.html \ html/man7/EVP_KDF-X963.html \ +html/man7/EVP_KEM-EC.html \ html/man7/EVP_KEM-RSA.html \ +html/man7/EVP_KEM-X25519.html \ html/man7/EVP_KEYEXCH-DH.html \ html/man7/EVP_KEYEXCH-ECDH.html \ html/man7/EVP_KEYEXCH-X25519.html \ @@ -4755,7 +4765,9 @@ man/man7/EVP_KDF-TLS1_PRF.7 \ man/man7/EVP_KDF-X942-ASN1.7 \ man/man7/EVP_KDF-X942-CONCAT.7 \ man/man7/EVP_KDF-X963.7 \ +man/man7/EVP_KEM-EC.7 \ man/man7/EVP_KEM-RSA.7 \ +man/man7/EVP_KEM-X25519.7 \ man/man7/EVP_KEYEXCH-DH.7 \ man/man7/EVP_KEYEXCH-ECDH.7 \ man/man7/EVP_KEYEXCH-X25519.7 \ diff --git a/doc/man3/EVP_PKEY_decapsulate.pod b/doc/man3/EVP_PKEY_decapsulate.pod index 529e318f9e..cdda54d12f 100644 --- a/doc/man3/EVP_PKEY_decapsulate.pod +++ b/doc/man3/EVP_PKEY_decapsulate.pod @@ -2,7 +2,7 @@ =head1 NAME -EVP_PKEY_decapsulate_init, EVP_PKEY_decapsulate +EVP_PKEY_decapsulate_init, EVP_PKEY_auth_decapsulate_init, EVP_PKEY_decapsulate - Key decapsulation using a private key algorithm =head1 SYNOPSIS @@ -10,6 +10,8 @@ EVP_PKEY_decapsulate_init, EVP_PKEY_decapsulate #include <openssl/evp.h> int EVP_PKEY_decapsulate_init(EVP_PKEY_CTX *ctx, const OSSL_PARAM params[]); + int EVP_PKEY_auth_decapsulate_init(EVP_PKEY_CTX *ctx, EVP_PKEY *authpub, + const OSSL_PARAM params[]); int EVP_PKEY_decapsulate(EVP_PKEY_CTX *ctx, unsigned char *secret, size_t *secretlen, const unsigned char *wrapped, size_t wrappedlen); @@ -20,6 +22,10 @@ The EVP_PKEY_decapsulate_init() function initializes a private key algorithm context I<ctx> for a decapsulation operation and then sets the I<params> on the context in the same way as calling L<EVP_PKEY_CTX_set_params(3)>. +The EVP_PKEY_auth_decapsulate_init() function is similiar to +EVP_PKEY_decapsulate_init() but also passes an I<authpub> authentication public +key that is used during decapsulation. + The EVP_PKEY_decapsulate() function performs a private key decapsulation operation using I<ctx>. The data to be decapsulated is specified using the I<wrapped> and I<wrappedlen> parameters. @@ -35,9 +41,10 @@ for the operation may be set or modified using L<EVP_PKEY_CTX_set_params(3)>. =head1 RETURN VALUES -EVP_PKEY_decapsulate_init() and EVP_PKEY_decapsulate() 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 private key algorithm. +EVP_PKEY_decapsulate_init(), EVP_PKEY_auth_decapsulate_init() and +EVP_PKEY_decapsulate() 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 private key algorithm. =head1 EXAMPLES @@ -73,7 +80,7 @@ Decapsulate data using RSA: /* malloc failure */ /* Decapsulated secret data is secretlen bytes long */ - if (EVP_PKEY_decapsulaterctx, secret, &secretlen, in, inlen) <= 0) + if (EVP_PKEY_decapsulate(ctx, secret, &secretlen, in, inlen) <= 0) /* Error */ @@ -81,15 +88,18 @@ Decapsulate data using RSA: L<EVP_PKEY_CTX_new(3)>, L<EVP_PKEY_encapsulate(3)>, -L<EVP_KEM-RSA(7)>, +L<EVP_KEM-RSA(7)>, L<EVP_KEM-X25519(7)>, L<EVP_KEM-EC(7)> =head1 HISTORY -These functions were added in OpenSSL 3.0. |