summaryrefslogtreecommitdiffstats
path: root/demos
diff options
context:
space:
mode:
authorslontis <shane.lontis@oracle.com>2023-08-29 18:02:14 +1000
committerHugo Landau <hlandau@openssl.org>2023-09-01 10:09:56 +0100
commitb544c72f3755c0ea51408d3118821a1ac126c070 (patch)
tree036e4527f5fec3755dc127417cd945e3b517cdcd /demos
parent3961991593f788b3efb2a27563d358c7c58f854c (diff)
Add ED25519 Signature demo.
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com> Reviewed-by: Hugo Landau <hlandau@openssl.org> (Merged from https://github.com/openssl/openssl/pull/21883)
Diffstat (limited to 'demos')
-rw-r--r--demos/README.txt8
-rw-r--r--demos/signature/EVP_ED_Signature_demo.c208
-rw-r--r--demos/signature/Makefile11
3 files changed, 221 insertions, 6 deletions
diff --git a/demos/README.txt b/demos/README.txt
index cc72721fbe..32c15cd394 100644
--- a/demos/README.txt
+++ b/demos/README.txt
@@ -51,9 +51,11 @@ pkread.c Print out a description of a PKCS12 file.
pkwrite.c Add a password to an existing PKCS12 file.
signature:
-EVP_Signature_demo.c Compute and verify a signature from multiple buffers
-rsa_pss_direct.c Compute and verify an RSA-PSS signature from a hash
-rsa_pss_hash.c Compute and verify an RSA-PSS signature over a buffer
+EVP_EC_Signature_demo.c Compute and verify an EC signature.
+EVP_DSA_Signature_demo.c Compute and verify a DSA signature.
+EVP_ED_Signature_demo.c Compute and verify an ED25519 signature.
+rsa_pss_direct.c Compute and verify an RSA-PSS signature from a hash
+rsa_pss_hash.c Compute and verify an RSA-PSS signature over a buffer
sslecho:
main.c Simple SSL echo client/server.
diff --git a/demos/signature/EVP_ED_Signature_demo.c b/demos/signature/EVP_ED_Signature_demo.c
new file mode 100644
index 0000000000..e5cb6f4de1
--- /dev/null
+++ b/demos/signature/EVP_ED_Signature_demo.c
@@ -0,0 +1,208 @@
+/*-
+ * Copyright 2023 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
+ */
+
+/*
+ * This demonstration will calculate and verify an ED25519 signature of
+ * a message using EVP_DigestSign() and EVP_DigestVerify().
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <openssl/err.h>
+#include <openssl/evp.h>
+#include <openssl/core_names.h>
+
+/* A test message to be signed (TBS) */
+static const unsigned char hamlet[] =
+ "To be, or not to be, that is the question,\n"
+ "Whether tis nobler in the minde to suffer\n"
+ "The slings and arrowes of outragious fortune,\n"
+ "Or to take Armes again in a sea of troubles,\n";
+
+static int demo_sign(EVP_PKEY *priv,
+ const unsigned char *tbs, size_t tbs_len,
+ OSSL_LIB_CTX *libctx,
+ unsigned char **sig_out_value,
+ size_t *sig_out_len)
+{
+ int ret = 0;
+ size_t sig_len;
+ unsigned char *sig_value = NULL;
+ EVP_MD_CTX *sign_context = NULL;
+
+ /* Create a signature context */
+ sign_context = EVP_MD_CTX_new();
+ if (sign_context == NULL) {
+ fprintf(stderr, "EVP_MD_CTX_new failed.\n");
+ goto cleanup;
+ }
+
+ /*
+ * Initialize the sign context using an ED25519 private key
+ * Notice that the digest name must NOT be used.
+ * In this demo we don't specify any additional parameters via
+ * OSSL_PARAM, which means it will use default values.
+ * For more information, refer to doc/man7/EVP_SIGNATURE-ED25519.pod
+ * "ED25519 and ED448 Signature Parameters"
+ */
+ if (!EVP_DigestSignInit_ex(sign_context, NULL, NULL, libctx, NULL, priv, NULL)) {
+ fprintf(stderr, "EVP_DigestSignInit_ex failed.\n");
+ goto cleanup;
+ }
+
+ /* Calculate the required size for the signature by passing a NULL buffer. */
+ if (!EVP_DigestSign(sign_context, NULL, &sig_len, tbs, tbs_len)) {
+ fprintf(stderr, "EVP_DigestSign using NULL buffer failed.\n");
+ goto cleanup;
+ }
+ sig_value = OPENSSL_malloc(sig_len);
+ if (sig_value == NULL) {
+ fprintf(stderr, "OPENSSL_malloc failed.\n");
+ goto cleanup;
+ }
+ fprintf(stdout, "Generating signature:\n");
+ if (!EVP_DigestSign(sign_context, sig_value, &sig_len, tbs, tbs_len)) {
+ fprintf(stderr, "EVP_DigestSign failed.\n");
+ goto cleanup;
+ }
+ *sig_out_len = sig_len;
+ *sig_out_value = sig_value;
+ BIO_dump_indent_fp(stdout, sig_value, sig_len, 2);
+ fprintf(stdout, "\n");
+ ret = 1;
+
+cleanup:
+ if (!ret)
+ OPENSSL_free(sig_value);
+ EVP_MD_CTX_free(sign_context);
+ return ret;
+}
+
+static int demo_verify(EVP_PKEY *pub,
+ const unsigned char *tbs, size_t tbs_len,
+ const unsigned char *sig_value, size_t sig_len,
+ OSSL_LIB_CTX *libctx)
+{
+ int ret = 0;
+ EVP_MD_CTX *verify_context = NULL;
+
+ /*
+ * Make a verify signature context to hold temporary state
+ * during signature verification
+ */
+ verify_context = EVP_MD_CTX_new();
+ if (verify_context == NULL) {
+ fprintf(stderr, "EVP_MD_CTX_new failed.\n");
+ goto cleanup;
+ }
+ /* Initialize the verify context with a ED25519 public key */
+ if (!EVP_DigestVerifyInit_ex(verify_context, NULL, NULL,
+ libctx, NULL, pub, NULL)) {
+ fprintf(stderr, "EVP_DigestVerifyInit_ex failed.\n");
+ goto cleanup;
+ }
+ /*
+ * ED25519 only supports the one shot interface using EVP_DigestVerify()
+ * The streaming EVP_DigestVerifyUpdate() API is not supported.
+ */
+ if (!EVP_DigestVerify(verify_context, sig_value, sig_len,
+ tbs, tbs_len)) {
+ fprintf(stderr, "EVP_DigestVerify() failed.\n");
+ goto cleanup;
+ }
+ fprintf(stdout, "Signature verified.\n");
+ ret = 1;
+
+cleanup:
+ EVP_MD_CTX_free(verify_context);
+ return ret;
+}
+
+static int create_key(OSSL_LIB_CTX *libctx,
+ EVP_PKEY **privout, EVP_PKEY **pubout)
+{
+ int ret = 0;
+ EVP_PKEY *priv = NULL, *pub = NULL;
+ unsigned char pubdata[32];
+ size_t pubdata_len = 0;
+
+ /*
+ * In this demo we just create a keypair, and extract the
+ * public key. We could also use EVP_PKEY_new_raw_private_key_ex()
+ * to create a key from raw data.
+ */
+ priv = EVP_PKEY_Q_keygen(libctx, NULL, "ED25519");
+ if (priv == NULL) {
+ fprintf(stderr, "EVP_PKEY_Q_keygen() failed\n");
+ goto end;
+ }
+
+ if (!EVP_PKEY_get_octet_string_param(priv,
+ OSSL_PKEY_PARAM_PUB_KEY,
+ pubdata,
+ sizeof(pubdata),
+ &pubdata_len)) {
+ fprintf(stderr, "EVP_PKEY_get_octet_string_param() failed\n");
+ goto end;
+ }
+ pub = EVP_PKEY_new_raw_public_key_ex(libctx, "ED25519", NULL, pubdata, pubdata_len);
+ if (pub == NULL) {
+ fprintf(stderr, "EVP_PKEY_new_raw_public_key_ex() failed\n");
+ goto end;
+ }
+ ret = 1;
+end:
+ if (ret) {
+ *pubout = pub;
+ *privout = priv;
+ } else {
+ EVP_PKEY_free(priv);
+ }
+ return ret;
+}
+
+int main(void)
+{
+ OSSL_LIB_CTX *libctx = NULL;
+ size_t sig_len = 0;
+ unsigned char *sig_value = NULL;
+ int ret = EXIT_FAILURE;
+ EVP_PKEY *priv = NULL, *pub = NULL;
+
+ libctx = OSSL_LIB_CTX_new();
+ if (libctx == NULL) {
+ fprintf(stderr, "OSSL_LIB_CTX_new() returned NULL\n");
+ goto cleanup;
+ }
+ if (!create_key(libctx, &priv, &pub)) {
+ fprintf(stderr, "Failed to create key.\n");
+ goto cleanup;
+ }
+
+ if (!demo_sign(priv, hamlet, sizeof(hamlet), libctx,
+ &sig_value, &sig_len)) {
+ fprintf(stderr, "demo_sign failed.\n");
+ goto cleanup;
+ }
+ if (!demo_verify(pub, hamlet, sizeof(hamlet),
+ sig_value, sig_len, libctx)) {
+ fprintf(stderr, "demo_verify failed.\n");
+ goto cleanup;
+ }
+ ret = EXIT_SUCCESS;
+
+cleanup:
+ if (ret != EXIT_SUCCESS)
+ ERR_print_errors_fp(stderr);
+ EVP_PKEY_free(pub);
+ EVP_PKEY_free(priv);
+ OSSL_LIB_CTX_free(libctx);
+ OPENSSL_free(sig_value);
+ return ret;
+}
diff --git a/demos/signature/Makefile b/demos/signature/Makefile
index 394eef6d42..2a7c196007 100644
--- a/demos/signature/Makefile
+++ b/demos/signature/Makefile
@@ -1,23 +1,28 @@
#
# To run the demos when linked with a shared library (default):
#
-# LD_LIBRARY_PATH=../.. ./EVP_Signature_demo
+# LD_LIBRARY_PATH=../.. ./EVP_EC_Signature_demo
+# LD_LIBRARY_PATH=../.. ./EVP_DSA_Signature_demo
+# LD_LIBRARY_PATH=../.. ./EVP_ED_Signature_demo
+# LD_LIBRARY_PATH=../.. ./rsa_pss_direct
+# LD_LIBRARY_PATH=../.. ./rsa_pss_hash
CFLAGS = -I../../include -g -Wall
LDFLAGS = -L../..
LDLIBS = -lcrypto
-all: EVP_EC_Signature_demo EVP_DSA_Signature_demo rsa_pss_direct rsa_pss_hash
+all: EVP_EC_Signature_demo EVP_DSA_Signature_demo EVP_ED_Signature_demo rsa_pss_direct rsa_pss_hash
%.o: %.c
$(CC) $(CFLAGS) -c $<
EVP_EC_Signature_demo: EVP_EC_Signature_demo.o
EVP_DSA_Signature_demo: EVP_DSA_Signature_demo.o
+EVP_ED_Signature_demo: EVP_ED_Signature_demo.o
rsa_pss_direct: rsa_pss_direct.o
rsa_pss_hash: rsa_pss_hash.o
test: ;
clean:
- $(RM) *.o EVP_EC_Signature_demo EVP_DSA_Signature_demo rsa_pss_direct rsa_pss_hash
+ $(RM) *.o EVP_EC_Signature_demo EVP_DSA_Signature_demo EVP_ED_Signature_demo rsa_pss_direct rsa_pss_hash