From 11a2a451939cf09fd30b46bc9b3d4a5bce8283f3 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Tue, 5 Feb 2019 11:02:07 +0100 Subject: [PATCH 01/19] Add names to builds --- .travis.yml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 01884e66..d5685c9e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,7 +4,8 @@ dist: xenial matrix: include: - - os: linux + - name: "Linux + GCC + Linting + Metadata" + os: linux compiler: gcc env: - MAKETARGET="test-all tidy-all check-format check-metadata check-license-files" @@ -15,7 +16,8 @@ matrix: - python3 - python3-setuptools - python3-pip - - os: linux + - name: "Linux + Clang" + os: linux compiler: clang env: - MAKETARGET=test-all @@ -26,12 +28,14 @@ matrix: - python3 - python3-setuptools - python3-pip - - os: osx + - name: "MacOS + Clang" + os: osx osx_image: xcode10.1 compiler: clang env: - MAKETARGET=test-all - - os: osx + - name: "MacOS + GCC8" + os: osx osx_image: xcode10.1 compiler: gcc addons: From a8aa346912357d50804908299ec8cb7c9c16b7e7 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Tue, 5 Feb 2019 11:03:10 +0100 Subject: [PATCH 02/19] Use python3-yaml instead of pip on Linux. --- .travis.yml | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index d5685c9e..6448a838 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,10 +12,9 @@ matrix: addons: apt: packages: - - valgrind - python3 - - python3-setuptools - - python3-pip + - python3-yaml + - valgrind - name: "Linux + Clang" os: linux compiler: clang @@ -24,14 +23,15 @@ matrix: addons: apt: packages: - - valgrind - python3 - - python3-setuptools - - python3-pip + - python3-yaml + - valgrind - name: "MacOS + Clang" os: osx osx_image: xcode10.1 compiler: clang + before_install: + - pip3 install -r requirements.txt env: - MAKETARGET=test-all - name: "MacOS + GCC8" @@ -42,13 +42,11 @@ matrix: homebrew: packages: - gcc@8 + before_install: + - pip3 install -r requirements.txt env: - MAKETARGET=test-all -before_install: - - python3 --version - - pip3 install -r requirements.txt - script: - make ${MAKETARGET} From a9e7e904d323089b6cd4401c656dc822da18e326 Mon Sep 17 00:00:00 2001 From: Joost Rijneveld Date: Tue, 5 Feb 2019 11:04:19 +0100 Subject: [PATCH 03/19] Run tests on userspace-emulated PowerPC This has the downside of not supporting running tests on Valgrind, see the discussion in issue #15. However, this does test quite a lot already. This uses the docker container defined in https://github.com/thomwiggers/debian-unstable-powerpc/. Co-authored-by: Thom Wiggers --- .travis.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.travis.yml b/.travis.yml index 6448a838..db8f4cac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,6 +26,15 @@ matrix: - python3 - python3-yaml - valgrind + - name: "Run tests on qemu-ppc" + os: linux + services: docker + env: + - MAKETARGET="run-functest-all run-testvectors-all run-sanitizer-all run-symbol-namespace-all" + script: # TODO: should we do this in a Dockerfile instead? + - docker run --rm --privileged multiarch/qemu-user-static:register --reset + - docker run --rm -v `pwd`:`pwd` -w `pwd` "twiggers/debian-sid-powerpc" /bin/bash -c "uname -a && + make ${MAKETARGET}" - name: "MacOS + Clang" os: osx osx_image: xcode10.1 From 59f92730cfd94b38a578dee3c86069e28f2da18c Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Wed, 6 Feb 2019 17:20:31 +0100 Subject: [PATCH 04/19] Include an actually random version of randombytes --- Makefile | 12 +- common/notrandombytes.c | 7 +- common/randombytes.c | 323 ++++++++++++++++++++++++++++++++++++++++ common/randombytes.h | 8 +- 4 files changed, 342 insertions(+), 8 deletions(-) create mode 100644 common/randombytes.c diff --git a/Makefile b/Makefile index df4c1ca6..cccc5989 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -g $(EXTRAFLAGS) ALL_SCHEMES=$(filter-out crypto_%.c, $(wildcard crypto_*/*)) +COMMON_FILES = common/fips202.c common/sha2.c +RANDOM_IMPL = common/randombytes.c default: help @@ -19,8 +21,8 @@ bin/functest_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))functest.c $(wildcard -iquote "./common/" \ -iquote "$(SCHEME)/clean/" \ -o bin/functest_$(subst /,_,$(SCHEME)) \ - common/*.c \ - $(SCHEME)/clean/*.c \ + $(COMMON_FILES) \ + $(RANDOM_IMPL) \ $< .PHONY: functest @@ -45,7 +47,8 @@ bin/sanitizer_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))functest.c $(wildcard -iquote "./common/" \ -iquote "$(SCHEME)/clean/" \ -o bin/sanitizer_$(subst /,_,$(SCHEME)) \ - common/*.c \ + $(COMMON_FILES) \ + $(RANDOM_IMPL) \ $(SCHEME)/clean/*.c \ $< @@ -59,7 +62,8 @@ bin/testvectors_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))testvectors.c $(wil -iquote "./common/" \ -iquote "$(SCHEME)/clean/" \ -o bin/testvectors_$(subst /,_,$(SCHEME)) \ - common/*.c \ + $(COMMON_FILES) \ + common/notrandombytes.c \ $(SCHEME)/clean/*.c \ $< diff --git a/common/notrandombytes.c b/common/notrandombytes.c index 43f16e57..bd6dffdb 100644 --- a/common/notrandombytes.c +++ b/common/notrandombytes.c @@ -56,7 +56,7 @@ static void surf(void) { } } -void randombytes(uint8_t *x, uint64_t xlen) { +int randombytes(uint8_t *buf, size_t xlen) { while (xlen > 0) { if (!outleft) { if (!++in[0]) { @@ -69,8 +69,9 @@ void randombytes(uint8_t *x, uint64_t xlen) { surf(); outleft = 8; } - *x = out[--outleft]; - ++x; + *buf = out[--outleft]; + ++buf; --xlen; } + return 0; } diff --git a/common/randombytes.c b/common/randombytes.c new file mode 100644 index 00000000..fac65577 --- /dev/null +++ b/common/randombytes.c @@ -0,0 +1,323 @@ +/* +The MIT License + +Copyright (c) 2017 Daan Sprenkels + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ + +// In the case that are compiling on linux, we need to define _GNU_SOURCE +// *before* randombytes.h is included. Otherwise SYS_getrandom will not be +// declared. +#if defined(__linux__) +# define _GNU_SOURCE +#endif /* defined(__linux__) */ + +#include "randombytes.h" + +#if defined(_WIN32) +/* Windows */ +# include +# include /* CryptAcquireContext, CryptGenRandom */ +#endif /* defined(_WIN32) */ + + +#if defined(__linux__) +/* Linux */ +// We would need to include , but not every target has access +// to the linux headers. We only need RNDGETENTCNT, so we instead inline it. +// RNDGETENTCNT is originally defined in `include/uapi/linux/random.h` in the +// linux repo. +# define RNDGETENTCNT 0x80045200 + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +// We need SSIZE_MAX as the maximum read len from /dev/urandom +# if !defined(SSIZE_MAX) +# define SSIZE_MAX (SIZE_MAX / 2 - 1) +# endif /* defined(SSIZE_MAX) */ + +#endif /* defined(__linux__) */ + + +#if defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) +/* Dragonfly, FreeBSD, NetBSD, OpenBSD (has arc4random) */ +# include +# if defined(BSD) +# include +# endif +#endif + +#if defined(__EMSCRIPTEN__) +# include +# include +# include +# include +#endif /* defined(__EMSCRIPTEN__) */ + + +#if defined(_WIN32) +static int randombytes_win32_randombytes(void* buf, const size_t n) +{ + HCRYPTPROV ctx; + BOOL tmp; + + tmp = CryptAcquireContext(&ctx, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT); + if (tmp == FALSE) return -1; + + tmp = CryptGenRandom(ctx, n, (BYTE*) buf); + if (tmp == FALSE) return -1; + + tmp = CryptReleaseContext(ctx, 0); + if (tmp == FALSE) return -1; + + return 0; +} +#endif /* defined(_WIN32) */ + + +#if defined(__linux__) && defined(SYS_getrandom) +static int randombytes_linux_randombytes_getrandom(void *buf, size_t n) +{ + /* I have thought about using a separate PRF, seeded by getrandom, but + * it turns out that the performance of getrandom is good enough + * (250 MB/s on my laptop). + */ + size_t offset = 0, chunk; + int ret; + while (n > 0) { + /* getrandom does not allow chunks larger than 33554431 */ + chunk = n <= 33554431 ? n : 33554431; + do { + ret = syscall(SYS_getrandom, (char *)buf + offset, chunk, 0); + } while (ret == -1 && errno == EINTR); + if (ret < 0) { + return ret; + } + offset += ret; + n -= ret; + } + assert(n == 0); + return 0; +} +#endif /* defined(__linux__) && defined(SYS_getrandom) */ + + +#if defined(__linux__) && !defined(SYS_getrandom) +static int randombytes_linux_read_entropy_ioctl(int device, int *entropy) +{ + return ioctl(device, RNDGETENTCNT, entropy); +} + +static int randombytes_linux_read_entropy_proc(FILE *stream, int *entropy) +{ + int retcode; + do { + rewind(stream); + retcode = fscanf(stream, "%d", entropy); + } while (retcode != 1 && errno == EINTR); + if (retcode != 1) { + return -1; + } + return 0; +} + +static int randombytes_linux_wait_for_entropy(int device) +{ + /* We will block on /dev/random, because any increase in the OS' entropy + * level will unblock the request. I use poll here (as does libsodium), + * because we don't *actually* want to read from the device. */ + enum { IOCTL, PROC } strategy = IOCTL; + const int bits = 128; + struct pollfd pfd; + int fd; + FILE *proc_file; + int retcode, retcode_error = 0; // Used as return codes throughout this function + int entropy = 0; + + /* If the device has enough entropy already, we will want to return early */ + retcode = randombytes_linux_read_entropy_ioctl(device, &entropy); + if (retcode != 0 && errno == ENOTTY) { + /* The ioctl call on /dev/urandom has failed due to a ENOTTY (i.e. + * unsupported action). We will fall back to reading from + * `/proc/sys/kernel/random/entropy_avail`. This is obviously less + * ideal, but at this point it seems we have no better option. */ + strategy = PROC; + // Open the entropy count file + proc_file = fopen("/proc/sys/kernel/random/entropy_avail", "r"); + } else if (retcode != 0) { + // Unrecoverable ioctl error + return -1; + } + if (entropy >= bits) { + return 0; + } + + do { + fd = open("/dev/random", O_RDONLY); + } while (fd == -1 && errno == EINTR); /* EAGAIN will not occur */ + if (fd == -1) { + /* Unrecoverable IO error */ + return -1; + } + + pfd.fd = fd; + pfd.events = POLLIN; + for (;;) { + retcode = poll(&pfd, 1, -1); + if (retcode == -1 && (errno == EINTR || errno == EAGAIN)) { + continue; + } else if (retcode == 1) { + if (strategy == IOCTL) { + retcode = randombytes_linux_read_entropy_ioctl(device, &entropy); + } else if (strategy == PROC) { + retcode = randombytes_linux_read_entropy_proc(proc_file, &entropy); + } else { + return -1; // Unreachable + } + + if (retcode != 0) { + // Unrecoverable I/O error + retcode_error = retcode; + break; + } + if (entropy >= bits) { + break; + } + } else { + // Unreachable: poll() should only return -1 or 1 + retcode_error = -1; + break; + } + } + do { + retcode = close(fd); + } while (retcode == -1 && errno == EINTR); + if (strategy == PROC) { + do { + retcode = fclose(proc_file); + } while (retcode == -1 && errno == EINTR); + } + if (retcode_error != 0) { + return retcode_error; + } + return retcode; +} + + +static int randombytes_linux_randombytes_urandom(void *buf, size_t n) +{ + int fd; + size_t offset = 0, count; + ssize_t tmp; + do { + fd = open("/dev/urandom", O_RDONLY); + } while (fd == -1 && errno == EINTR); + if (fd == -1) return -1; + if (randombytes_linux_wait_for_entropy(fd) == -1) return -1; + + while (n > 0) { + count = n <= SSIZE_MAX ? n : SSIZE_MAX; + tmp = read(fd, (char *)buf + offset, count); + if (tmp == -1 && (errno == EAGAIN || errno == EINTR)) { + continue; + } + if (tmp == -1) return -1; /* Unrecoverable IO error */ + offset += tmp; + n -= tmp; + } + assert(n == 0); + return 0; +} +#endif /* defined(__linux__) && !defined(SYS_getrandom) */ + + +#if defined(BSD) +static int randombytes_bsd_randombytes(void *buf, size_t n) +{ + arc4random_buf(buf, n); + return 0; +} +#endif /* defined(BSD) */ + + +#if defined(__EMSCRIPTEN__) +static int randombytes_js_randombytes_nodejs(void *buf, size_t n) { + const int ret = EM_ASM_INT({ + var crypto; + try { + crypto = require('crypto'); + } catch (error) { + return -2; + } + try { + writeArrayToMemory(crypto.randomBytes($1), $0); + return 0; + } catch (error) { + return -1; + } + }, buf, n); + switch (ret) { + case 0: + return 0; + case -1: + errno = EINVAL; + return -1; + case -2: + errno = ENOSYS; + return -1; + } + assert(false); // Unreachable +} +#endif /* defined(__EMSCRIPTEN__) */ + + +int randombytes(uint8_t *buf, size_t n) +{ +#if defined(__EMSCRIPTEN__) + return randombytes_js_randombytes_nodejs(buf, n); +#elif defined(__linux__) +# if defined(SYS_getrandom) + /* Use getrandom system call */ + return randombytes_linux_randombytes_getrandom(buf, n); +# else + /* When we have enough entropy, we can read from /dev/urandom */ + return randombytes_linux_randombytes_urandom(buf, n); +# endif +#elif defined(BSD) + /* Use arc4random system call */ + return randombytes_bsd_randombytes(buf, n); +#elif defined(_WIN32) + /* Use windows API */ + return randombytes_win32_randombytes(buf, n); +#else +# error "randombytes(...) is not supported on this platform" +#endif +} diff --git a/common/randombytes.h b/common/randombytes.h index f99d033e..4ab2fd5e 100644 --- a/common/randombytes.h +++ b/common/randombytes.h @@ -2,6 +2,12 @@ #define RANDOMBYTES_H #include -void randombytes(uint8_t *x, uint64_t xlen); +#ifdef _WIN32 +# include +#else +# include +#endif + +int randombytes(uint8_t *buf, size_t xlen); #endif From 70c5e535bb9ae8d43b102d5faad8d09b18a7f069 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Thu, 7 Feb 2019 09:59:28 +0100 Subject: [PATCH 05/19] Fix accidentally deleted line I shouldve run `make -B test-all`. --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index cccc5989..a99e7a90 100644 --- a/Makefile +++ b/Makefile @@ -21,6 +21,7 @@ bin/functest_$(subst /,_,$(SCHEME)): test/$(dir $(SCHEME))functest.c $(wildcard -iquote "./common/" \ -iquote "$(SCHEME)/clean/" \ -o bin/functest_$(subst /,_,$(SCHEME)) \ + $(SCHEME)/clean/*.c \ $(COMMON_FILES) \ $(RANDOM_IMPL) \ $< From da2667a846c3f8d8ddb4e9c78051f254b6fc67a0 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Fri, 1 Feb 2019 20:58:26 -0500 Subject: [PATCH 06/19] Add local Makefile for kyber768 --- crypto_kem/kyber768/clean/Makefile | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 crypto_kem/kyber768/clean/Makefile diff --git a/crypto_kem/kyber768/clean/Makefile b/crypto_kem/kyber768/clean/Makefile new file mode 100644 index 00000000..6551de20 --- /dev/null +++ b/crypto_kem/kyber768/clean/Makefile @@ -0,0 +1,14 @@ +LIB=libkyber768.so +OBJECTS=cbd.o indcpa.o kem.o kex.o ntt.o poly.o polyvec.o precomp.o reduce.o verify.o + +COMMON_DIR=../../../common +COMMON_OBJECTS=$(COMMON_DIR)/fips202.o $(COMMON_DIR)/notrandombytes.o + +CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -fPIC -g -I$(COMMON_DIR) $(EXTRAFLAGS) + +$(LIB): $(OBJECTS) $(COMMON_OBJECTS) + $(CC) -shared -o $@ $(OBJECTS) $(COMMON_OBJECTS) + +clean: + $(RM) $(OBJECTS) $(COMMON_OBJECTS) + $(RM) $(LIB) From 84d8d5a6c2dc187072903f52400d9602982beee2 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 12:22:58 -0500 Subject: [PATCH 07/19] Clean up Makefile --- crypto_kem/kyber768/clean/Makefile | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/crypto_kem/kyber768/clean/Makefile b/crypto_kem/kyber768/clean/Makefile index 6551de20..e802b821 100644 --- a/crypto_kem/kyber768/clean/Makefile +++ b/crypto_kem/kyber768/clean/Makefile @@ -1,14 +1,13 @@ -LIB=libkyber768.so -OBJECTS=cbd.o indcpa.o kem.o kex.o ntt.o poly.o polyvec.o precomp.o reduce.o verify.o +LIB=kyber768_clean.a -COMMON_DIR=../../../common -COMMON_OBJECTS=$(COMMON_DIR)/fips202.o $(COMMON_DIR)/notrandombytes.o +SOURCES=$(wildcard *.c) +OBJECTS=$(patsubst %.c,%.o,$(SOURCES)) -CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -fPIC -g -I$(COMMON_DIR) $(EXTRAFLAGS) +CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -I../../../common $(EXTRAFLAGS) -$(LIB): $(OBJECTS) $(COMMON_OBJECTS) - $(CC) -shared -o $@ $(OBJECTS) $(COMMON_OBJECTS) +$(LIB): $(OBJECTS) + $(AR) -r $@ $(OBJECTS) clean: - $(RM) $(OBJECTS) $(COMMON_OBJECTS) + $(RM) $(OBJECTS) $(RM) $(LIB) From 4a387d7896e2c055024548e996c8c6c794a20ea5 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 12:41:55 -0500 Subject: [PATCH 08/19] Rename GNU Makefile --- crypto_kem/kyber768/clean/{Makefile => Makefile.GNU_make} | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) rename crypto_kem/kyber768/clean/{Makefile => Makefile.GNU_make} (71%) diff --git a/crypto_kem/kyber768/clean/Makefile b/crypto_kem/kyber768/clean/Makefile.GNU_make similarity index 71% rename from crypto_kem/kyber768/clean/Makefile rename to crypto_kem/kyber768/clean/Makefile.GNU_make index e802b821..457d0a83 100644 --- a/crypto_kem/kyber768/clean/Makefile +++ b/crypto_kem/kyber768/clean/Makefile.GNU_make @@ -5,9 +5,11 @@ OBJECTS=$(patsubst %.c,%.o,$(SOURCES)) CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -I../../../common $(EXTRAFLAGS) +all: $(LIB) + $(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) + $(AR) -r $@ $(OBJECTS) clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) + $(RM) $(OBJECTS) + $(RM) $(LIB) From e98d0536231ad81b8faa3597bb052dcefa997075 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 12:46:50 -0500 Subject: [PATCH 09/19] Rename --- crypto_kem/kyber768/clean/{Makefile.GNU_make => GNUmakefile} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename crypto_kem/kyber768/clean/{Makefile.GNU_make => GNUmakefile} (91%) diff --git a/crypto_kem/kyber768/clean/Makefile.GNU_make b/crypto_kem/kyber768/clean/GNUmakefile similarity index 91% rename from crypto_kem/kyber768/clean/Makefile.GNU_make rename to crypto_kem/kyber768/clean/GNUmakefile index 457d0a83..27703b5a 100644 --- a/crypto_kem/kyber768/clean/Makefile.GNU_make +++ b/crypto_kem/kyber768/clean/GNUmakefile @@ -1,4 +1,4 @@ -LIB=kyber768_clean.a +LIB=libkyber768_clean.a SOURCES=$(wildcard *.c) OBJECTS=$(patsubst %.c,%.o,$(SOURCES)) From 7c0ecc0cdb31a54f3270bd37667dc339aad6ade0 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 18:37:50 -0500 Subject: [PATCH 10/19] Create nmake file for building on Windows and fix compilation error --- .gitignore | 4 ++++ crypto_kem/kyber768/clean/Makefile.Microsoft_nmake | 14 ++++++++++++++ crypto_kem/kyber768/clean/indcpa.c | 2 +- 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 crypto_kem/kyber768/clean/Makefile.Microsoft_nmake diff --git a/.gitignore b/.gitignore index e0b99a16..3794b9c0 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ bin/ *.a *.so *~ + +# Object and library files on Windows +*.lib +*.obj diff --git a/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake new file mode 100644 index 00000000..13f3d73a --- /dev/null +++ b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake @@ -0,0 +1,14 @@ +LIB=libkyber768_clean.lib + +OBJECTS=cbd.obj indcpa.obj kem.obj kex.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj + +CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now + +all: $(LIB) + +$(LIB): $(OBJECTS) + LIB.EXE /OUT:$@ $** + +clean: + DEL $(OBJECTS) + DEL $(LIB) diff --git a/crypto_kem/kyber768/clean/indcpa.c b/crypto_kem/kyber768/clean/indcpa.c index 528851c7..210ad1e9 100644 --- a/crypto_kem/kyber768/clean/indcpa.c +++ b/crypto_kem/kyber768/clean/indcpa.c @@ -133,7 +133,7 @@ void PQCLEAN_KYBER768_gen_matrix(polyvec *a, const unsigned char *seed, uint16_t val; unsigned int nblocks; const unsigned int maxnblocks = 4; - uint8_t buf[SHAKE128_RATE * maxnblocks]; + uint8_t buf[SHAKE128_RATE * /* maxnblocks = */ 4]; int i, j; uint64_t state[25]; // SHAKE state unsigned char extseed[KYBER_SYMBYTES + 2]; From b0963308081169ec7e7faa91097f3e3e92d27b2a Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 19:26:18 -0500 Subject: [PATCH 11/19] First attempt at appveyor configuration --- appveyor.yml | 12 ++++++++++++ scripts_windows/build_all.bat | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 appveyor.yml create mode 100644 scripts_windows/build_all.bat diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 00000000..bbfc9e6a --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,12 @@ +version: 1.0.{build} + +image: Visual Studio 2017 + +build: + verbosity: minimal + +init: + - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" + +build_script: + - scripts_windows\build_all.bat diff --git a/scripts_windows/build_all.bat b/scripts_windows/build_all.bat new file mode 100644 index 00000000..44cec721 --- /dev/null +++ b/scripts_windows/build_all.bat @@ -0,0 +1,19 @@ +@ECHO OFF +SETLOCAL +SET EL=0 + +REM CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" +REM IF ERRORLEVEL 1 SET EL=1 + +FOR /D %%K IN (crypto_kem\*) DO ( + FOR /D %%L IN (%%K\*) DO ( + cd %%L + nmake /f Makefile.Microsoft_nmake clean + IF ERRORLEVEL 1 SET EL=2 + nmake /f Makefile.Microsoft_nmake + IF ERRORLEVEL 1 SET EL=3 + cd ..\..\.. + ) +) + +EXIT /b %EL% From 5d931897e632ec0ba2ae0ce638c6faf9b7a31f75 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 20:22:59 -0500 Subject: [PATCH 12/19] Temporary check that errors really make the build fail --- crypto_kem/kyber768/clean/Makefile.Microsoft_nmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake index 13f3d73a..d6f0fab3 100644 --- a/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake +++ b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake @@ -2,7 +2,7 @@ LIB=libkyber768_clean.lib OBJECTS=cbd.obj indcpa.obj kem.obj kex.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj -CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now +CFLAGS=/I ..\..\..\common /W4 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now all: $(LIB) From 2d684ea323dd335004f0f7a666d5d743f8c7d22b Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 20:24:26 -0500 Subject: [PATCH 13/19] Revert temporary error --- crypto_kem/kyber768/clean/Makefile.Microsoft_nmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake index d6f0fab3..13f3d73a 100644 --- a/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake +++ b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake @@ -2,7 +2,7 @@ LIB=libkyber768_clean.lib OBJECTS=cbd.obj indcpa.obj kem.obj kex.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj -CFLAGS=/I ..\..\..\common /W4 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now +CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now all: $(LIB) From 46ba607ebaf9524bbdad8191d550144cb6696ac7 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 20:53:21 -0500 Subject: [PATCH 14/19] Update README.md with information about Makefiles and Windows CI --- README.md | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f0efbeeb..2abd1e0c 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,13 @@ # PQClean [![Build Status](https://travis-ci.com/PQClean/PQClean.svg?branch=master)](https://travis-ci.com/PQClean/PQClean) +[![Build status](https://ci.appveyor.com/api/projects/status/186ky7yb9mlqj3io?svg=true)](https://ci.appveyor.com/project/PQClean/pqclean) **PQClean**, in short, is an effort to collect **clean** implementations of the post-quantum schemes that are in the [NIST post-quantum project](https://csrc.nist.gov/projects/post-quantum-cryptography). The goal of PQClean is to provide *standalone implementations* that + * can easily be integrated into libraries such as [liboqs](https://openquantumsafe.org/#liboqs) or [libpqcrypto](https://libpqcrypto.org/); * can efficiently upstream into higher-level protocol integration efforts such as [Open Quantum Safe](https://openquantumsafe.org/#integrations); * can easily be integrated into benchmarking frameworks such as [SUPERCOP](https://bench.cr.yp.to/supercop.html); @@ -15,6 +17,7 @@ The goal of PQClean is to provide *standalone implementations* that * are suitable targets for formal verification. What PQClean is **not** aiming for is + * a build system producing an integrated library of all schemes; * including benchmarking of implementations; and * including integration into higher-level applications or protocols. @@ -33,8 +36,8 @@ _The checking of items on this list is still being developed. Checked items shou * [x] Consistent test vectors across runs * [ ] Consistent test vectors on big-endian and little-endian machines * [ ] Consistent test vectors on 32-bit and 64-bit machines -* [X] No errors/warnings reported by valgrind -* [X] No errors/warnings reported by address sanitizer +* [x] No errors/warnings reported by valgrind +* [x] No errors/warnings reported by address sanitizer * [ ] Only dependencies: * [x] `fips202.c` * [x] `sha2.c` @@ -47,12 +50,12 @@ _The checking of items on this list is still being developed. Checked items shou * [ ] No branching on secret data (dynamically checked using valgrind) * [ ] No access to secret memory locations (dynamically checked using valgrind) * [ ] Separate subdirectories (without symlinks) for each parameter set of each scheme -* [ ] Builds under Linux, MacOS, and Windows +* [x] Builds under Linux, MacOS, and Windows * [x] Linux * [x] MacOS - * [ ] Windows -* [ ] Makefile-based build for each separate scheme -* [ ] Makefile-based build for Windows (`nmake`) + * [x] Windows +* [x] Makefile-based build for each separate scheme +* [x] Makefile-based build for Windows (`nmake`) * [x] All exported symbols are namespaced with `PQCLEAN_SCHEMENAME_` * [x] Each implementation comes with a `LICENSE` file (see below) * [x] Each scheme comes with a `META.yml` file giving details about version of the algorithm, designers @@ -104,6 +107,23 @@ int crypto_sign_signature(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t int crypto_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen, const uint8_t *pk); ``` +## Building PQClean + +As noted above, PQClean is **not** meant to be built as a single library: it is a collection of source code that can be easily integrated into other libraries. The PQClean repository includes various test programs which do build various files, but you should not use the resulting binaries for any purpose. + +## Using source code from PQClean in your own project + +Each implementation directory in PQClean (e.g., crypto\_kem/kyber768\clean) can be extracted for use in your own project. You will need to: + +1. Copy the source code from the implementation's directory into your project. +2. Add the files to your project's build system. +3. Provide instantiations of any of the common cryptographic algorithms used by the implementation. This likely includes `common/randombytes.h` (a cryptographic random number generator), and possibly `common/sha2.h` (the SHA-2 hash function family) and `common/fips202.h` (the SHA-3 hash function family). + +Regarding #2, adding the files to your project's build system, each implementation in PQClean is accompanied by example two makefiles that show how one could build the files for that implementation: + +- The file `GNUmakefile` which can be used with GNU Make. +- The file `Makefile.Microsoft_nmake` which can be used with Visual Studio's nmake. + ## License Each subdirectory containing implementations contains a LICENSE file stating under what license From 19b25d47ed5055a1fa0084cda4ae59a29269cdd4 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 21:02:34 -0500 Subject: [PATCH 15/19] Add Makefiles for dilithium-iii --- crypto_sign/dilithium-iii/clean/GNUmakefile | 15 +++++++++++++++ .../clean/Makefile.Microsoft_nmake | 14 ++++++++++++++ scripts_windows/build_all.bat | 18 ++++++++++-------- 3 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 crypto_sign/dilithium-iii/clean/GNUmakefile create mode 100644 crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake diff --git a/crypto_sign/dilithium-iii/clean/GNUmakefile b/crypto_sign/dilithium-iii/clean/GNUmakefile new file mode 100644 index 00000000..84a65680 --- /dev/null +++ b/crypto_sign/dilithium-iii/clean/GNUmakefile @@ -0,0 +1,15 @@ +LIB=libdilithium-iii_clean.a + +SOURCES=$(wildcard *.c) +OBJECTS=$(patsubst %.c,%.o,$(SOURCES)) + +CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -I../../../common $(EXTRAFLAGS) + +all: $(LIB) + +$(LIB): $(OBJECTS) + $(AR) -r $@ $(OBJECTS) + +clean: + $(RM) $(OBJECTS) + $(RM) $(LIB) diff --git a/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake b/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake new file mode 100644 index 00000000..62dc9eaa --- /dev/null +++ b/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake @@ -0,0 +1,14 @@ +LIB=libdilithium-iii_clean.lib + +OBJECTS=ntt.c packing.c poly.c polyvec.c reduce.c rounding.c sign.c + +CFLAGS=/I ..\..\..\common /W1 /WX + +all: $(LIB) + +$(LIB): $(OBJECTS) + LIB.EXE /OUT:$@ $** + +clean: + DEL $(OBJECTS) + DEL $(LIB) diff --git a/scripts_windows/build_all.bat b/scripts_windows/build_all.bat index 44cec721..19c4ff87 100644 --- a/scripts_windows/build_all.bat +++ b/scripts_windows/build_all.bat @@ -5,14 +5,16 @@ SET EL=0 REM CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" REM IF ERRORLEVEL 1 SET EL=1 -FOR /D %%K IN (crypto_kem\*) DO ( - FOR /D %%L IN (%%K\*) DO ( - cd %%L - nmake /f Makefile.Microsoft_nmake clean - IF ERRORLEVEL 1 SET EL=2 - nmake /f Makefile.Microsoft_nmake - IF ERRORLEVEL 1 SET EL=3 - cd ..\..\.. +FOR /D %%J IN (crypto_kem, crypto_sig) DO ( + FOR /D %%K IN (%%J\*) DO ( + FOR /D %%L IN (%%K\*) DO ( + cd %%L + nmake /f Makefile.Microsoft_nmake clean + IF ERRORLEVEL 1 SET EL=2 + nmake /f Makefile.Microsoft_nmake + IF ERRORLEVEL 1 SET EL=3 + cd ..\..\.. + ) ) ) From 4f14ce17c9fe85937cdfa643c46cde689ed09590 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 21:14:10 -0500 Subject: [PATCH 16/19] Fix Windows build for dilithium-iii --- .../clean/Makefile.Microsoft_nmake | 2 +- scripts_windows/build_all.bat | 18 ++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake b/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake index 62dc9eaa..8bff3abc 100644 --- a/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake +++ b/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake @@ -1,6 +1,6 @@ LIB=libdilithium-iii_clean.lib -OBJECTS=ntt.c packing.c poly.c polyvec.c reduce.c rounding.c sign.c +OBJECTS=ntt.obj packing.obj poly.obj polyvec.obj reduce.obj rounding.obj sign.obj CFLAGS=/I ..\..\..\common /W1 /WX diff --git a/scripts_windows/build_all.bat b/scripts_windows/build_all.bat index 19c4ff87..5b3b3bb2 100644 --- a/scripts_windows/build_all.bat +++ b/scripts_windows/build_all.bat @@ -5,16 +5,14 @@ SET EL=0 REM CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" REM IF ERRORLEVEL 1 SET EL=1 -FOR /D %%J IN (crypto_kem, crypto_sig) DO ( - FOR /D %%K IN (%%J\*) DO ( - FOR /D %%L IN (%%K\*) DO ( - cd %%L - nmake /f Makefile.Microsoft_nmake clean - IF ERRORLEVEL 1 SET EL=2 - nmake /f Makefile.Microsoft_nmake - IF ERRORLEVEL 1 SET EL=3 - cd ..\..\.. - ) +FOR /D %%K IN (crypto_kem\* crypto_sign\*) DO ( + FOR /D %%L IN (%%K\*) DO ( + cd %%L + nmake /f Makefile.Microsoft_nmake clean + IF ERRORLEVEL 1 SET EL=2 + nmake /f Makefile.Microsoft_nmake + IF ERRORLEVEL 1 SET EL=3 + cd ..\..\.. ) ) From 0703346ddc619686d3c8db9ebb29a519d15fdbfb Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Wed, 6 Feb 2019 21:16:56 -0500 Subject: [PATCH 17/19] Remove signature makefiles --- crypto_sign/dilithium-iii/clean/GNUmakefile | 15 --------------- .../dilithium-iii/clean/Makefile.Microsoft_nmake | 14 -------------- scripts_windows/build_all.bat | 2 +- 3 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 crypto_sign/dilithium-iii/clean/GNUmakefile delete mode 100644 crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake diff --git a/crypto_sign/dilithium-iii/clean/GNUmakefile b/crypto_sign/dilithium-iii/clean/GNUmakefile deleted file mode 100644 index 84a65680..00000000 --- a/crypto_sign/dilithium-iii/clean/GNUmakefile +++ /dev/null @@ -1,15 +0,0 @@ -LIB=libdilithium-iii_clean.a - -SOURCES=$(wildcard *.c) -OBJECTS=$(patsubst %.c,%.o,$(SOURCES)) - -CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -I../../../common $(EXTRAFLAGS) - -all: $(LIB) - -$(LIB): $(OBJECTS) - $(AR) -r $@ $(OBJECTS) - -clean: - $(RM) $(OBJECTS) - $(RM) $(LIB) diff --git a/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake b/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake deleted file mode 100644 index 8bff3abc..00000000 --- a/crypto_sign/dilithium-iii/clean/Makefile.Microsoft_nmake +++ /dev/null @@ -1,14 +0,0 @@ -LIB=libdilithium-iii_clean.lib - -OBJECTS=ntt.obj packing.obj poly.obj polyvec.obj reduce.obj rounding.obj sign.obj - -CFLAGS=/I ..\..\..\common /W1 /WX - -all: $(LIB) - -$(LIB): $(OBJECTS) - LIB.EXE /OUT:$@ $** - -clean: - DEL $(OBJECTS) - DEL $(LIB) diff --git a/scripts_windows/build_all.bat b/scripts_windows/build_all.bat index 5b3b3bb2..44cec721 100644 --- a/scripts_windows/build_all.bat +++ b/scripts_windows/build_all.bat @@ -5,7 +5,7 @@ SET EL=0 REM CALL "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" REM IF ERRORLEVEL 1 SET EL=1 -FOR /D %%K IN (crypto_kem\* crypto_sign\*) DO ( +FOR /D %%K IN (crypto_kem\*) DO ( FOR /D %%L IN (%%K\*) DO ( cd %%L nmake /f Makefile.Microsoft_nmake clean From 24e28e34028e70e32ce8199fd16460ab17de80d0 Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Fri, 8 Feb 2019 09:42:53 -0500 Subject: [PATCH 18/19] Use a single Makefile for BSD and GNU Make and add comments --- crypto_kem/kyber768/clean/{GNUmakefile => Makefile} | 6 +++--- crypto_kem/kyber768/clean/Makefile.Microsoft_nmake | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) rename crypto_kem/kyber768/clean/{GNUmakefile => Makefile} (59%) diff --git a/crypto_kem/kyber768/clean/GNUmakefile b/crypto_kem/kyber768/clean/Makefile similarity index 59% rename from crypto_kem/kyber768/clean/GNUmakefile rename to crypto_kem/kyber768/clean/Makefile index 27703b5a..616dcbf3 100644 --- a/crypto_kem/kyber768/clean/GNUmakefile +++ b/crypto_kem/kyber768/clean/Makefile @@ -1,7 +1,7 @@ -LIB=libkyber768_clean.a +# This Makefile has been tested with GNU Make and BSD Make -SOURCES=$(wildcard *.c) -OBJECTS=$(patsubst %.c,%.o,$(SOURCES)) +LIB=libkyber768_clean.a +OBJECTS=cbd.o indcpa.o kem.o kex.o ntt.o poly.o polyvec.o precomp.o reduce.o verify.o CFLAGS=-Wall -Wextra -Wpedantic -Werror -std=c99 -I../../../common $(EXTRAFLAGS) diff --git a/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake index 13f3d73a..af4b6833 100644 --- a/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake +++ b/crypto_kem/kyber768/clean/Makefile.Microsoft_nmake @@ -1,5 +1,7 @@ -LIB=libkyber768_clean.lib +# This Makefile can be used with Microsoft Visual Studio's nmake using the command: +# nmake /f Makefile.Microsoft_nmake +LIB=libkyber768_clean.lib OBJECTS=cbd.obj indcpa.obj kem.obj kex.obj ntt.obj poly.obj polyvec.obj precomp.obj reduce.obj verify.obj CFLAGS=/I ..\..\..\common /W1 /WX # FIXME: ideally would use /W4 instead of /W1, but too many failures in Kyber right now From 361c38a47a77ee0b424e02152fd2d4287900f1cc Mon Sep 17 00:00:00 2001 From: Douglas Stebila Date: Fri, 8 Feb 2019 09:45:50 -0500 Subject: [PATCH 19/19] Update README to refer to common Makefile --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2abd1e0c..eebe2ffd 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ Each implementation directory in PQClean (e.g., crypto\_kem/kyber768\clean) can Regarding #2, adding the files to your project's build system, each implementation in PQClean is accompanied by example two makefiles that show how one could build the files for that implementation: -- The file `GNUmakefile` which can be used with GNU Make. +- The file `Makefile` which can be used with GNU Make, BSD Make, and possibly others. - The file `Makefile.Microsoft_nmake` which can be used with Visual Studio's nmake. ## License