Path: blob/main/crypto/openssl/providers/implementations/exchange/ecx_exch.c
48383 views
/*1* Copyright 2020-2024 The OpenSSL Project Authors. All Rights Reserved.2*3* Licensed under the Apache License 2.0 (the "License"). You may not use4* this file except in compliance with the License. You can obtain a copy5* in the file LICENSE in the source distribution or at6* https://www.openssl.org/source/license.html7*/89#include <openssl/crypto.h>10#include <openssl/core_dispatch.h>11#include <openssl/core_names.h>12#include <openssl/params.h>13#include <openssl/err.h>14#include <openssl/proverr.h>15#include "internal/cryptlib.h"16#include "crypto/ecx.h"17#include "prov/implementations.h"18#include "prov/providercommon.h"19#include "prov/securitycheck.h"2021static OSSL_FUNC_keyexch_newctx_fn x25519_newctx;22static OSSL_FUNC_keyexch_newctx_fn x448_newctx;23static OSSL_FUNC_keyexch_init_fn x25519_init;24static OSSL_FUNC_keyexch_init_fn x448_init;25static OSSL_FUNC_keyexch_set_peer_fn ecx_set_peer;26static OSSL_FUNC_keyexch_derive_fn ecx_derive;27static OSSL_FUNC_keyexch_freectx_fn ecx_freectx;28static OSSL_FUNC_keyexch_dupctx_fn ecx_dupctx;29static OSSL_FUNC_keyexch_gettable_ctx_params_fn ecx_gettable_ctx_params;30static OSSL_FUNC_keyexch_get_ctx_params_fn ecx_get_ctx_params;3132/*33* What's passed as an actual key is defined by the KEYMGMT interface.34* We happen to know that our KEYMGMT simply passes ECX_KEY structures, so35* we use that here too.36*/3738typedef struct {39size_t keylen;40ECX_KEY *key;41ECX_KEY *peerkey;42} PROV_ECX_CTX;4344static void *ecx_newctx(void *provctx, size_t keylen)45{46PROV_ECX_CTX *ctx;4748if (!ossl_prov_is_running())49return NULL;5051ctx = OPENSSL_zalloc(sizeof(PROV_ECX_CTX));52if (ctx == NULL)53return NULL;5455ctx->keylen = keylen;5657return ctx;58}5960static void *x25519_newctx(void *provctx)61{62return ecx_newctx(provctx, X25519_KEYLEN);63}6465static void *x448_newctx(void *provctx)66{67return ecx_newctx(provctx, X448_KEYLEN);68}6970static int ecx_init(void *vecxctx, void *vkey, const char *algname)71{72PROV_ECX_CTX *ecxctx = (PROV_ECX_CTX *)vecxctx;73ECX_KEY *key = vkey;7475if (!ossl_prov_is_running())76return 0;7778if (ecxctx == NULL79|| key == NULL80|| key->keylen != ecxctx->keylen81|| !ossl_ecx_key_up_ref(key)) {82ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);83return 0;84}8586ossl_ecx_key_free(ecxctx->key);87ecxctx->key = key;8889#ifdef FIPS_MODULE90if (!ossl_FIPS_IND_callback(key->libctx, algname, "Init"))91return 0;92#endif93return 1;94}9596static int x25519_init(void *vecxctx, void *vkey,97ossl_unused const OSSL_PARAM params[])98{99return ecx_init(vecxctx, vkey, "X25519");100}101102static int x448_init(void *vecxctx, void *vkey,103ossl_unused const OSSL_PARAM params[])104{105return ecx_init(vecxctx, vkey, "X448");106}107108static int ecx_set_peer(void *vecxctx, void *vkey)109{110PROV_ECX_CTX *ecxctx = (PROV_ECX_CTX *)vecxctx;111ECX_KEY *key = vkey;112113if (!ossl_prov_is_running())114return 0;115116if (ecxctx == NULL117|| key == NULL118|| key->keylen != ecxctx->keylen119|| !ossl_ecx_key_up_ref(key)) {120ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);121return 0;122}123ossl_ecx_key_free(ecxctx->peerkey);124ecxctx->peerkey = key;125126return 1;127}128129static int ecx_derive(void *vecxctx, unsigned char *secret, size_t *secretlen,130size_t outlen)131{132PROV_ECX_CTX *ecxctx = (PROV_ECX_CTX *)vecxctx;133134if (!ossl_prov_is_running())135return 0;136return ossl_ecx_compute_key(ecxctx->peerkey, ecxctx->key, ecxctx->keylen,137secret, secretlen, outlen);138}139140static void ecx_freectx(void *vecxctx)141{142PROV_ECX_CTX *ecxctx = (PROV_ECX_CTX *)vecxctx;143144ossl_ecx_key_free(ecxctx->key);145ossl_ecx_key_free(ecxctx->peerkey);146147OPENSSL_free(ecxctx);148}149150static void *ecx_dupctx(void *vecxctx)151{152PROV_ECX_CTX *srcctx = (PROV_ECX_CTX *)vecxctx;153PROV_ECX_CTX *dstctx;154155if (!ossl_prov_is_running())156return NULL;157158dstctx = OPENSSL_zalloc(sizeof(*srcctx));159if (dstctx == NULL)160return NULL;161162*dstctx = *srcctx;163if (dstctx->key != NULL && !ossl_ecx_key_up_ref(dstctx->key)) {164ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);165OPENSSL_free(dstctx);166return NULL;167}168169if (dstctx->peerkey != NULL && !ossl_ecx_key_up_ref(dstctx->peerkey)) {170ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR);171ossl_ecx_key_free(dstctx->key);172OPENSSL_free(dstctx);173return NULL;174}175176return dstctx;177}178179static const OSSL_PARAM *ecx_gettable_ctx_params(ossl_unused void *vctx,180ossl_unused void *provctx)181{182static const OSSL_PARAM known_gettable_ctx_params[] = {183OSSL_FIPS_IND_GETTABLE_CTX_PARAM()184OSSL_PARAM_END185};186return known_gettable_ctx_params;187}188189static int ecx_get_ctx_params(ossl_unused void *vctx, OSSL_PARAM params[])190{191#ifdef FIPS_MODULE192int approved = 0;193OSSL_PARAM *p = OSSL_PARAM_locate(params,194OSSL_ALG_PARAM_FIPS_APPROVED_INDICATOR);195196if (p != NULL && !OSSL_PARAM_set_int(p, approved))197return 0;198#endif199return 1;200}201202const OSSL_DISPATCH ossl_x25519_keyexch_functions[] = {203{ OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))x25519_newctx },204{ OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))x25519_init },205{ OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))ecx_derive },206{ OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))ecx_set_peer },207{ OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))ecx_freectx },208{ OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))ecx_dupctx },209{ OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))ecx_get_ctx_params },210{ OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS,211(void (*)(void))ecx_gettable_ctx_params },212OSSL_DISPATCH_END213};214215const OSSL_DISPATCH ossl_x448_keyexch_functions[] = {216{ OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))x448_newctx },217{ OSSL_FUNC_KEYEXCH_INIT, (void (*)(void))x448_init },218{ OSSL_FUNC_KEYEXCH_DERIVE, (void (*)(void))ecx_derive },219{ OSSL_FUNC_KEYEXCH_SET_PEER, (void (*)(void))ecx_set_peer },220{ OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))ecx_freectx },221{ OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))ecx_dupctx },222{ OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))ecx_get_ctx_params },223{ OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS,224(void (*)(void))ecx_gettable_ctx_params },225OSSL_DISPATCH_END226};227228229