From 4f5d33988d1f57b4a9242b28d47453fd204d1c3d Mon Sep 17 00:00:00 2001 From: Ingo Franzki Date: Mon, 9 Jan 2023 11:41:21 +0100 Subject: [PATCH] libseckey: EC signature: Reject deterministic signatures With parameter OSSL_SIGNATURE_PARAM_NONCE_TYPE one can choose to generate a deterministic signature, i.e. using a deterministic nonce K. We do not support that so far, so reject to set the nonce type to anything other than 0 (random nonce K). See OpenSSL commit https://github.com/openssl/openssl/commit/f3090fc710e30a749acaf9e5dfbe20dd163cf15d Signed-off-by: Ingo Franzki Signed-off-by: Steffen Eiden --- libseckey/sk_provider.c | 57 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/libseckey/sk_provider.c b/libseckey/sk_provider.c index 3476a9ed..ba37b5ae 100644 --- a/libseckey/sk_provider.c +++ b/libseckey/sk_provider.c @@ -552,6 +552,33 @@ static const OSSL_PARAM *sk_prov_cached_params_build( return provctx->cached_parms[index]; } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +static bool sk_prov_check_uint_param(const OSSL_PARAM params[], + const char *param_name, + const struct sk_prov_key *key, + int key_type, + unsigned int expected_value) +{ + const OSSL_PARAM *p; + unsigned int value; + + if (key == NULL) + return true; + if (key->type != key_type) + return true; + + p = OSSL_PARAM_locate_const(params, param_name); + if (p == NULL) + return true; + + if (OSSL_PARAM_get_uint(p, &value) != 1) + return true; + + return value == expected_value; +} +#pragma GCC diagnostic pop + static struct sk_prov_op_ctx *sk_prov_op_newctx(struct sk_prov_ctx *provctx, const char *propq, int type) @@ -1361,6 +1388,16 @@ static int sk_prov_sign_op_set_ctx_params(void *vctx, const OSSL_PARAM params[]) for (p = params; p != NULL && p->key != NULL; p++) sk_debug_op_ctx(ctx, "param: %s", p->key); +#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE + /* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */ + if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE, + ctx->key, EVP_PKEY_EC, 0)) { + put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM, + "Deterministic signature is not supported"); + return 0; + } +#endif + default_set_params_fn = (OSSL_FUNC_signature_set_ctx_params_fn *) sk_prov_get_default_sign_func(ctx->provctx, ctx->type, OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS); @@ -1729,6 +1766,16 @@ static int sk_prov_sign_op_sign_init(void *vctx, void *vkey, for (p = params; p != NULL && p->key != NULL; p++) sk_debug_op_ctx(ctx, "param: %s", p->key); +#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE + /* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */ + if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE, + key, EVP_PKEY_EC, 0)) { + put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM, + "Deterministic signature is not supported"); + return 0; + } +#endif + default_sign_init_fn = (OSSL_FUNC_signature_sign_init_fn *) sk_prov_get_default_sign_func(ctx->provctx, ctx->type, @@ -1955,6 +2002,16 @@ static int sk_prov_sign_op_digest_sign_init(struct sk_prov_op_ctx *ctx, for (p = params; p != NULL && p->key != NULL; p++) sk_debug_op_ctx(ctx, "param: %s", p->key); +#ifdef OSSL_SIGNATURE_PARAM_NONCE_TYPE + /* OSSL_SIGNATURE_PARAM_NONCE_TYPE is used for EC sign ops only */ + if (!sk_prov_check_uint_param(params, OSSL_SIGNATURE_PARAM_NONCE_TYPE, + key, EVP_PKEY_EC, 0)) { + put_error_op_ctx(ctx, SK_PROV_ERR_INVALID_PARAM, + "Deterministic signature is not supported"); + return 0; + } +#endif + default_digest_sign_init_fn = (OSSL_FUNC_signature_digest_sign_init_fn *) sk_prov_get_default_sign_func(ctx->provctx,