1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2020-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci#include <openssl/crypto.h> 11e1051a39Sopenharmony_ci#include <openssl/core_dispatch.h> 12e1051a39Sopenharmony_ci#include <openssl/core_names.h> 13e1051a39Sopenharmony_ci#include <openssl/err.h> 14e1051a39Sopenharmony_ci#include <openssl/params.h> 15e1051a39Sopenharmony_ci#include <openssl/evp.h> 16e1051a39Sopenharmony_ci#include <openssl/err.h> 17e1051a39Sopenharmony_ci#include <openssl/proverr.h> 18e1051a39Sopenharmony_ci#include "internal/nelem.h" 19e1051a39Sopenharmony_ci#include "internal/sizes.h" 20e1051a39Sopenharmony_ci#include "prov/providercommon.h" 21e1051a39Sopenharmony_ci#include "prov/implementations.h" 22e1051a39Sopenharmony_ci#include "prov/provider_ctx.h" 23e1051a39Sopenharmony_ci#include "prov/der_ecx.h" 24e1051a39Sopenharmony_ci#include "crypto/ecx.h" 25e1051a39Sopenharmony_ci 26e1051a39Sopenharmony_ci#ifdef S390X_EC_ASM 27e1051a39Sopenharmony_ci# include "s390x_arch.h" 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_ci# define S390X_CAN_SIGN(edtype) \ 30e1051a39Sopenharmony_ci((OPENSSL_s390xcap_P.pcc[1] & S390X_CAPBIT(S390X_SCALAR_MULTIPLY_##edtype)) \ 31e1051a39Sopenharmony_ci&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_SIGN_##edtype)) \ 32e1051a39Sopenharmony_ci&& (OPENSSL_s390xcap_P.kdsa[0] & S390X_CAPBIT(S390X_EDDSA_VERIFY_##edtype))) 33e1051a39Sopenharmony_ci 34e1051a39Sopenharmony_cistatic int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig, 35e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen); 36e1051a39Sopenharmony_cistatic int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig, 37e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen); 38e1051a39Sopenharmony_cistatic int s390x_ed25519_digestverify(const ECX_KEY *edkey, 39e1051a39Sopenharmony_ci const unsigned char *sig, 40e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen); 41e1051a39Sopenharmony_cistatic int s390x_ed448_digestverify(const ECX_KEY *edkey, 42e1051a39Sopenharmony_ci const unsigned char *sig, 43e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen); 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ci#endif /* S390X_EC_ASM */ 46e1051a39Sopenharmony_ci 47e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_newctx_fn eddsa_newctx; 48e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_init_fn eddsa_digest_signverify_init; 49e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_fn ed25519_digest_sign; 50e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_sign_fn ed448_digest_sign; 51e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_fn ed25519_digest_verify; 52e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_digest_verify_fn ed448_digest_verify; 53e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_freectx_fn eddsa_freectx; 54e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_dupctx_fn eddsa_dupctx; 55e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_get_ctx_params_fn eddsa_get_ctx_params; 56e1051a39Sopenharmony_cistatic OSSL_FUNC_signature_gettable_ctx_params_fn eddsa_gettable_ctx_params; 57e1051a39Sopenharmony_ci 58e1051a39Sopenharmony_citypedef struct { 59e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx; 60e1051a39Sopenharmony_ci ECX_KEY *key; 61e1051a39Sopenharmony_ci 62e1051a39Sopenharmony_ci /* The Algorithm Identifier of the signature algorithm */ 63e1051a39Sopenharmony_ci unsigned char aid_buf[OSSL_MAX_ALGORITHM_ID_SIZE]; 64e1051a39Sopenharmony_ci unsigned char *aid; 65e1051a39Sopenharmony_ci size_t aid_len; 66e1051a39Sopenharmony_ci} PROV_EDDSA_CTX; 67e1051a39Sopenharmony_ci 68e1051a39Sopenharmony_cistatic void *eddsa_newctx(void *provctx, const char *propq_unused) 69e1051a39Sopenharmony_ci{ 70e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx; 71e1051a39Sopenharmony_ci 72e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 73e1051a39Sopenharmony_ci return NULL; 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX)); 76e1051a39Sopenharmony_ci if (peddsactx == NULL) { 77e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE); 78e1051a39Sopenharmony_ci return NULL; 79e1051a39Sopenharmony_ci } 80e1051a39Sopenharmony_ci 81e1051a39Sopenharmony_ci peddsactx->libctx = PROV_LIBCTX_OF(provctx); 82e1051a39Sopenharmony_ci 83e1051a39Sopenharmony_ci return peddsactx; 84e1051a39Sopenharmony_ci} 85e1051a39Sopenharmony_ci 86e1051a39Sopenharmony_cistatic int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, 87e1051a39Sopenharmony_ci void *vedkey, 88e1051a39Sopenharmony_ci ossl_unused const OSSL_PARAM params[]) 89e1051a39Sopenharmony_ci{ 90e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 91e1051a39Sopenharmony_ci ECX_KEY *edkey = (ECX_KEY *)vedkey; 92e1051a39Sopenharmony_ci WPACKET pkt; 93e1051a39Sopenharmony_ci int ret; 94e1051a39Sopenharmony_ci 95e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 96e1051a39Sopenharmony_ci return 0; 97e1051a39Sopenharmony_ci 98e1051a39Sopenharmony_ci if (mdname != NULL && mdname[0] != '\0') { 99e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_DIGEST); 100e1051a39Sopenharmony_ci return 0; 101e1051a39Sopenharmony_ci } 102e1051a39Sopenharmony_ci 103e1051a39Sopenharmony_ci if (edkey == NULL) { 104e1051a39Sopenharmony_ci if (peddsactx->key != NULL) 105e1051a39Sopenharmony_ci /* there is nothing to do on reinit */ 106e1051a39Sopenharmony_ci return 1; 107e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NO_KEY_SET); 108e1051a39Sopenharmony_ci return 0; 109e1051a39Sopenharmony_ci } 110e1051a39Sopenharmony_ci 111e1051a39Sopenharmony_ci if (!ossl_ecx_key_up_ref(edkey)) { 112e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 113e1051a39Sopenharmony_ci return 0; 114e1051a39Sopenharmony_ci } 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci /* 117e1051a39Sopenharmony_ci * We do not care about DER writing errors. 118e1051a39Sopenharmony_ci * All it really means is that for some reason, there's no 119e1051a39Sopenharmony_ci * AlgorithmIdentifier to be had, but the operation itself is 120e1051a39Sopenharmony_ci * still valid, just as long as it's not used to construct 121e1051a39Sopenharmony_ci * anything that needs an AlgorithmIdentifier. 122e1051a39Sopenharmony_ci */ 123e1051a39Sopenharmony_ci peddsactx->aid_len = 0; 124e1051a39Sopenharmony_ci ret = WPACKET_init_der(&pkt, peddsactx->aid_buf, sizeof(peddsactx->aid_buf)); 125e1051a39Sopenharmony_ci switch (edkey->type) { 126e1051a39Sopenharmony_ci case ECX_KEY_TYPE_ED25519: 127e1051a39Sopenharmony_ci ret = ret && ossl_DER_w_algorithmIdentifier_ED25519(&pkt, -1, edkey); 128e1051a39Sopenharmony_ci break; 129e1051a39Sopenharmony_ci case ECX_KEY_TYPE_ED448: 130e1051a39Sopenharmony_ci ret = ret && ossl_DER_w_algorithmIdentifier_ED448(&pkt, -1, edkey); 131e1051a39Sopenharmony_ci break; 132e1051a39Sopenharmony_ci default: 133e1051a39Sopenharmony_ci /* Should never happen */ 134e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 135e1051a39Sopenharmony_ci ossl_ecx_key_free(edkey); 136e1051a39Sopenharmony_ci return 0; 137e1051a39Sopenharmony_ci } 138e1051a39Sopenharmony_ci if (ret && WPACKET_finish(&pkt)) { 139e1051a39Sopenharmony_ci WPACKET_get_total_written(&pkt, &peddsactx->aid_len); 140e1051a39Sopenharmony_ci peddsactx->aid = WPACKET_get_curr(&pkt); 141e1051a39Sopenharmony_ci } 142e1051a39Sopenharmony_ci WPACKET_cleanup(&pkt); 143e1051a39Sopenharmony_ci 144e1051a39Sopenharmony_ci peddsactx->key = edkey; 145e1051a39Sopenharmony_ci 146e1051a39Sopenharmony_ci return 1; 147e1051a39Sopenharmony_ci} 148e1051a39Sopenharmony_ci 149e1051a39Sopenharmony_ciint ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret, 150e1051a39Sopenharmony_ci size_t *siglen, size_t sigsize, 151e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 152e1051a39Sopenharmony_ci{ 153e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 154e1051a39Sopenharmony_ci const ECX_KEY *edkey = peddsactx->key; 155e1051a39Sopenharmony_ci 156e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 157e1051a39Sopenharmony_ci return 0; 158e1051a39Sopenharmony_ci 159e1051a39Sopenharmony_ci if (sigret == NULL) { 160e1051a39Sopenharmony_ci *siglen = ED25519_SIGSIZE; 161e1051a39Sopenharmony_ci return 1; 162e1051a39Sopenharmony_ci } 163e1051a39Sopenharmony_ci if (sigsize < ED25519_SIGSIZE) { 164e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 165e1051a39Sopenharmony_ci return 0; 166e1051a39Sopenharmony_ci } 167e1051a39Sopenharmony_ci if (edkey->privkey == NULL) { 168e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 169e1051a39Sopenharmony_ci return 0; 170e1051a39Sopenharmony_ci } 171e1051a39Sopenharmony_ci#ifdef S390X_EC_ASM 172e1051a39Sopenharmony_ci if (S390X_CAN_SIGN(ED25519)) { 173e1051a39Sopenharmony_ci if (s390x_ed25519_digestsign(edkey, sigret, tbs, tbslen) == 0) { 174e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 175e1051a39Sopenharmony_ci return 0; 176e1051a39Sopenharmony_ci } 177e1051a39Sopenharmony_ci *siglen = ED25519_SIGSIZE; 178e1051a39Sopenharmony_ci return 1; 179e1051a39Sopenharmony_ci } 180e1051a39Sopenharmony_ci#endif /* S390X_EC_ASM */ 181e1051a39Sopenharmony_ci if (ossl_ed25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey, 182e1051a39Sopenharmony_ci peddsactx->libctx, NULL) == 0) { 183e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 184e1051a39Sopenharmony_ci return 0; 185e1051a39Sopenharmony_ci } 186e1051a39Sopenharmony_ci *siglen = ED25519_SIGSIZE; 187e1051a39Sopenharmony_ci return 1; 188e1051a39Sopenharmony_ci} 189e1051a39Sopenharmony_ci 190e1051a39Sopenharmony_ciint ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, 191e1051a39Sopenharmony_ci size_t *siglen, size_t sigsize, 192e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 193e1051a39Sopenharmony_ci{ 194e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 195e1051a39Sopenharmony_ci const ECX_KEY *edkey = peddsactx->key; 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 198e1051a39Sopenharmony_ci return 0; 199e1051a39Sopenharmony_ci 200e1051a39Sopenharmony_ci if (sigret == NULL) { 201e1051a39Sopenharmony_ci *siglen = ED448_SIGSIZE; 202e1051a39Sopenharmony_ci return 1; 203e1051a39Sopenharmony_ci } 204e1051a39Sopenharmony_ci if (sigsize < ED448_SIGSIZE) { 205e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL); 206e1051a39Sopenharmony_ci return 0; 207e1051a39Sopenharmony_ci } 208e1051a39Sopenharmony_ci if (edkey->privkey == NULL) { 209e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_NOT_A_PRIVATE_KEY); 210e1051a39Sopenharmony_ci return 0; 211e1051a39Sopenharmony_ci } 212e1051a39Sopenharmony_ci#ifdef S390X_EC_ASM 213e1051a39Sopenharmony_ci if (S390X_CAN_SIGN(ED448)) { 214e1051a39Sopenharmony_ci if (s390x_ed448_digestsign(edkey, sigret, tbs, tbslen) == 0) { 215e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 216e1051a39Sopenharmony_ci return 0; 217e1051a39Sopenharmony_ci } 218e1051a39Sopenharmony_ci *siglen = ED448_SIGSIZE; 219e1051a39Sopenharmony_ci return 1; 220e1051a39Sopenharmony_ci } 221e1051a39Sopenharmony_ci#endif /* S390X_EC_ASM */ 222e1051a39Sopenharmony_ci if (ossl_ed448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey, 223e1051a39Sopenharmony_ci edkey->privkey, NULL, 0, edkey->propq) == 0) { 224e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, PROV_R_FAILED_TO_SIGN); 225e1051a39Sopenharmony_ci return 0; 226e1051a39Sopenharmony_ci } 227e1051a39Sopenharmony_ci *siglen = ED448_SIGSIZE; 228e1051a39Sopenharmony_ci return 1; 229e1051a39Sopenharmony_ci} 230e1051a39Sopenharmony_ci 231e1051a39Sopenharmony_ciint ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig, 232e1051a39Sopenharmony_ci size_t siglen, const unsigned char *tbs, 233e1051a39Sopenharmony_ci size_t tbslen) 234e1051a39Sopenharmony_ci{ 235e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 236e1051a39Sopenharmony_ci const ECX_KEY *edkey = peddsactx->key; 237e1051a39Sopenharmony_ci 238e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || siglen != ED25519_SIGSIZE) 239e1051a39Sopenharmony_ci return 0; 240e1051a39Sopenharmony_ci 241e1051a39Sopenharmony_ci#ifdef S390X_EC_ASM 242e1051a39Sopenharmony_ci if (S390X_CAN_SIGN(ED25519)) 243e1051a39Sopenharmony_ci return s390x_ed25519_digestverify(edkey, sig, tbs, tbslen); 244e1051a39Sopenharmony_ci#endif /* S390X_EC_ASM */ 245e1051a39Sopenharmony_ci 246e1051a39Sopenharmony_ci return ossl_ed25519_verify(tbs, tbslen, sig, edkey->pubkey, 247e1051a39Sopenharmony_ci peddsactx->libctx, edkey->propq); 248e1051a39Sopenharmony_ci} 249e1051a39Sopenharmony_ci 250e1051a39Sopenharmony_ciint ed448_digest_verify(void *vpeddsactx, const unsigned char *sig, 251e1051a39Sopenharmony_ci size_t siglen, const unsigned char *tbs, 252e1051a39Sopenharmony_ci size_t tbslen) 253e1051a39Sopenharmony_ci{ 254e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 255e1051a39Sopenharmony_ci const ECX_KEY *edkey = peddsactx->key; 256e1051a39Sopenharmony_ci 257e1051a39Sopenharmony_ci if (!ossl_prov_is_running() || siglen != ED448_SIGSIZE) 258e1051a39Sopenharmony_ci return 0; 259e1051a39Sopenharmony_ci 260e1051a39Sopenharmony_ci#ifdef S390X_EC_ASM 261e1051a39Sopenharmony_ci if (S390X_CAN_SIGN(ED448)) 262e1051a39Sopenharmony_ci return s390x_ed448_digestverify(edkey, sig, tbs, tbslen); 263e1051a39Sopenharmony_ci#endif /* S390X_EC_ASM */ 264e1051a39Sopenharmony_ci 265e1051a39Sopenharmony_ci return ossl_ed448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey, 266e1051a39Sopenharmony_ci NULL, 0, edkey->propq); 267e1051a39Sopenharmony_ci} 268e1051a39Sopenharmony_ci 269e1051a39Sopenharmony_cistatic void eddsa_freectx(void *vpeddsactx) 270e1051a39Sopenharmony_ci{ 271e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 272e1051a39Sopenharmony_ci 273e1051a39Sopenharmony_ci ossl_ecx_key_free(peddsactx->key); 274e1051a39Sopenharmony_ci 275e1051a39Sopenharmony_ci OPENSSL_free(peddsactx); 276e1051a39Sopenharmony_ci} 277e1051a39Sopenharmony_ci 278e1051a39Sopenharmony_cistatic void *eddsa_dupctx(void *vpeddsactx) 279e1051a39Sopenharmony_ci{ 280e1051a39Sopenharmony_ci PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx; 281e1051a39Sopenharmony_ci PROV_EDDSA_CTX *dstctx; 282e1051a39Sopenharmony_ci 283e1051a39Sopenharmony_ci if (!ossl_prov_is_running()) 284e1051a39Sopenharmony_ci return NULL; 285e1051a39Sopenharmony_ci 286e1051a39Sopenharmony_ci dstctx = OPENSSL_zalloc(sizeof(*srcctx)); 287e1051a39Sopenharmony_ci if (dstctx == NULL) 288e1051a39Sopenharmony_ci return NULL; 289e1051a39Sopenharmony_ci 290e1051a39Sopenharmony_ci *dstctx = *srcctx; 291e1051a39Sopenharmony_ci dstctx->key = NULL; 292e1051a39Sopenharmony_ci 293e1051a39Sopenharmony_ci if (srcctx->key != NULL && !ossl_ecx_key_up_ref(srcctx->key)) { 294e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_PROV, ERR_R_INTERNAL_ERROR); 295e1051a39Sopenharmony_ci goto err; 296e1051a39Sopenharmony_ci } 297e1051a39Sopenharmony_ci dstctx->key = srcctx->key; 298e1051a39Sopenharmony_ci 299e1051a39Sopenharmony_ci return dstctx; 300e1051a39Sopenharmony_ci err: 301e1051a39Sopenharmony_ci eddsa_freectx(dstctx); 302e1051a39Sopenharmony_ci return NULL; 303e1051a39Sopenharmony_ci} 304e1051a39Sopenharmony_ci 305e1051a39Sopenharmony_cistatic int eddsa_get_ctx_params(void *vpeddsactx, OSSL_PARAM *params) 306e1051a39Sopenharmony_ci{ 307e1051a39Sopenharmony_ci PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; 308e1051a39Sopenharmony_ci OSSL_PARAM *p; 309e1051a39Sopenharmony_ci 310e1051a39Sopenharmony_ci if (peddsactx == NULL) 311e1051a39Sopenharmony_ci return 0; 312e1051a39Sopenharmony_ci 313e1051a39Sopenharmony_ci p = OSSL_PARAM_locate(params, OSSL_SIGNATURE_PARAM_ALGORITHM_ID); 314e1051a39Sopenharmony_ci if (p != NULL && !OSSL_PARAM_set_octet_string(p, peddsactx->aid, 315e1051a39Sopenharmony_ci peddsactx->aid_len)) 316e1051a39Sopenharmony_ci return 0; 317e1051a39Sopenharmony_ci 318e1051a39Sopenharmony_ci return 1; 319e1051a39Sopenharmony_ci} 320e1051a39Sopenharmony_ci 321e1051a39Sopenharmony_cistatic const OSSL_PARAM known_gettable_ctx_params[] = { 322e1051a39Sopenharmony_ci OSSL_PARAM_octet_string(OSSL_SIGNATURE_PARAM_ALGORITHM_ID, NULL, 0), 323e1051a39Sopenharmony_ci OSSL_PARAM_END 324e1051a39Sopenharmony_ci}; 325e1051a39Sopenharmony_ci 326e1051a39Sopenharmony_cistatic const OSSL_PARAM *eddsa_gettable_ctx_params(ossl_unused void *vpeddsactx, 327e1051a39Sopenharmony_ci ossl_unused void *provctx) 328e1051a39Sopenharmony_ci{ 329e1051a39Sopenharmony_ci return known_gettable_ctx_params; 330e1051a39Sopenharmony_ci} 331e1051a39Sopenharmony_ci 332e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_ed25519_signature_functions[] = { 333e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, 334e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, 335e1051a39Sopenharmony_ci (void (*)(void))eddsa_digest_signverify_init }, 336e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, 337e1051a39Sopenharmony_ci (void (*)(void))ed25519_digest_sign }, 338e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, 339e1051a39Sopenharmony_ci (void (*)(void))eddsa_digest_signverify_init }, 340e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, 341e1051a39Sopenharmony_ci (void (*)(void))ed25519_digest_verify }, 342e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, 343e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, 344e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params }, 345e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, 346e1051a39Sopenharmony_ci (void (*)(void))eddsa_gettable_ctx_params }, 347e1051a39Sopenharmony_ci { 0, NULL } 348e1051a39Sopenharmony_ci}; 349e1051a39Sopenharmony_ci 350e1051a39Sopenharmony_ciconst OSSL_DISPATCH ossl_ed448_signature_functions[] = { 351e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, 352e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, 353e1051a39Sopenharmony_ci (void (*)(void))eddsa_digest_signverify_init }, 354e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, 355e1051a39Sopenharmony_ci (void (*)(void))ed448_digest_sign }, 356e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, 357e1051a39Sopenharmony_ci (void (*)(void))eddsa_digest_signverify_init }, 358e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, 359e1051a39Sopenharmony_ci (void (*)(void))ed448_digest_verify }, 360e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, 361e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, 362e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, (void (*)(void))eddsa_get_ctx_params }, 363e1051a39Sopenharmony_ci { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, 364e1051a39Sopenharmony_ci (void (*)(void))eddsa_gettable_ctx_params }, 365e1051a39Sopenharmony_ci { 0, NULL } 366e1051a39Sopenharmony_ci}; 367e1051a39Sopenharmony_ci 368e1051a39Sopenharmony_ci#ifdef S390X_EC_ASM 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_cistatic int s390x_ed25519_digestsign(const ECX_KEY *edkey, unsigned char *sig, 371e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 372e1051a39Sopenharmony_ci{ 373e1051a39Sopenharmony_ci int rc; 374e1051a39Sopenharmony_ci union { 375e1051a39Sopenharmony_ci struct { 376e1051a39Sopenharmony_ci unsigned char sig[64]; 377e1051a39Sopenharmony_ci unsigned char priv[32]; 378e1051a39Sopenharmony_ci } ed25519; 379e1051a39Sopenharmony_ci unsigned long long buff[512]; 380e1051a39Sopenharmony_ci } param; 381e1051a39Sopenharmony_ci 382e1051a39Sopenharmony_ci memset(¶m, 0, sizeof(param)); 383e1051a39Sopenharmony_ci memcpy(param.ed25519.priv, edkey->privkey, sizeof(param.ed25519.priv)); 384e1051a39Sopenharmony_ci 385e1051a39Sopenharmony_ci rc = s390x_kdsa(S390X_EDDSA_SIGN_ED25519, ¶m.ed25519, tbs, tbslen); 386e1051a39Sopenharmony_ci OPENSSL_cleanse(param.ed25519.priv, sizeof(param.ed25519.priv)); 387e1051a39Sopenharmony_ci if (rc != 0) 388e1051a39Sopenharmony_ci return 0; 389e1051a39Sopenharmony_ci 390e1051a39Sopenharmony_ci s390x_flip_endian32(sig, param.ed25519.sig); 391e1051a39Sopenharmony_ci s390x_flip_endian32(sig + 32, param.ed25519.sig + 32); 392e1051a39Sopenharmony_ci return 1; 393e1051a39Sopenharmony_ci} 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_cistatic int s390x_ed448_digestsign(const ECX_KEY *edkey, unsigned char *sig, 396e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 397e1051a39Sopenharmony_ci{ 398e1051a39Sopenharmony_ci int rc; 399e1051a39Sopenharmony_ci union { 400e1051a39Sopenharmony_ci struct { 401e1051a39Sopenharmony_ci unsigned char sig[128]; 402e1051a39Sopenharmony_ci unsigned char priv[64]; 403e1051a39Sopenharmony_ci } ed448; 404e1051a39Sopenharmony_ci unsigned long long buff[512]; 405e1051a39Sopenharmony_ci } param; 406e1051a39Sopenharmony_ci 407e1051a39Sopenharmony_ci memset(¶m, 0, sizeof(param)); 408e1051a39Sopenharmony_ci memcpy(param.ed448.priv + 64 - 57, edkey->privkey, 57); 409e1051a39Sopenharmony_ci 410e1051a39Sopenharmony_ci rc = s390x_kdsa(S390X_EDDSA_SIGN_ED448, ¶m.ed448, tbs, tbslen); 411e1051a39Sopenharmony_ci OPENSSL_cleanse(param.ed448.priv, sizeof(param.ed448.priv)); 412e1051a39Sopenharmony_ci if (rc != 0) 413e1051a39Sopenharmony_ci return 0; 414e1051a39Sopenharmony_ci 415e1051a39Sopenharmony_ci s390x_flip_endian64(param.ed448.sig, param.ed448.sig); 416e1051a39Sopenharmony_ci s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); 417e1051a39Sopenharmony_ci memcpy(sig, param.ed448.sig, 57); 418e1051a39Sopenharmony_ci memcpy(sig + 57, param.ed448.sig + 64, 57); 419e1051a39Sopenharmony_ci return 1; 420e1051a39Sopenharmony_ci} 421e1051a39Sopenharmony_ci 422e1051a39Sopenharmony_cistatic int s390x_ed25519_digestverify(const ECX_KEY *edkey, 423e1051a39Sopenharmony_ci const unsigned char *sig, 424e1051a39Sopenharmony_ci const unsigned char *tbs, size_t tbslen) 425e1051a39Sopenharmony_ci{ 426e1051a39Sopenharmony_ci union { 427e1051a39Sopenharmony_ci struct { 428e1051a39Sopenharmony_ci unsigned char sig[64]; 429e1051a39Sopenharmony_ci unsigned char pub[32]; 430e1051a39Sopenharmony_ci } ed25519; 431e1051a39Sopenharmony_ci unsigned long long buff[512]; 432e1051a39Sopenharmony_ci } param; 433e1051a39Sopenharmony_ci 434e1051a39Sopenharmony_ci memset(¶m, 0, sizeof(param)); 435e1051a39Sopenharmony_ci s390x_flip_endian32(param.ed25519.sig, sig); 436e1051a39Sopenharmony_ci s390x_flip_endian32(param.ed25519.sig + 32, sig + 32); 437e1051a39Sopenharmony_ci s390x_flip_endian32(param.ed25519.pub, edkey->pubkey); 438e1051a39Sopenharmony_ci 439e1051a39Sopenharmony_ci return s390x_kdsa(S390X_EDDSA_VERIFY_ED25519, 440e1051a39Sopenharmony_ci ¶m.ed25519, tbs, tbslen) == 0 ? 1 : 0; 441e1051a39Sopenharmony_ci} 442e1051a39Sopenharmony_ci 443e1051a39Sopenharmony_cistatic int s390x_ed448_digestverify(const ECX_KEY *edkey, 444e1051a39Sopenharmony_ci const unsigned char *sig, 445e1051a39Sopenharmony_ci const unsigned char *tbs, 446e1051a39Sopenharmony_ci size_t tbslen) 447e1051a39Sopenharmony_ci{ 448e1051a39Sopenharmony_ci union { 449e1051a39Sopenharmony_ci struct { 450e1051a39Sopenharmony_ci unsigned char sig[128]; 451e1051a39Sopenharmony_ci unsigned char pub[64]; 452e1051a39Sopenharmony_ci } ed448; 453e1051a39Sopenharmony_ci unsigned long long buff[512]; 454e1051a39Sopenharmony_ci } param; 455e1051a39Sopenharmony_ci 456e1051a39Sopenharmony_ci memset(¶m, 0, sizeof(param)); 457e1051a39Sopenharmony_ci memcpy(param.ed448.sig, sig, 57); 458e1051a39Sopenharmony_ci s390x_flip_endian64(param.ed448.sig, param.ed448.sig); 459e1051a39Sopenharmony_ci memcpy(param.ed448.sig + 64, sig + 57, 57); 460e1051a39Sopenharmony_ci s390x_flip_endian64(param.ed448.sig + 64, param.ed448.sig + 64); 461e1051a39Sopenharmony_ci memcpy(param.ed448.pub, edkey->pubkey, 57); 462e1051a39Sopenharmony_ci s390x_flip_endian64(param.ed448.pub, param.ed448.pub); 463e1051a39Sopenharmony_ci 464e1051a39Sopenharmony_ci return s390x_kdsa(S390X_EDDSA_VERIFY_ED448, 465e1051a39Sopenharmony_ci ¶m.ed448, tbs, tbslen) == 0 ? 1 : 0; 466e1051a39Sopenharmony_ci} 467e1051a39Sopenharmony_ci 468e1051a39Sopenharmony_ci#endif /* S390X_EC_ASM */ 469