/*
* Copyright 2020-2021 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 <assert.h>
#include <string.h>
/* For strcasecmp on Windows */
#include "e_os.h"
#include <openssl/core_dispatch.h>
#include <openssl/core_names.h>
#include <openssl/params.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
#include "internal/param_build_set.h"
#include "openssl/param_build.h"
#include "crypto/ecx.h"
#include "prov/implementations.h"
#include "prov/providercommon.h"
#include "prov/provider_ctx.h"
#ifdef S390X_EC_ASM
# include "s390x_arch.h"
# include <openssl/sha.h> /* For SHA512_DIGEST_LENGTH */
#endif
static OSSL_FUNC_keymgmt_new_fn x25519_new_key;
static OSSL_FUNC_keymgmt_new_fn x448_new_key;
static OSSL_FUNC_keymgmt_new_fn ed25519_new_key;
static OSSL_FUNC_keymgmt_new_fn ed448_new_key;
static OSSL_FUNC_keymgmt_gen_init_fn x25519_gen_init;
static OSSL_FUNC_keymgmt_gen_init_fn x448_gen_init;
static OSSL_FUNC_keymgmt_gen_init_fn ed25519_gen_init;
static OSSL_FUNC_keymgmt_gen_init_fn ed448_gen_init;
static OSSL_FUNC_keymgmt_gen_fn x25519_gen;
static OSSL_FUNC_keymgmt_gen_fn x448_gen;
static OSSL_FUNC_keymgmt_gen_fn ed25519_gen;
static OSSL_FUNC_keymgmt_gen_fn ed448_gen;
static OSSL_FUNC_keymgmt_gen_cleanup_fn ecx_gen_cleanup;
static OSSL_FUNC_keymgmt_load_fn ecx_load;
static OSSL_FUNC_keymgmt_get_params_fn x25519_get_params;
static OSSL_FUNC_keymgmt_get_params_fn x448_get_params;
static OSSL_FUNC_keymgmt_get_params_fn ed25519_get_params;
static OSSL_FUNC_keymgmt_get_params_fn ed448_get_params;
static OSSL_FUNC_keymgmt_gettable_params_fn x25519_gettable_params;
static OSSL_FUNC_keymgmt_gettable_params_fn x448_gettable_params;
static OSSL_FUNC_keymgmt_gettable_params_fn ed25519_gettable_params;
static OSSL_FUNC_keymgmt_gettable_params_fn ed448_gettable_params;
static OSSL_FUNC_keymgmt_set_params_fn x25519_set_params;
static OSSL_FUNC_keymgmt_set_params_fn x448_set_params;
static OSSL_FUNC_keymgmt_set_params_fn ed25519_set_params;
static OSSL_FUNC_keymgmt_set_params_fn ed448_set_params;
static OSSL_FUNC_keymgmt_settable_params_fn x25519_settable_params;
static OSSL_FUNC_keymgmt_settable_params_fn x448_settable_params;
static OSSL_FUNC_keymgmt_settable_params_fn ed25519_settable_params;
static OSSL_FUNC_keymgmt_settable_params_fn ed448_settable_params;
static OSSL_FUNC_keymgmt_has_fn ecx_has;
static OSSL_FUNC_keymgmt_match_fn ecx_match;
static OSSL_FUNC_keymgmt_validate_fn x25519_validate;
static OSSL_FUNC_keymgmt_validate_fn x448_validate;
static OSSL_FUNC_keymgmt_validate_fn ed25519_validate;
static OSSL_FUNC_keymgmt_validate_fn ed448_validate;
static OSSL_FUNC_keymgmt_import_fn ecx_import;
static OSSL_FUNC_keymgmt_import_types_fn ecx_imexport_types;
static OSSL_FUNC_keymgmt_export_fn ecx_export;
static OSSL_FUNC_keymgmt_export_types_fn ecx_imexport_types;
#define ECX_POSSIBLE_SELECTIONS (OSSL_KEYMGMT_SELECT_KEYPAIR)
struct ecx_gen_ctx {
OSSL_LIB_CTX *libctx;
char *propq;
ECX_KEY_TYPE type;
int selection;
};
#ifdef S390X_EC_ASM
static void *s390x_ecx_keygen25519(struct ecx_gen_ctx *gctx);
static void *s390x_ecx_keygen448(struct ecx_gen_ctx *gctx);
static void *s390x_ecd_keygen25519(struct ecx_gen_ctx *gctx);
static void *s390x_ecd_keygen448(struct ecx_gen_ctx *gctx);
#endif
static void *x25519_new_key(void *provctx)
{
if (!ossl_prov_is_running())
return 0;
return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X25519, 0,
NULL);
}
static void *x448_new_key(void *provctx)
{
if (!ossl_prov_is_running())
return 0;
return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_X448, 0,
NULL);
}
static void *ed25519_new_key(void *provctx)
{
if (!ossl_prov_is_running())
return 0;
return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED25519, 0,
NULL);
}
static void *ed448_new_key(void *provctx)
{
if (!ossl_prov_is_running())
return 0;
return ossl_ecx_key_new(PROV_LIBCTX_OF(provctx), ECX_KEY_TYPE_ED448, 0,
NULL);
}
static int ecx_has(const void *keydata, int selection)
{
const ECX_KEY *key = keydata;
int ok = 0;
if (ossl_prov_is_running() && key != NULL) {
/*
* ECX keys always have all the parameters they need (i.e. none).
* Therefore we always return with 1, if asked about parameters.
*/
ok = 1;
if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0)
ok