From fc71c6016dda4d983dfbc187677d2045cf5abedc Mon Sep 17 00:00:00 2001 From: David Garske Date: Wed, 6 Jun 2018 14:00:11 -0700 Subject: [PATCH] Added new examples for ECC and PKCS7. Moved the signature/firmware_sign example into new `ecc` folder. --- .gitignore | 7 ++ ecc/Makefile | 36 ++++++ ecc/README.md | 112 ++++++++++++++++++ ecc/ecc-key-decode.c | 84 +++++++++++++ .../firmware_sign/eccsign.c => ecc/ecc-sign.c | 0 ecc/ecc-stack.c | 44 +++++++ ecc/ecc-verify.c | 98 +++++++++++++++ pkcs7/Makefile | 36 ++++++ pkcs7/README.md | 40 +++++++ pkcs7/pkcs7-verify.c | 69 +++++++++++ pkcs7/signed.p7s | Bin 0 -> 1633 bytes signature/firmware_sign/Makefile | 13 -- signature/firmware_sign/README.md | 31 ----- 13 files changed, 526 insertions(+), 44 deletions(-) create mode 100644 ecc/Makefile create mode 100644 ecc/README.md create mode 100644 ecc/ecc-key-decode.c rename signature/firmware_sign/eccsign.c => ecc/ecc-sign.c (100%) create mode 100644 ecc/ecc-stack.c create mode 100644 ecc/ecc-verify.c create mode 100644 pkcs7/Makefile create mode 100644 pkcs7/README.md create mode 100644 pkcs7/pkcs7-verify.c create mode 100755 pkcs7/signed.p7s delete mode 100644 signature/firmware_sign/Makefile delete mode 100644 signature/firmware_sign/README.md diff --git a/.gitignore b/.gitignore index e012f499..c19b4a98 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,10 @@ btle/ecc-server signature/sigtest/wolfsigtest signature/sigtest/opensigtest signature/firmware_sign/eccsign + +ecc/ecc-key-decode +ecc/ecc-sign +ecc/ecc-stack +ecc/ecc-verify +pkcs7/pkcs7-verify +*.dSYM diff --git a/ecc/Makefile b/ecc/Makefile new file mode 100644 index 00000000..332941f2 --- /dev/null +++ b/ecc/Makefile @@ -0,0 +1,36 @@ +# ECC Examples Makefile +CC = gcc +LIB_PATH = /usr/local +CFLAGS = -Wall -I$(LIB_PATH)/include +LIBS = -L$(LIB_PATH)/lib -lm + +# option variables +DYN_LIB = -lwolfssl +STATIC_LIB = $(LIB_PATH)/lib/libwolfssl.a +DEBUG_FLAGS = -g -DDEBUG +DEBUG_INC_PATHS = -MD +OPTIMIZE = -Os + +# Options +#CFLAGS+=$(DEBUG_FLAGS) +CFLAGS+=$(OPTIMIZE) +#LIBS+=$(STATIC_LIB) +LIBS+=$(DYN_LIB) + +# build targets +SRC=$(wildcard *.c) +TARGETS=$(patsubst %.c, %, $(SRC)) + +.PHONY: clean all + +all: $(TARGETS) + +debug: CFLAGS+=$(DEBUG_FLAGS) +debug: all + +# build template +%: %.c + $(CC) -o $@ $< $(CFLAGS) $(LIBS) + +clean: + rm -f $(TARGETS) diff --git a/ecc/README.md b/ecc/README.md new file mode 100644 index 00000000..c388e564 --- /dev/null +++ b/ecc/README.md @@ -0,0 +1,112 @@ +# Examples demonstrating ECC + +## Building + +### Build and install wolfSSL + +``` +./configure --enable-ecc --enable-ecccustcurves CFLAGS="-DWOLFSSL_TEST_CERT" && make && sudo make install +``` + +### Build Example + +``` +make + +gcc -o ecc-key-decode ecc-key-decode.c -Wall -I/usr/local/include -Os -L/usr/local/lib -lm -lwolfssl +gcc -o ecc-sign ecc-sign.c -Wall -I/usr/local/include -Os -L/usr/local/lib -lm -lwolfssl +gcc -o ecc-stack ecc-stack.c -Wall -I/usr/local/include -Os -L/usr/local/lib -lm -lwolfssl +gcc -o ecc-verify ecc-verify.c -Wall -I/usr/local/include -Os -L/usr/local/lib -lm -lwolfssl +``` + +### Debug + +To enable debug change the Makefile to: + +``` +CFLAGS+=$(DEBUG_FLAGS) +#CFLAGS+=$(OPTIMIZE) +``` + +Build wolfSSL using: `./configure --enable-ecc --enable-ecccustcurves --enable-debug CFLAGS="-DWOLFSSL_TEST_CERT" && make && sudo make install` + + +## Usage + +### `ecc-key-decode` + +This example shows how to extract a public key from a certificate and load it. + +``` +./ecc-key-decode +bytes = 781 +decodedCert.pubKeySize 91 +publickey size: 32 +Success + +``` + +### `ecc-sign` + +This example demonstrates signing large data by performing the hash in chunks and signing. The sign is done multiple times to show how its normal for the signature size to vary for the same private key and hash data because a new public key is generated for each operation. + +``` +./ecc-sign +KeyGen Done +Sign ret 0, sigLen 103 +Verify ret 0, is_valid_sig 1 +Firmware Signature 0: Ret 0, HashLen 32, SigLen 103 +Sign ret 0, sigLen 102 +Verify ret 0, is_valid_sig 1 +Firmware Signature 1: Ret 0, HashLen 32, SigLen 102 +Sign ret 0, sigLen 102 +Verify ret 0, is_valid_sig 1 +Firmware Signature 2: Ret 0, HashLen 32, SigLen 102 +Sign ret 0, sigLen 103 +Verify ret 0, is_valid_sig 1 +Firmware Signature 3: Ret 0, HashLen 32, SigLen 103 +Sign ret 0, sigLen 103 +Verify ret 0, is_valid_sig 1 +Firmware Signature 4: Ret 0, HashLen 32, SigLen 103 +Sign ret 0, sigLen 103 +Verify ret 0, is_valid_sig 1 +Firmware Signature 5: Ret 0, HashLen 32, SigLen 103 +Sign ret 0, sigLen 102 +Verify ret 0, is_valid_sig 1 +Firmware Signature 6: Ret 0, HashLen 32, SigLen 102 +Sign ret 0, sigLen 102 +Verify ret 0, is_valid_sig 1 +Firmware Signature 7: Ret 0, HashLen 32, SigLen 102 +Sign ret 0, sigLen 103 +Verify ret 0, is_valid_sig 1 +Firmware Signature 8: Ret 0, HashLen 32, SigLen 103 +Sign ret 0, sigLen 102 +Verify ret 0, is_valid_sig 1 +Firmware Signature 9: Ret 0, HashLen 32, SigLen 102 + +``` + +### `ecc-stack` + +This example show stack use for an ECC key generation. + +``` +./ecc-stack +total Allocs = 5 +total Deallocs = 5 +total Bytes = 16440 +peak Bytes = 16440 +current Bytes = 0 +stack used = 25296 +sizeof RNG = 32 +sizeof ecc_key = 4424 +``` + +### `ecc-verify` + +This example demonstrates using a Koblitz (SECP256K1) curve. + +``` +./ecc-verify +hash_firmware_verify: 0 +``` diff --git a/ecc/ecc-key-decode.c b/ecc/ecc-key-decode.c new file mode 100644 index 00000000..694b665f --- /dev/null +++ b/ecc/ecc-key-decode.c @@ -0,0 +1,84 @@ +#include +#include +#include +#include +#include +#include + +#include + +#if defined(WOLFSSL_TEST_CERT) || defined(OPENSSL_EXTRA) || \ + defined(OPENSSL_EXTRA_X509_SMALL) + +static void check_ret(char*, int); + +int main(void) +{ + DecodedCert decodedCert; + FILE* file; + byte derBuffer[4096]; + size_t bytes; + ecc_key eccKey; + int ret; + word32 inOutIdx = 0; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + wolfCrypt_Init(); + + file = fopen("../certs/client-ecc-cert.der", "rb"); + if (!file) { + printf("Failed to open file\n"); + exit(-99); + } + + bytes = fread(derBuffer, 1, 4096, file); + fclose(file); + + printf("bytes = %d\n", (int) bytes); + + InitDecodedCert(&decodedCert, derBuffer, (word32) bytes, 0); + + ret = ParseCert(&decodedCert, CERT_TYPE, NO_VERIFY, NULL); + check_ret("ParseCert", ret); + + ret = wc_ecc_init(&eccKey); + check_ret("wc_ecc_init", ret); + + printf("decodedCert.pubKeySize %d\n", decodedCert.pubKeySize); + WOLFSSL_BUFFER(decodedCert.publicKey, decodedCert.pubKeySize); + + ret = wc_EccPublicKeyDecode(decodedCert.publicKey, &inOutIdx, &eccKey, decodedCert.pubKeySize); + check_ret("wc_EccPublicKeyDecode", ret); + + printf("publickey size: %d\n", wc_ecc_size(&eccKey)); + + wolfCrypt_Cleanup(); + + printf("Success\n"); + + return 0; +} + + +static void check_ret(char* call, int ret) +{ + if (ret != 0) { + printf("call: %s\n", call); + printf("ret = %d\n", ret); + exit(-99); + } + return; +} + +#else + +int main(void) +{ + printf("Not compiled in: Must build wolfSSL using ./confgiure --enable-opensslextra or ./configure CFLAGS=-DWOLFSSL_TEST_CERT\n"); + return 0; +} + +#endif diff --git a/signature/firmware_sign/eccsign.c b/ecc/ecc-sign.c similarity index 100% rename from signature/firmware_sign/eccsign.c rename to ecc/ecc-sign.c diff --git a/ecc/ecc-stack.c b/ecc/ecc-stack.c new file mode 100644 index 00000000..983fdb3b --- /dev/null +++ b/ecc/ecc-stack.c @@ -0,0 +1,44 @@ +#define WOLFSSL_TRACK_MEMORY +#define HAVE_STACK_SIZE + +#include +#include +#include +#include + +#include +#include + +static RNG rng; +static ecc_key genKey; + +void* do_it(void* args) +{ + int ret; + + InitMemoryTracker(); + + ret = wc_ecc_make_key(&rng, 32, &genKey); + if (ret < 0) { + printf("ecc make key failed\n"); + } + + ShowMemoryTracker(); + + return 0; +} + + +int main() +{ + int ret = wc_InitRng(&rng); + if (ret < 0) { + printf("Init RNG failed\n"); + } + + StackSizeCheck(NULL, do_it); + printf("sizeof RNG = %lu\n", sizeof(RNG)); + printf("sizeof ecc_key = %lu\n", sizeof(ecc_key)); + + return 0; +} diff --git a/ecc/ecc-verify.c b/ecc/ecc-verify.c new file mode 100644 index 00000000..6762bed3 --- /dev/null +++ b/ecc/ecc-verify.c @@ -0,0 +1,98 @@ +#include +#include +#include +#include +#include +#include + +#if defined(WOLFSSL_CUSTOM_CURVES) && defined(HAVE_ECC_KOBLITZ) + +#define MAX_BLOCK_SIZE 1024 + +int hash_firmware_verify(const byte* fwAddr, word32 fwLen, const byte* sigBuf, word32 sigLen) +{ + wc_Sha256 sha; + byte hash[WC_SHA256_DIGEST_SIZE]; + int ret; + ecc_key eccKey; + word32 inOutIdx; + const byte pubKey[] = { + 0x30, 0x56, 0x30, 0x10, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x05, 0x2b, + 0x81, 0x04, 0x00, 0x0a, 0x03, 0x42, 0x00, 0x04, 0xcf, 0x43, 0x31, 0x08, 0x86, 0xe1, 0xf5, 0xf3, + 0xd3, 0x73, 0x00, 0x40, 0x96, 0xaa, 0xa8, 0xe5, 0xb5, 0x39, 0x14, 0x64, 0xd6, 0xff, 0x65, 0x5b, + 0x29, 0x72, 0x66, 0x7a, 0x47, 0x90, 0x29, 0x16, 0x23, 0xad, 0xba, 0x90, 0x52, 0x56, 0x42, 0xe0, + 0x1c, 0x8a, 0x80, 0x0d, 0x79, 0x57, 0xe6, 0x6e, 0x3d, 0x73, 0x4a, 0xf1, 0xe1, 0xd2, 0x6f, 0x2b, + 0x51, 0xd0, 0xa8, 0x89, 0xa0, 0x58, 0xff, 0xbd + }; + int pos, verify; + + ret = wc_InitSha256(&sha); + if (ret != 0) + return ret; + + pos = 0; + while (fwLen > 0) { + int len = fwLen; + + if (len > MAX_BLOCK_SIZE) + len = MAX_BLOCK_SIZE; + + ret = wc_Sha256Update(&sha, fwAddr + pos, len); + if (ret < 0) + goto exit; + + pos += len; + fwLen -= len; + } + + ret = wc_Sha256Final(&sha, hash); + if (ret < 0) + goto exit; + + inOutIdx = 0; + ret = wc_EccPublicKeyDecode(pubKey, &inOutIdx, &eccKey, sizeof(pubKey)); + if (ret < 0) + goto exit; + + ret = wc_ecc_set_curve(&eccKey, 32, ECC_SECP256K1); + if (ret < 0) + goto exit; + + ret = wc_ecc_verify_hash((byte*)sigBuf, sigLen, hash, sizeof(hash), &verify, &eccKey); + if (ret < 0) + goto exit; + +exit: + wc_Sha256Free(&sha); + + return ret; +} + +int main(void) +{ + int ret; + const byte data[] = {'t', 'e', 's', 't', '\n'}; + const byte sigBuf[] = { + 0x30, 0x43, 0x02, 0x1f, 0x11, 0x80, 0x77, 0xa8, 0xfe, 0x05, 0x70, 0x3a, 0x62, 0x9f, 0x2a, 0xe3, + 0x10, 0x67, 0x8b, 0x58, 0xb4, 0x87, 0x81, 0x51, 0x21, 0x7e, 0x8b, 0x8a, 0x15, 0xd2, 0xa0, 0xc6, + 0x58, 0xcc, 0x95, 0x02, 0x20, 0x00, 0xd6, 0x07, 0xdc, 0x50, 0xcb, 0xbb, 0x48, 0x89, 0xc1, 0x89, + 0x34, 0xff, 0xcc, 0x75, 0x33, 0x08, 0x82, 0x12, 0x3f, 0x8d, 0x32, 0x16, 0xf4, 0xf3, 0xa4, 0x18, + 0xb7, 0x0e, 0x26, 0x55, 0x81 + }; + word32 sigLen = (word32)sizeof(sigBuf); + + ret = hash_firmware_verify(data, sizeof(data), sigBuf, sigLen); + printf("hash_firmware_verify: %d\n", ret); + + return 0; +} + +#else + +int main(void) +{ + printf("Not compiled in: Build wolfSSL with `./configure --enable-ecccustcurves CFLAGS=-DHAVE_ECC_KOBLITZ` or `WOLFSSL_CUSTOM_CURVES` and `HAVE_ECC_KOBLITZ`\n"); + return 0; +} + +#endif diff --git a/pkcs7/Makefile b/pkcs7/Makefile new file mode 100644 index 00000000..332941f2 --- /dev/null +++ b/pkcs7/Makefile @@ -0,0 +1,36 @@ +# ECC Examples Makefile +CC = gcc +LIB_PATH = /usr/local +CFLAGS = -Wall -I$(LIB_PATH)/include +LIBS = -L$(LIB_PATH)/lib -lm + +# option variables +DYN_LIB = -lwolfssl +STATIC_LIB = $(LIB_PATH)/lib/libwolfssl.a +DEBUG_FLAGS = -g -DDEBUG +DEBUG_INC_PATHS = -MD +OPTIMIZE = -Os + +# Options +#CFLAGS+=$(DEBUG_FLAGS) +CFLAGS+=$(OPTIMIZE) +#LIBS+=$(STATIC_LIB) +LIBS+=$(DYN_LIB) + +# build targets +SRC=$(wildcard *.c) +TARGETS=$(patsubst %.c, %, $(SRC)) + +.PHONY: clean all + +all: $(TARGETS) + +debug: CFLAGS+=$(DEBUG_FLAGS) +debug: all + +# build template +%: %.c + $(CC) -o $@ $< $(CFLAGS) $(LIBS) + +clean: + rm -f $(TARGETS) diff --git a/pkcs7/README.md b/pkcs7/README.md new file mode 100644 index 00000000..702aaa35 --- /dev/null +++ b/pkcs7/README.md @@ -0,0 +1,40 @@ +# Examples demonstrating PKCS7 + +## Building + +### Build and install wolfSSL + +``` +./configure --enable-pkcs7 && make && sudo make install +``` + +### Build Example + +``` +make +gcc -o pkcs7 pkcs7.c -Wall -I/usr/local/include -Os -L/usr/local/lib -lm -lwolfssl +gcc -o ecc-verify ecc-verify.c -Wall -I/usr/local/include -Os -L/usr/local/lib -lm -lwolfssl +``` + +### Debug + +To enable debug change the Makefile to: + +``` +CFLAGS+=$(DEBUG_FLAGS) +#CFLAGS+=$(OPTIMIZE) +``` + +Build wolfSSL using: `./configure --enable-pkcs7 --enable-debug && make && sudo make install` + + +## Usage + + +### `pkcs7-verify` + +``` +./pkcs7-verify +Der 1633 +PKCS7 Verify Success +``` diff --git a/pkcs7/pkcs7-verify.c b/pkcs7/pkcs7-verify.c new file mode 100644 index 00000000..7b8e8082 --- /dev/null +++ b/pkcs7/pkcs7-verify.c @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include + +#ifdef HAVE_PKCS7 + +int main(int argc, char** argv) +{ + int rc = 0; + PKCS7 pkcs7; + XFILE derFile; + byte* derBuf = NULL; + word32 derSz = 0; + +#ifdef DEBUG_WOLFSSL + wolfSSL_Debugging_ON(); +#endif + + /* load DER PKCS7 */ + derFile = fopen("signed.p7s", "rb"); + if (derFile) { + fseek(derFile, 0, SEEK_END); + derSz = (int)ftell(derFile); + rewind(derFile); + + derBuf = (byte*)XMALLOC(derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER); + if (derBuf == NULL) { + rc = MEMORY_E; goto exit; + } + + rc = (int)fread(derBuf, 1, derSz, derFile); + fclose(derFile); + } + + printf("Der %d\n", derSz); + WOLFSSL_BUFFER(derBuf, derSz); + + /* Test verify */ + rc = wc_PKCS7_Init(&pkcs7, NULL, INVALID_DEVID); + if (rc != 0) goto exit; + rc = wc_PKCS7_InitWithCert(&pkcs7, NULL, 0); + if (rc != 0) goto exit; + rc = wc_PKCS7_VerifySignedData(&pkcs7, derBuf, derSz); + if (rc != 0) goto exit; + + printf("PKCS7 Verify Success\n"); + +exit: + + if (rc != 0) + printf("RC=%d\n", rc); + + wc_PKCS7_Free(&pkcs7); + XFREE(derBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + + return rc; +} + +#else + +int main(int argc, char** argv) +{ + printf("Not compiled in: Must build wolfSSL using ./configure --enable-pkcs7\n"); + return 0; +} + +#endif diff --git a/pkcs7/signed.p7s b/pkcs7/signed.p7s new file mode 100755 index 0000000000000000000000000000000000000000..e1e6280c2d193089b25844ddc263e98a1d76ab0d GIT binary patch literal 1633 zcmXqLVvA+t)N1o+`_9YA&a|M3&Cj5T&5MbV(U9MOmyI)_&4V$OnT3gwmBBy-p^$Nb zIE$!nr9x_6a(+r`ih_%4kV0~5QHdVIf+iL_gC-U$gC=IB1HD7#SLx7#l^2^BRG;hET3S;}levg8~Wc zayI{>^i-g$1r7KiuI32HFDl7N%uAt%vzr)|ki!@lTg*+2{0s(7j9g4jjEoFRPW)im z5b3mJ4a;U#<1g-OO7%Z)*PVawbhF>dyUK~XryY>a-p_Al8DJN+t#{kUgAX<``)f~* zdSqR>{`#o|mgb_H)sv5J);eQ)DOk=?Zt;A}RhtelH7}dFLM70@kScunP+Tkg^{%5zO>=jAJagxpkV7~3ye}Jcx4dnb zz;4BjMXDG-w4HcFWtHP;pYrq5n|sA1E~a0tyOvX&){z-u zVlzEU=RuD5;~N4|=eE4m_l<~{{V7JQVDa~lOH?zB52cGg)tOpmBf0Fs)d07gYaufi z@3s%RIhl!>k%4h>;{=1oUU0gT6=q>FU;w5%Z~|}p;l#+u!otkNx&W9ym_udxSj1RF zJhi)dCQlIF_~B{c%E+{U8HF=rz8c7bq?K8KDXc-nCS85zy}ha1<|(S5-8sEz)Aa+* z*THF4mYgQWGno;r^I>t-@DQrjxu6j zx$Y}eUly6L!fD#Csm-?8*jMuC>~9kt|0kPwEjahM zSIN|FyZiL%9g-6d=QU?9?l+wrFQNU7Nql07y2qSNx2zm@JX^Kr)6e{zAhFZ`yjJ9_ zoVzLZWN)#A>YhN)gyWVg3?Ex9=W{y0`vLEk8Jh!px~Id@b}jv|CrOEOI$khEZ