ED25519 examples for key gen and .der output, sign/verify

pull/43/head
kaleb-himes 2017-04-11 17:35:51 -06:00
parent dcb6f3da5d
commit 7bb3cc3ad1
10 changed files with 366 additions and 0 deletions

4
.gitignore vendored
View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
M2ёље§лЖЋбыЫЃ_<D083>PKЭq<D0AD>пBОїЎx<D08E>^<5E>И<EFBFBD>m йд<D0B9>Ѓ|<7C>ь.вdй/я<>чCДШ c8ё<38>

View File

@ -0,0 +1 @@
™Έm ΩΤƒ£|μ.<2E>dΩ/ο<>ηC΄Θ c8ρ<38>

View File

@ -0,0 +1,81 @@
#include <stdio.h>
#include <wolfssl/options.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/ssl.h>
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;
}

View File

@ -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);
}

View File

@ -0,0 +1,68 @@
#include <stdio.h>
#include <wolfssl/options.h>
//#include <wolfssl/wolfcrypt/dsa.h>
#include <wolfssl/wolfcrypt/asn_public.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/ssl.h>
#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;
}

View File

@ -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 */

View File

@ -19,3 +19,22 @@ $ ./firmware [filename] [sig] [hash]
Usage: signature <filename> <sig> <hash>
<sig>: 1=ECC (def), 2=RSA, 3=RSA (w/DER Encoding)
<hash>: 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