From 6c2e8d35e6420143135582b6d9c17cdef89fcfde Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Thu, 10 Nov 2022 15:17:30 +0000
Subject: Provide digestsign/digestverify hooks for EVP_PKEY_METHOD.

These are needed for EVP implementations of Ed25519 and X25519.

ok beck@ tb@
---
 src/lib/libcrypto/evp/evp.h      |  3 ++-
 src/lib/libcrypto/evp/evp_err.c  |  3 ++-
 src/lib/libcrypto/evp/evp_locl.h |  7 ++++++-
 src/lib/libcrypto/evp/m_sigver.c | 23 ++++++++++++++++++++++-
 4 files changed, 32 insertions(+), 4 deletions(-)

(limited to 'src/lib')

diff --git a/src/lib/libcrypto/evp/evp.h b/src/lib/libcrypto/evp/evp.h
index 31c26b4444..f4702ab433 100644
--- a/src/lib/libcrypto/evp/evp.h
+++ b/src/lib/libcrypto/evp/evp.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp.h,v 1.109 2022/11/10 14:46:44 jsing Exp $ */
+/* $OpenBSD: evp.h,v 1.110 2022/11/10 15:17:30 jsing Exp $ */
 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
  * All rights reserved.
  *
@@ -1447,6 +1447,7 @@ void ERR_load_EVP_strings(void);
 #define EVP_R_NO_OPERATION_SET				 149
 #define EVP_R_NO_SIGN_FUNCTION_CONFIGURED		 104
 #define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED		 105
+#define EVP_R_ONLY_ONESHOT_SUPPORTED			 177
 #define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE	 150
 #define EVP_R_OPERATON_NOT_INITIALIZED			 151
 #define EVP_R_OUTPUT_ALIASES_INPUT			 172
diff --git a/src/lib/libcrypto/evp/evp_err.c b/src/lib/libcrypto/evp/evp_err.c
index 109d2d4b2e..9cf89f47fb 100644
--- a/src/lib/libcrypto/evp/evp_err.c
+++ b/src/lib/libcrypto/evp/evp_err.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_err.c,v 1.29 2022/11/10 14:46:44 jsing Exp $ */
+/* $OpenBSD: evp_err.c,v 1.30 2022/11/10 15:17:30 jsing Exp $ */
 /* ====================================================================
  * Copyright (c) 1999-2011 The OpenSSL Project.  All rights reserved.
  *
@@ -123,6 +123,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
 	{ERR_REASON(EVP_R_NO_OPERATION_SET)      , "no operation set"},
 	{ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED), "no sign function configured"},
 	{ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED), "no verify function configured"},
+	{ERR_REASON(EVP_R_ONLY_ONESHOT_SUPPORTED), "only oneshot supported"},
 	{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), "operation not supported for this keytype"},
 	{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
 	{ERR_REASON(EVP_R_OUTPUT_ALIASES_INPUT)  , "output aliases input"},
diff --git a/src/lib/libcrypto/evp/evp_locl.h b/src/lib/libcrypto/evp/evp_locl.h
index 1e79af4c6d..dd7d2522e6 100644
--- a/src/lib/libcrypto/evp/evp_locl.h
+++ b/src/lib/libcrypto/evp/evp_locl.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: evp_locl.h,v 1.28 2022/09/13 04:59:18 jsing Exp $ */
+/* $OpenBSD: evp_locl.h,v 1.29 2022/11/10 15:17:30 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2000.
  */
@@ -260,6 +260,11 @@ struct evp_pkey_method_st {
 	int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
 	int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
 
+	int (*digestsign)(EVP_MD_CTX *ctx, unsigned char *sig, size_t *siglen,
+	    const unsigned char *tbs, size_t tbslen);
+	int (*digestverify) (EVP_MD_CTX *ctx, const unsigned char *sig,
+	    size_t siglen, const unsigned char *tbs, size_t tbslen);
+
 	int (*check)(EVP_PKEY *pkey);
 	int (*public_check)(EVP_PKEY *pkey);
 	int (*param_check)(EVP_PKEY *pkey);
diff --git a/src/lib/libcrypto/evp/m_sigver.c b/src/lib/libcrypto/evp/m_sigver.c
index bd9374651a..5be924bed5 100644
--- a/src/lib/libcrypto/evp/m_sigver.c
+++ b/src/lib/libcrypto/evp/m_sigver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: m_sigver.c,v 1.9 2021/05/09 14:25:40 tb Exp $ */
+/* $OpenBSD: m_sigver.c,v 1.10 2022/11/10 15:17:30 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2006.
  */
@@ -65,6 +65,13 @@
 
 #include "evp_locl.h"
 
+static int
+update_oneshot_only(EVP_MD_CTX *ctx, const void *data, size_t datalen)
+{
+	EVPerror(EVP_R_ONLY_ONESHOT_SUPPORTED);
+	return 0;
+}
+
 static int
 do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
     ENGINE *e, EVP_PKEY *pkey, int ver)
@@ -93,6 +100,9 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
 			    ctx) <=0)
 				return 0;
 			ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
+		} else if (ctx->pctx->pmeth->digestverify != NULL) {
+			ctx->pctx->operation = EVP_PKEY_OP_VERIFY;
+			ctx->update = update_oneshot_only;
 		} else if (EVP_PKEY_verify_init(ctx->pctx) <= 0)
 			return 0;
 	} else {
@@ -100,6 +110,9 @@ do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, const EVP_MD *type,
 			if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0)
 				return 0;
 			ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
+		} else if (ctx->pctx->pmeth->digestsign != NULL) {
+			ctx->pctx->operation = EVP_PKEY_OP_SIGN;
+			ctx->update = update_oneshot_only;
 		} else if (EVP_PKEY_sign_init(ctx->pctx) <= 0)
 			return 0;
 	}
@@ -190,6 +203,10 @@ int
 EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
     const unsigned char *tbs, size_t tbslen)
 {
+	if (ctx->pctx->pmeth->digestsign != NULL)
+		return ctx->pctx->pmeth->digestsign(ctx, sigret, siglen,
+		    tbs, tbslen);
+
 	if (sigret != NULL) {
 		if (EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
 			return 0;
@@ -229,6 +246,10 @@ int
 EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret, size_t siglen,
     const unsigned char *tbs, size_t tbslen)
 {
+	if (ctx->pctx->pmeth->digestverify != NULL)
+		return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen,
+		    tbs, tbslen);
+
 	if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
 		return -1;
 
-- 
cgit v1.2.3-55-g6feb