From 7ad19a30a4fd6c53effa892a17ad978aacb8f3a6 Mon Sep 17 00:00:00 2001 From: Thom Wiggers Date: Mon, 4 Mar 2019 15:12:38 +0100 Subject: [PATCH] First start of windows test support --- crypto_sign/dilithium-iii/clean/api.h | 1 + test/Makefile.Microsoft_nmake | 20 +++++++++++------- test/crypto_sign/functest.c | 10 ++++----- test/crypto_sign/testvectors.c | 1 + test/helpers.py | 30 +++++++++++++++++++++++---- test/test_dynamic_memory.py | 3 +-- test/test_format.py | 4 +++- test/test_functest.py | 18 +++++++++++----- 8 files changed, 63 insertions(+), 24 deletions(-) diff --git a/crypto_sign/dilithium-iii/clean/api.h b/crypto_sign/dilithium-iii/clean/api.h index 74effc3c..c6e80d95 100644 --- a/crypto_sign/dilithium-iii/clean/api.h +++ b/crypto_sign/dilithium-iii/clean/api.h @@ -1,4 +1,5 @@ #ifndef API_H +#include #define API_H #include diff --git a/test/Makefile.Microsoft_nmake b/test/Makefile.Microsoft_nmake index c37a727e..52616574 100644 --- a/test/Makefile.Microsoft_nmake +++ b/test/Makefile.Microsoft_nmake @@ -1,7 +1,7 @@ # This Makefile can be used with Microsoft Visual Studio's nmake using the command: # nmake /f Makefile.Microsoft_nmake -# override as desired +# override as desired, use /E # vim: set ts=4 sw=4 et: TYPE=kem SCHEME=kyber768 @@ -31,17 +31,23 @@ clean-scheme: nmake /f Makefile.Microsoft_nmake clean cd ..\..\..\test -$(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\randombytes.obj - -MKDIR $(DEST_DIR) - $(CC) /c crypto_$(TYPE)\functest.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) - LINK.EXE /OUT:$@ functest.obj $(COMMON_OBJECTS_NOPATH) randombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib Advapi32.lib +functest: $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe -$(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).EXE: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\notrandombytes.obj +testvectors: $(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).exe + +$(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\randombytes.obj -MKDIR $(DEST_DIR) + -DEL functest.obj + $(CC) /c crypto_$(TYPE)\functest.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) + LINK.EXE /OUT:$@ functest.obj $(COMMON_OBJECTS_NOPATH) notrandombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib Advapi32.lib + +$(DEST_DIR)\testvectors_$(SCHEME)_$(IMPLEMENTATION).exe: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\notrandombytes.obj + -MKDIR $(DEST_DIR) + -DEL testvectors.obj $(CC) /c crypto_$(TYPE)\testvectors.c $(CFLAGS) /I $(SCHEME_DIR) /DPQCLEAN_NAMESPACE=PQCLEAN_$(SCHEME_UPPERCASE)_$(IMPLEMENTATION_UPPERCASE) LINK.EXE /OUT:$@ testvectors.obj $(COMMON_OBJECTS_NOPATH) notrandombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib clean: -DEL functest.obj testvectors.obj -DEL $(COMMON_OBJECTS_NOPATH) randombytes.obj notrandombytes.obj - -DEL $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE + -DEL $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe diff --git a/test/crypto_sign/functest.c b/test/crypto_sign/functest.c index 60ea57c2..42a73cf6 100644 --- a/test/crypto_sign/functest.c +++ b/test/crypto_sign/functest.c @@ -98,9 +98,9 @@ static int test_sign(void) { // twice if ((returncode = crypto_sign_open(sm + 8, &mlen, sm + 8, smlen, pk + 8)) != 0) { - printf("ERROR Signature did not verify correctly!\n"); + fprintf(stderr, "ERROR Signature did not verify correctly!\n"); if (returncode > 0) { - puts("ERROR return code should be < 0 on failure"); + fprintf(stderr, "ERROR return code should be < 0 on failure"); } return 1; } @@ -109,7 +109,7 @@ static int test_sign(void) { check_canary(sk) || check_canary(sk + CRYPTO_SECRETKEYBYTES + 8) || check_canary(sm) || check_canary(sm + MLEN + CRYPTO_BYTES + 8) || check_canary(m) || check_canary(m + MLEN + 8)) { - printf("ERROR canary overwritten\n"); + fprintf(stderr, "ERROR canary overwritten\n"); return 1; } } @@ -143,9 +143,9 @@ static int test_wrong_pk(void) { // twice returncode = crypto_sign_open(sm, &mlen, sm, smlen, pk2); if (!returncode) { - printf("ERROR Signature did verify correctly under wrong public key!\n"); + fprintf(stderr, "ERROR Signature did verify correctly under wrong public key!\n"); if (returncode > 0) { - puts("ERROR return code should be < 0"); + fprintf(stderr, "ERROR return code should be < 0"); } return 1; } diff --git a/test/crypto_sign/testvectors.c b/test/crypto_sign/testvectors.c index 8388d8c1..dcbc4e38 100644 --- a/test/crypto_sign/testvectors.c +++ b/test/crypto_sign/testvectors.c @@ -32,6 +32,7 @@ int main(void) { uint8_t mi[MAXMLEN]; uint8_t sm[MAXMLEN + CRYPTO_BYTES]; + size_t smlen; size_t mlen; diff --git a/test/helpers.py b/test/helpers.py index 09a20985..db984484 100644 --- a/test/helpers.py +++ b/test/helpers.py @@ -1,5 +1,7 @@ +import functools import os import subprocess +import unittest def run_subprocess(command, working_dir='.', env=None, expected_returncode=0): @@ -15,6 +17,7 @@ def run_subprocess(command, working_dir='.', env=None, expected_returncode=0): # Note we need to capture stdout/stderr from the subprocess, # then print it, which nose/unittest will then capture and # buffer appropriately + print(working_dir + " > " + " ".join(command)) result = subprocess.run( command, stdout=subprocess.PIPE, @@ -22,7 +25,6 @@ def run_subprocess(command, working_dir='.', env=None, expected_returncode=0): cwd=working_dir, env=env, ) - print(working_dir + " > " + " ".join(command)) print(result.stdout.decode('utf-8')) assert(result.returncode == expected_returncode) return result.stdout.decode('utf-8') @@ -35,13 +37,33 @@ def make(*args, working_dir='.', env=None, **kwargs): Usage: make('clean', 'targetb', SCHEME='bla') """ - make_command = 'make' + if os.name == 'nt': + make_command = ['nmake', '/f', 'Makefile.Microsoft_nmake', '/E'] + # we need SCHEME_UPPERCASE and IMPLEMENTATION_UPPERCASE with nmake + for envvar in ['IMPLEMENTATION', 'SCHEME']: + if envvar in kwargs: + kwargs['{}_UPPERCASE'.format(envvar)] = kwargs[envvar].upper().replace('-', '') + else: + make_command = ['make'] + return run_subprocess( [ - make_command, - *args, + *make_command, *['{}={}'.format(k, v) for k, v in kwargs.items()], + *args, ], working_dir=working_dir, env=env, ) + + +def skip_windows(message="This test is not supported on Windows"): + def wrapper(f): + @functools.wraps(f) + def skip_windows(*args, **kwargs): + raise unittest.SkipTest(message) + if os.name == 'nt': + return skip_windows + else: + return f + return wrapper \ No newline at end of file diff --git a/test/test_dynamic_memory.py b/test/test_dynamic_memory.py index f2fbb698..8853eaea 100644 --- a/test/test_dynamic_memory.py +++ b/test/test_dynamic_memory.py @@ -9,8 +9,6 @@ import unittest def test_dynamic_memory(): - if sys.platform not in ['linux', 'darwin']: - raise unittest.SkipTest() for scheme in pqclean.Scheme.all_schemes(): for implementation in scheme.implementations: # Keep this loop outside, to allow multiple assertions @@ -18,6 +16,7 @@ def test_dynamic_memory(): yield (check_dynamic_memory, implementation, function) +@helpers.skip_windows() def check_dynamic_memory(implementation, function): # 'make' will take care of not rebuilding existing library files helpers.make(working_dir=implementation.path()) diff --git a/test/test_format.py b/test/test_format.py index 6dc92084..bcc08f66 100644 --- a/test/test_format.py +++ b/test/test_format.py @@ -2,7 +2,7 @@ import os from glob import glob import pqclean -from helpers import run_subprocess +from helpers import run_subprocess, skip_windows def test_formatting(): @@ -11,6 +11,8 @@ def test_formatting(): yield check_format, implementation +@skip_windows(message="This test needs to be amended to work with Windows " + "installations of astyle") def check_format(implementation: pqclean.Implementation): cfiles = glob(os.path.join(implementation.path(), '*.c')) hfiles = glob(os.path.join(implementation.path(), '*.h')) diff --git a/test/test_functest.py b/test/test_functest.py index 0b0e3d9e..1ec92a8d 100644 --- a/test/test_functest.py +++ b/test/test_functest.py @@ -24,17 +24,22 @@ def test_functest_sanitizers(): def check_functest(implementation): - helpers.make(TYPE=implementation.scheme.type, + helpers.make(#'functest', + TYPE=implementation.scheme.type, SCHEME=implementation.scheme.name, IMPLEMENTATION=implementation.name, working_dir=os.path.join('..', 'test')) helpers.run_subprocess( - ['./functest_{}_{}'.format(implementation.scheme.name, - implementation.name)], + [os.path.join('..', 'bin', 'functest_{}_{}{}'.format( + implementation.scheme.name, + implementation.name, + '.exe' if os.name == 'nt' else '' + ))], os.path.join('..', 'bin'), ) +@helpers.skip_windows def check_functest_sanitizers(implementation): env = None if platform.machine() == 'ppc' and os.environ.get('CC', 'gcc') == 'clang': @@ -51,8 +56,11 @@ def check_functest_sanitizers(implementation): working_dir=os.path.join('..', 'test'), env=env) helpers.run_subprocess( - ['./functest_{}_{}'.format(implementation.scheme.name, - implementation.name)], + [os.path.join('..', 'bin', 'functest_{}_{}{}'.format( + implementation.scheme.name, + implementation.name, + '.exe' if os.name == 'nt' else '' + ))], os.path.join('..', 'bin'), env=env, )