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..663a7bc2 --- /dev/null +++ b/ecc/ecc-key-decode.c @@ -0,0 +1,89 @@ +#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("read bytes = %d\n", (int) bytes); + if (bytes <= 0) { + return -1; + } + + 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)); + + FreeDecodedCert(&decodedCert); + + 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..708acab0 --- /dev/null +++ b/ecc/ecc-stack.c @@ -0,0 +1,59 @@ +#define WOLFSSL_TRACK_MEMORY +#define HAVE_STACK_SIZE + +#include +#include +#include +#include + +#include +#include + +#define TEST_KEY_SZ 32 + +static WC_RNG mRng; +static ecc_key mGenKey; + +static void* do_it(void* args) +{ + int ret; + + InitMemoryTracker(); + + ret = wc_ecc_make_key(&mRng, TEST_KEY_SZ, &mGenKey); + if (ret != 0) { + printf("ecc make key failed %d\n", ret); + } + + ShowMemoryTracker(); + CleanupMemoryTracker(); + + (void)args; + + return 0; +} + + +int main() +{ + int ret; + + wolfCrypt_Init(); + + ret = wc_InitRng(&mRng); + if (ret != 0) { + printf("Init RNG failed %d\n", ret); + } + + StackSizeCheck(NULL, do_it); + printf("sizeof RNG = %lu\n", sizeof(WC_RNG)); + printf("sizeof ecc_key = %lu\n", sizeof(ecc_key)); + + ret = wc_FreeRng(&mRng); + if (ret != 0) { + printf("Free RNG failed %d\n", ret); + } + wolfCrypt_Cleanup(); + + return 0; +} diff --git a/ecc/ecc-verify.c b/ecc/ecc-verify.c new file mode 100644 index 00000000..230a1bce --- /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) { + word32 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..864d25ef --- /dev/null +++ b/pkcs7/pkcs7-verify.c @@ -0,0 +1,77 @@ +#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; + + (void)argc; + (void)argv; + +#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); + + if (rc != derSz) { + printf("Failed to read der file!\n"); + return -1; + } + } + + 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 00000000..e1e6280c Binary files /dev/null and b/pkcs7/signed.p7s differ diff --git a/signature/firmware_sign/Makefile b/signature/firmware_sign/Makefile deleted file mode 100644 index eae685f2..00000000 --- a/signature/firmware_sign/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -CC=gcc -CFLAGS=-Wall -LIBS=-lwolfssl - -all:eccsign - -eccsign:eccsign.o - $(CC) -o $@ $(LIBS) $^ $(CFLAGS) - -.PHONY: clean all - -clean: - rm -f *.o eccsign diff --git a/signature/firmware_sign/README.md b/signature/firmware_sign/README.md deleted file mode 100644 index 24005282..00000000 --- a/signature/firmware_sign/README.md +++ /dev/null @@ -1,31 +0,0 @@ -# Example demonstrating signing a firmware image using ECC - -## Building - -### Build and install wolfSSL - -``` -./configure --enable-ecc && make && sudo make install -``` - -### Build Example - -``` -make -``` - -## Usage - -``` -./eccsign -Firmware Signature 0: Ret 0, HashLen 32, SigLen 71 -Firmware Signature 1: Ret 0, HashLen 32, SigLen 71 -Firmware Signature 2: Ret 0, HashLen 32, SigLen 71 -Firmware Signature 3: Ret 0, HashLen 32, SigLen 72 -Firmware Signature 4: Ret 0, HashLen 32, SigLen 71 -Firmware Signature 5: Ret 0, HashLen 32, SigLen 71 -Firmware Signature 6: Ret 0, HashLen 32, SigLen 71 -Firmware Signature 7: Ret 0, HashLen 32, SigLen 70 -Firmware Signature 8: Ret 0, HashLen 32, SigLen 70 -Firmware Signature 9: Ret 0, HashLen 32, SigLen 70 -```