From 7bb3cc3ad13dbabaacb70c6f19fd94d9d12922c4 Mon Sep 17 00:00:00 2001 From: kaleb-himes Date: Tue, 11 Apr 2017 17:35:51 -0600 Subject: [PATCH] ED25519 examples for key gen and .der output, sign/verify --- .gitignore | 4 ++ signature/ED25519/Makefile | 45 +++++++++++++ signature/ED25519/README | 21 ++++++ signature/ED25519/ed_priv_test_key.der | 1 + signature/ED25519/ed_pub_test_key.der | 1 + signature/ED25519/gen_key_files.c | 81 +++++++++++++++++++++++ signature/ED25519/genkeybuffers.pl | 92 ++++++++++++++++++++++++++ signature/ED25519/sign_and_verify.c | 68 +++++++++++++++++++ signature/ED25519/test_keys.h | 34 ++++++++++ signature/README.md | 19 ++++++ 10 files changed, 366 insertions(+) create mode 100644 signature/ED25519/Makefile create mode 100644 signature/ED25519/README create mode 100644 signature/ED25519/ed_priv_test_key.der create mode 100644 signature/ED25519/ed_pub_test_key.der create mode 100644 signature/ED25519/gen_key_files.c create mode 100755 signature/ED25519/genkeybuffers.pl create mode 100644 signature/ED25519/sign_and_verify.c create mode 100644 signature/ED25519/test_keys.h diff --git a/.gitignore b/.gitignore index c2ede6a7..73a5d14e 100644 --- a/.gitignore +++ b/.gitignore @@ -78,8 +78,12 @@ crypto/keys/*.der crypto/keys/*.x963 signature/signature +signature/ED25519/gen_key_files +signature/ED25519/sign_and_verify #cergen certgen/test.o certgen/newCert* certgen/run_certgen_example + + diff --git a/signature/ED25519/Makefile b/signature/ED25519/Makefile new file mode 100644 index 00000000..9dc7b85a --- /dev/null +++ b/signature/ED25519/Makefile @@ -0,0 +1,45 @@ +EXECUTABLE1 := sign_and_verify +C_SOURCES1 := sign_and_verify.c +C_OBJECTS1 := ${C_SOURCES1:.c=.o} +OBJECTS1 := $(C_OBJECTS1) + +EXECUTABLE2 := gen_key_files +C_SOURCES2 := gen_key_files.c +C_OBJECTS2 := ${C_SOURCES2:.c=.o} +OBJECTS2 := $(C_OBJECTS2) + +INCLUDE_DIRS := +LIBRARY_DIRS := +LIBRARIES := + +#example: if using custom install location add the include and lib dir to the +# INCLUDE_DIRS and LIBRARY_DIRS respectively + +#INCLUDE_DIRS += /Users/khimes/work/testDir/wolf-install-dir-for-testing/include +#LIBRARY_DIRS += /Users/khimes/work/testDir/wolf-install-dir-for-testing/lib +LIBRARIES += wolfssl + +CPPFLAGS += $(foreach includedir,$(INCLUDE_DIRS),-I$(includedir)) +#CPPFLAGS += -Werror +#CPPFLAGS += -Weverything +LDFLAGS += $(foreach librarydir,$(LIBRARY_DIRS),-L$(librarydir)) +LDFLAGS += $(foreach library,$(LIBRARIES),-l$(library)) + +.PHONY: all clean distclean + +all: $(EXECUTABLE1) $(EXECUTABLE2) + +$(EXECUTABLE1): $(OBJECTS1) + $(LINK.cc) $(OBJECTS1) -o $(EXECUTABLE1) + +$(EXECUTABLE2): $(OBJECTS2) + $(LINK.cc) $(OBJECTS2) -o $(EXECUTABLE2) + + +$(EXECUTABLE1): $(OBJECTS1) +$(EXECUTABLE2): $(OBJECTS2) +clean: + @- $(RM) $(EXECUTABLE1) $(EXECUTABLE2) + @- $(RM) $(OBJECTS1) $(OBJECTS2) + +distclean: clean diff --git a/signature/ED25519/README b/signature/ED25519/README new file mode 100644 index 00000000..3bf1c091 --- /dev/null +++ b/signature/ED25519/README @@ -0,0 +1,21 @@ +To compile without Makefile: + +gcc -o gen_key_files gen_key_files.c -lwolfssl +gcc -o sign_and_verify sign_and_verify.c -lwolfssl + + +To re-create the ed25519 private/public key files and update the test_keys.h +header file run these commands: + +./gen_key_files +./genkeybuffers.pl + +To sign a message and verify the signature run: + +./sign_and_verify + + +Best wishes in all your testing! + +- The wolfSSL Team + diff --git a/signature/ED25519/ed_priv_test_key.der b/signature/ED25519/ed_priv_test_key.der new file mode 100644 index 00000000..d2042d87 --- /dev/null +++ b/signature/ED25519/ed_priv_test_key.der @@ -0,0 +1 @@ +M2۶ˣ_PKqBx^m ԃ|H.d/C c8 \ No newline at end of file diff --git a/signature/ED25519/ed_pub_test_key.der b/signature/ED25519/ed_pub_test_key.der new file mode 100644 index 00000000..ceffaa77 --- /dev/null +++ b/signature/ED25519/ed_pub_test_key.der @@ -0,0 +1 @@ +m ԃ|H.d/C c8 \ No newline at end of file diff --git a/signature/ED25519/gen_key_files.c b/signature/ED25519/gen_key_files.c new file mode 100644 index 00000000..c33d1923 --- /dev/null +++ b/signature/ED25519/gen_key_files.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include + +int create_and_output_ed_key(void); +static int err_sys(const char* msg, int es); + +static int err_sys(const char* msg, int es) +{ + printf("%s error = %d\n", msg, es); + + exit(-1); +} + +int +main(int argc, char* argv[]) +{ + int ret = -1001; + FILE* file; + char edPrivFName[] = "./ed_priv_test_key.der"; + char edPubFName[] = "./ed_pub_test_key.der"; + byte exportPrivKey[ED25519_KEY_SIZE*2]; + byte exportPubKey[ED25519_KEY_SIZE]; + word32 exportPrivSz; + word32 exportPubSz; + WC_RNG rng; + ed25519_key edKeyOut; + + + wolfSSL_Debugging_ON(); +/*--------------- INIT ---------------------*/ + ret = wc_InitRng(&rng); + if (ret != 0) err_sys("wc_InitRng err: ", ret); /* replace all go-to's with err_sys */ + + ret = wc_ed25519_init(&edKeyOut); + if (ret != 0) err_sys("wc_ed25519_init err: ", ret); + +/*--------------- MAKE KEY ---------------------*/ + ret = wc_ed25519_make_key(&rng, ED25519_KEY_SIZE, &edKeyOut); + if (ret != 0) err_sys("wc_ed25519_make_key err: ", ret); + +/*--------------- GET KEY SIZES ---------------------*/ + exportPrivSz = wc_ed25519_priv_size(&edKeyOut); + if (exportPrivSz <= 0) err_sys("wc_ed25519_priv_size err: ", exportPrivSz); + + exportPubSz = wc_ed25519_pub_size(&edKeyOut); + if (exportPubSz <= 0) err_sys("wc_ed25519_pub_size err: ", exportPubSz); + +/*--------------- EXPORT KEYS TO BUFFERS ---------------------*/ + ret = wc_ed25519_export_key(&edKeyOut, exportPrivKey, &exportPrivSz, + exportPubKey, &exportPubSz); + if (ret != 0) err_sys("wc_ed25519_export_key err: ", ret); + +/*--------------- OUTPUT KEYS TO FILES ---------------------*/ + file = fopen(edPrivFName, "wb"); + if (!file) err_sys("error opening edPrivFName file", -1002); + + ret = (int) fwrite(exportPrivKey, 1, exportPrivSz, file); + if (ret <= 0) { + fclose(file); + err_sys("Failed to write to edPrivFName file", -1003); + } + + fclose(file); + + file = fopen(edPubFName, "wb"); + if (!file) err_sys("error opening edPubFName file", -1004); + + ret = (int) fwrite(exportPubKey, 1, exportPubSz, file); + if (ret <= 0) { + fclose(file); + err_sys("Failed to write to edPubFName file", -1005); + } + + fclose(file); + + if (ret > 0) ret = 0; + + return ret; +} diff --git a/signature/ED25519/genkeybuffers.pl b/signature/ED25519/genkeybuffers.pl new file mode 100755 index 00000000..2c156b39 --- /dev/null +++ b/signature/ED25519/genkeybuffers.pl @@ -0,0 +1,92 @@ +#!/usr/bin/perl + +# gencertbuf.pl +# version 1.1 +# Updated 04/11/2017 +# +# Copyright (C) 2006-2017 wolfSSL Inc. +# + +use strict; +use warnings; + +# ---- SCRIPT SETTINGS ------------------------------------------------------- + +# output C header file to write cert/key buffers to +my $outputFile = "./test_keys.h"; + +# 2048-bit certs/keys to be converted +# Used with USE_CERT_BUFFERS_2048 define. + +my @fileList_2048 = ( + [ "./ed_pub_test_key.der", "ed_pub_key_der_32" ], + [ "./ed_priv_test_key.der", "ed_priv_key_der_64" ], + ); + +# ---------------------------------------------------------------------------- + +my $num_2048 = @fileList_2048; + +# open our output file, "+>" creates and/or truncates +open OUT_FILE, "+>", $outputFile or die $!; + +print OUT_FILE "/* certs_test.h */\n\n"; +print OUT_FILE "#ifndef WOLFSSL_CERTS_TEST_H\n"; +print OUT_FILE "#define WOLFSSL_CERTS_TEST_H\n\n"; + + +# convert and print 32/64-bit certs/keys +print OUT_FILE "#ifdef USE_CERT_BUFFERS_ED\n\n"; +for (my $i = 0; $i < $num_2048; $i++) { + + my $fname = $fileList_2048[$i][0]; + my $sname = $fileList_2048[$i][1]; + + print OUT_FILE "/* $fname, (32/64)-bit */\n"; + print OUT_FILE "static const unsigned char $sname\[] =\n"; + print OUT_FILE "{\n"; + file_to_hex($fname); + print OUT_FILE "};\n"; + print OUT_FILE "static const int sizeof_$sname = sizeof($sname);\n\n"; +} + + +print OUT_FILE "#endif /* USE_CERT_BUFFERS_ED */\n\n"; +print OUT_FILE "#endif /* WOLFSSL_CERTS_TEST_H */\n\n"; +# close certs_test.h file +close OUT_FILE or die $!; + +# print file as hex, comma-separated, as needed by C buffer +sub file_to_hex { + my $fileName = $_[0]; + + open my $fp, "<", $fileName or die $!; + binmode($fp); + + my $fileLen = -s $fileName; + my $byte; + + for (my $i = 0, my $j = 1; $i < $fileLen; $i++, $j++) + { + if ($j == 1) { + print OUT_FILE "\t"; + } + read($fp, $byte, 1) or die "Error reading $fileName"; + my $output = sprintf("0x%02X", ord($byte)); + print OUT_FILE $output; + + if ($i != ($fileLen - 1)) { + print OUT_FILE ", "; + } + + if ($j == 10) { + $j = 0; + print OUT_FILE "\n"; + } + } + + print OUT_FILE "\n"; + + close($fp); +} + diff --git a/signature/ED25519/sign_and_verify.c b/signature/ED25519/sign_and_verify.c new file mode 100644 index 00000000..59288107 --- /dev/null +++ b/signature/ED25519/sign_and_verify.c @@ -0,0 +1,68 @@ +#include + +#include +//#include +#include +#include +#include +#define USE_CERT_BUFFERS_ED +#include "test_keys.h" + +static int err_sys(const char* msg, int es); + +static int err_sys(const char* msg, int es) +{ + printf("%s error = %d\n", msg, es); + + exit(-1); +} + +int +main(int argc, char* argv[]) +{ + + int ret = -1000; + int verify; + ed25519_key edPublicKey; + ed25519_key edPrivateKey; + + byte message[] = "Hi how are you?\n"; + byte sigOut[ED25519_SIG_SIZE]; + word32 sigOutSz = sizeof(sigOut); + + wolfSSL_Debugging_ON(); + + +/*--------------- INIT KEYS ---------------------*/ + ret = wc_ed25519_init(&edPublicKey); + ret = wc_ed25519_init(&edPrivateKey); + + if (ret != 0) { + printf("Error: wc_ed25519_init: %d\n", ret); + } + +/*--------------- IMPORT KEYS FROM HEADER ---------------------*/ + ret = wc_ed25519_import_public(ed_pub_key_der_32, sizeof_ed_pub_key_der_32, + &edPublicKey); + if (ret != 0) err_sys("Error: ED public key import failed: ", ret); + + ret = wc_ed25519_import_private_key(ed_priv_key_der_64, + ED25519_KEY_SIZE, + ed_priv_key_der_64 + ED25519_KEY_SIZE, + ED25519_KEY_SIZE, &edPrivateKey); + if (ret != 0) err_sys("Error: ED private key import failed: ", ret); + +/*--------------- SIGN THE MESSAGE ---------------------*/ + ret = wc_ed25519_sign_msg(message, sizeof(message), sigOut, &sigOutSz, + &edPrivateKey); + if (ret != 0) err_sys("Error: ED sign failed: ", ret); + +/*--------------- VERIFY THE MESSAGE ---------------------*/ + ret = wc_ed25519_verify_msg(sigOut, sigOutSz, message, sizeof(message), + &verify, &edPublicKey); + if (ret != 0) err_sys("Error: Could not verify signature: ", ret); + + printf("Successfully validated signature\n"); + + return 0; +} diff --git a/signature/ED25519/test_keys.h b/signature/ED25519/test_keys.h new file mode 100644 index 00000000..38c31c1c --- /dev/null +++ b/signature/ED25519/test_keys.h @@ -0,0 +1,34 @@ +/* certs_test.h */ + +#ifndef WOLFSSL_CERTS_TEST_H +#define WOLFSSL_CERTS_TEST_H + +#ifdef USE_CERT_BUFFERS_ED + +/* ./ed_pub_test_key.der, (32/64)-bit */ +static const unsigned char ed_pub_key_der_32[] = +{ + 0x99, 0xB8, 0x8B, 0x6D, 0x14, 0x0D, 0xD9, 0xD4, 0x83, 0xA3, + 0x7C, 0x82, 0x48, 0xE8, 0x01, 0xEC, 0x2E, 0xD2, 0x64, 0xD9, + 0x2F, 0xEF, 0x8D, 0xE7, 0x43, 0xB4, 0xC8, 0x0D, 0x63, 0x38, + 0xF1, 0x8F +}; +static const int sizeof_ed_pub_key_der_32 = sizeof(ed_pub_key_der_32); + +/* ./ed_priv_test_key.der, (32/64)-bit */ +static const unsigned char ed_priv_key_der_64[] = +{ + 0x4D, 0x32, 0xF1, 0xF9, 0xD5, 0xFD, 0xDB, 0xB6, 0x01, 0xAB, + 0xD1, 0x1F, 0xEB, 0x10, 0xCB, 0xA3, 0x5F, 0x92, 0x7F, 0x50, + 0x4B, 0xCD, 0x71, 0x83, 0xDF, 0x42, 0xBE, 0xF7, 0xAE, 0x78, + 0x90, 0x5E, 0x99, 0xB8, 0x8B, 0x6D, 0x14, 0x0D, 0xD9, 0xD4, + 0x83, 0xA3, 0x7C, 0x82, 0x48, 0xE8, 0x01, 0xEC, 0x2E, 0xD2, + 0x64, 0xD9, 0x2F, 0xEF, 0x8D, 0xE7, 0x43, 0xB4, 0xC8, 0x0D, + 0x63, 0x38, 0xF1, 0x8F +}; +static const int sizeof_ed_priv_key_der_64 = sizeof(ed_priv_key_der_64); + +#endif /* USE_CERT_BUFFERS_ED */ + +#endif /* WOLFSSL_CERTS_TEST_H */ + diff --git a/signature/README.md b/signature/README.md index 56ffc77c..487d19db 100644 --- a/signature/README.md +++ b/signature/README.md @@ -19,3 +19,22 @@ $ ./firmware [filename] [sig] [hash] Usage: signature : 1=ECC (def), 2=RSA, 3=RSA (w/DER Encoding) : 1=MD2, 2=MD4, 3=MD5, 4=SHA, 5=SHA256 (def), 6=SHA384, 7=SHA512, 8=MD5+SHA + +------------------ UPDATE ----------------- +April 11 2017: + +Added ED25519 directory + +ED25519 directory contains: + +1. App "gen_key_files.c" to generate public/private keys and output keys to .der +formatted files. + +2. genkeybuffers.pl - a perl script to write the header file "test_keys.h" using + the .der formatted files output from applicaton "gen_key_files.c" + +3. App "sign_and_verify.c" to use the "test_keys.h" header file buffers for + importing the public and private keys. App will then sign a msg with the + private key and verify that signature using the public key + +