diff options
author | Matt Caswell <matt@openssl.org> | 2020-03-05 15:42:13 +0000 |
---|---|---|
committer | Matt Caswell <matt@openssl.org> | 2020-03-09 07:59:15 +0000 |
commit | 3965480c824c9823db7803cc1a403be863cecc00 (patch) | |
tree | b10a87f0b52e3bc7fba8497685f082915589bae7 /providers | |
parent | eea1e780a1c2c6952af7b9e00129f5aaefb7207e (diff) | |
download | openssl-3965480c824c9823db7803cc1a403be863cecc00.zip openssl-3965480c824c9823db7803cc1a403be863cecc00.tar.gz openssl-3965480c824c9823db7803cc1a403be863cecc00.tar.bz2 |
Implement provider support for Ed25519 annd Ed448
At the moment we only provider support for these algorithms in the default
provider. These algorithms only support "one shot" EVP_DigestSign() and
EVP_DigestVerify() as per the existing libcrypto versions.
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/11261)
Diffstat (limited to 'providers')
-rw-r--r-- | providers/common/include/prov/providercommonerr.h | 1 | ||||
-rw-r--r-- | providers/common/provider_err.c | 1 | ||||
-rw-r--r-- | providers/defltprov.c | 4 | ||||
-rw-r--r-- | providers/implementations/include/prov/implementations.h | 2 | ||||
-rw-r--r-- | providers/implementations/signature/build.info | 5 | ||||
-rw-r--r-- | providers/implementations/signature/eddsa.c | 211 |
6 files changed, 224 insertions, 0 deletions
diff --git a/providers/common/include/prov/providercommonerr.h b/providers/common/include/prov/providercommonerr.h index 19ecab1..f834a71 100644 --- a/providers/common/include/prov/providercommonerr.h +++ b/providers/common/include/prov/providercommonerr.h @@ -64,6 +64,7 @@ int ERR_load_PROV_strings(void); # define PROV_R_FAILED_TO_GENERATE_KEY 121 # define PROV_R_FAILED_TO_GET_PARAMETER 103 # define PROV_R_FAILED_TO_SET_PARAMETER 104 +# define PROV_R_FAILED_TO_SIGN 175 # define PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 165 # define PROV_R_INAVLID_UKM_LENGTH 146 # define PROV_R_INVALID_AAD 108 diff --git a/providers/common/provider_err.c b/providers/common/provider_err.c index f73f823..1a65e2c 100644 --- a/providers/common/provider_err.c +++ b/providers/common/provider_err.c @@ -39,6 +39,7 @@ static const ERR_STRING_DATA PROV_str_reasons[] = { "failed to get parameter"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SET_PARAMETER), "failed to set parameter"}, + {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_FAILED_TO_SIGN), "failed to sign"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), "illegal or unsupported padding mode"}, {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_INAVLID_UKM_LENGTH), diff --git a/providers/defltprov.c b/providers/defltprov.c index a410eea..7bb23e3 100644 --- a/providers/defltprov.c +++ b/providers/defltprov.c @@ -385,6 +385,10 @@ static const OSSL_ALGORITHM deflt_signature[] = { { "DSA:dsaEncryption", "provider=default", dsa_signature_functions }, #endif { "RSA:rsaEncryption", "provider=default", rsa_signature_functions }, +#ifndef OPENSSL_NO_EC + { "ED25519:Ed25519", "provider=default", ed25519_signature_functions }, + { "ED448:Ed448", "provider=default", ed448_signature_functions }, +#endif { NULL, NULL, NULL } }; diff --git a/providers/implementations/include/prov/implementations.h b/providers/implementations/include/prov/implementations.h index e3afa98..94265ad 100644 --- a/providers/implementations/include/prov/implementations.h +++ b/providers/implementations/include/prov/implementations.h @@ -272,6 +272,8 @@ extern const OSSL_DISPATCH ecdh_keyexch_functions[]; /* Signature */ extern const OSSL_DISPATCH dsa_signature_functions[]; extern const OSSL_DISPATCH rsa_signature_functions[]; +extern const OSSL_DISPATCH ed25519_signature_functions[]; +extern const OSSL_DISPATCH ed448_signature_functions[]; /* Asym Cipher */ extern const OSSL_DISPATCH rsa_asym_cipher_functions[]; diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info index 22b55dc..c5d0645 100644 --- a/providers/implementations/signature/build.info +++ b/providers/implementations/signature/build.info @@ -3,11 +3,16 @@ $DSA_GOAL=../../libimplementations.a $RSA_GOAL=../../libimplementations.a +$EC_GOAL=../../libimplementations.a IF[{- !$disabled{dsa} -}] SOURCE[$DSA_GOAL]=dsa.c ENDIF +IF[{- !$disabled{ec} -}] + SOURCE[$EC_GOAL]=eddsa.c +ENDIF + SOURCE[$RSA_GOAL]=rsa.c diff --git a/providers/implementations/signature/eddsa.c b/providers/implementations/signature/eddsa.c new file mode 100644 index 0000000..d2444f9 --- /dev/null +++ b/providers/implementations/signature/eddsa.c @@ -0,0 +1,211 @@ +/* + * Copyright 2020 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/crypto.h> +#include <openssl/core_numbers.h> +#include <openssl/core_names.h> +#include <openssl/err.h> +#include <openssl/params.h> +#include <openssl/evp.h> +#include <openssl/err.h> +#include "internal/nelem.h" +#include "internal/sizes.h" +#include "prov/providercommonerr.h" +#include "prov/implementations.h" +#include "prov/providercommonerr.h" +#include "prov/provider_ctx.h" +#include "crypto/ecx.h" + +static OSSL_OP_signature_newctx_fn eddsa_newctx; +static OSSL_OP_signature_digest_sign_init_fn eddsa_digest_signverify_init; +static OSSL_OP_signature_digest_sign_fn ed25519_digest_sign; +static OSSL_OP_signature_digest_sign_fn ed448_digest_sign; +static OSSL_OP_signature_digest_verify_fn ed25519_digest_verify; +static OSSL_OP_signature_digest_verify_fn ed448_digest_verify; +static OSSL_OP_signature_freectx_fn eddsa_freectx; +static OSSL_OP_signature_dupctx_fn eddsa_dupctx; + +typedef struct { + OPENSSL_CTX *libctx; + ECX_KEY *key; +} PROV_EDDSA_CTX; + +static void *eddsa_newctx(void *provctx) +{ + PROV_EDDSA_CTX *peddsactx = OPENSSL_zalloc(sizeof(PROV_EDDSA_CTX)); + + if (peddsactx == NULL) { + PROVerr(0, ERR_R_MALLOC_FAILURE); + return NULL; + } + + peddsactx->libctx = PROV_LIBRARY_CONTEXT_OF(provctx); + + return peddsactx; +} + +static int eddsa_digest_signverify_init(void *vpeddsactx, const char *mdname, + const char *props, void *vedkey) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + ECX_KEY *edkey = (ECX_KEY *)vedkey; + + if (mdname != NULL) { + PROVerr(0, PROV_R_INVALID_DIGEST); + return 0; + } + + if (!ecx_key_up_ref(edkey)) { + PROVerr(0, ERR_R_INTERNAL_ERROR); + return 0; + } + + peddsactx->key = edkey; + + return 1; +} + +int ed25519_digest_sign(void *vpeddsactx, unsigned char *sigret, + size_t *siglen, size_t sigsize, + const unsigned char *tbs, size_t tbslen) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + const ECX_KEY *edkey = peddsactx->key; + + if (sigret == NULL) { + *siglen = ED25519_SIGSIZE; + return 1; + } + if (sigsize < ED25519_SIGSIZE) { + PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (ED25519_sign(sigret, tbs, tbslen, edkey->pubkey, edkey->privkey) == 0) { + PROVerr(0, PROV_R_FAILED_TO_SIGN); + return 0; + } + *siglen = ED25519_SIGSIZE; + return 1; +} + +int ed448_digest_sign(void *vpeddsactx, unsigned char *sigret, + size_t *siglen, size_t sigsize, + const unsigned char *tbs, size_t tbslen) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + const ECX_KEY *edkey = peddsactx->key; + + if (sigret == NULL) { + *siglen = ED448_SIGSIZE; + return 1; + } + if (sigsize < ED448_SIGSIZE) { + PROVerr(0, PROV_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (ED448_sign(peddsactx->libctx, sigret, tbs, tbslen, edkey->pubkey, + edkey->privkey, NULL, 0) == 0) { + PROVerr(0, PROV_R_FAILED_TO_SIGN); + return 0; + } + *siglen = ED448_SIGSIZE; + return 1; +} + +int ed25519_digest_verify(void *vpeddsactx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + const ECX_KEY *edkey = peddsactx->key; + + if (siglen != ED25519_SIGSIZE) + return 0; + + return ED25519_verify(tbs, tbslen, sig, edkey->pubkey); +} + +int ed448_digest_verify(void *vpeddsactx, const unsigned char *sig, + size_t siglen, const unsigned char *tbs, + size_t tbslen) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + const ECX_KEY *edkey = peddsactx->key; + + if (siglen != ED448_SIGSIZE) + return 0; + + return ED448_verify(peddsactx->libctx, tbs, tbslen, sig, edkey->pubkey, + NULL, 0); +} + +static void eddsa_freectx(void *vpeddsactx) +{ + PROV_EDDSA_CTX *peddsactx = (PROV_EDDSA_CTX *)vpeddsactx; + + ecx_key_free(peddsactx->key); + + OPENSSL_free(peddsactx); +} + +static void *eddsa_dupctx(void *vpeddsactx) +{ + PROV_EDDSA_CTX *srcctx = (PROV_EDDSA_CTX *)vpeddsactx; + PROV_EDDSA_CTX *dstctx; + + dstctx = OPENSSL_zalloc(sizeof(*srcctx)); + if (dstctx == NULL) + return NULL; + + *dstctx = *srcctx; + dstctx->key = NULL; + + if (srcctx->key != NULL && !ecx_key_up_ref(srcctx->key)) { + PROVerr(0, ERR_R_INTERNAL_ERROR); + goto err; + } + dstctx->key = srcctx->key; + + return dstctx; + err: + eddsa_freectx(dstctx); + return NULL; +} + +const OSSL_DISPATCH ed25519_signature_functions[] = { + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, + (void (*)(void))eddsa_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, + (void (*)(void))ed25519_digest_sign }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, + (void (*)(void))eddsa_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, + (void (*)(void))ed25519_digest_verify }, + { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, + { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, + { 0, NULL } +}; + +const OSSL_DISPATCH ed448_signature_functions[] = { + { OSSL_FUNC_SIGNATURE_NEWCTX, (void (*)(void))eddsa_newctx }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, + (void (*)(void))eddsa_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_SIGN, + (void (*)(void))ed448_digest_sign }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, + (void (*)(void))eddsa_digest_signverify_init }, + { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY, + (void (*)(void))ed448_digest_verify }, + { OSSL_FUNC_SIGNATURE_FREECTX, (void (*)(void))eddsa_freectx }, + { OSSL_FUNC_SIGNATURE_DUPCTX, (void (*)(void))eddsa_dupctx }, + { 0, NULL } +}; |