First start of windows test support

This commit is contained in:
Thom Wiggers 2019-03-04 15:12:38 +01:00
parent 4e7415f30d
commit 7ad19a30a4
No known key found for this signature in database
GPG Key ID: 001BB0A7CE26E363
8 changed files with 63 additions and 24 deletions

View File

@ -1,4 +1,5 @@
#ifndef API_H #ifndef API_H
#include <stdint.h>
#define API_H #define API_H
#include <stddef.h> #include <stddef.h>

View File

@ -1,7 +1,7 @@
# This Makefile can be used with Microsoft Visual Studio's nmake using the command: # This Makefile can be used with Microsoft Visual Studio's nmake using the command:
# nmake /f Makefile.Microsoft_nmake # nmake /f Makefile.Microsoft_nmake
# override as desired # override as desired, use /E
# vim: set ts=4 sw=4 et: # vim: set ts=4 sw=4 et:
TYPE=kem TYPE=kem
SCHEME=kyber768 SCHEME=kyber768
@ -31,17 +31,23 @@ clean-scheme:
nmake /f Makefile.Microsoft_nmake clean nmake /f Makefile.Microsoft_nmake clean
cd ..\..\..\test cd ..\..\..\test
$(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE: build-scheme $(COMMON_OBJECTS) $(COMMON_DIR)\randombytes.obj functest: $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe
-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
$(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) -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) $(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 LINK.EXE /OUT:$@ testvectors.obj $(COMMON_OBJECTS_NOPATH) notrandombytes.obj $(SCHEME_DIR)\lib$(SCHEME)_$(IMPLEMENTATION).lib
clean: clean:
-DEL functest.obj testvectors.obj -DEL functest.obj testvectors.obj
-DEL $(COMMON_OBJECTS_NOPATH) randombytes.obj notrandombytes.obj -DEL $(COMMON_OBJECTS_NOPATH) randombytes.obj notrandombytes.obj
-DEL $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).EXE -DEL $(DEST_DIR)\functest_$(SCHEME)_$(IMPLEMENTATION).exe

View File

@ -98,9 +98,9 @@ static int test_sign(void) {
// twice // twice
if ((returncode = if ((returncode =
crypto_sign_open(sm + 8, &mlen, sm + 8, smlen, pk + 8)) != 0) { 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) { if (returncode > 0) {
puts("ERROR return code should be < 0 on failure"); fprintf(stderr, "ERROR return code should be < 0 on failure");
} }
return 1; return 1;
} }
@ -109,7 +109,7 @@ static int test_sign(void) {
check_canary(sk) || check_canary(sk + CRYPTO_SECRETKEYBYTES + 8) || check_canary(sk) || check_canary(sk + CRYPTO_SECRETKEYBYTES + 8) ||
check_canary(sm) || check_canary(sm + MLEN + CRYPTO_BYTES + 8) || check_canary(sm) || check_canary(sm + MLEN + CRYPTO_BYTES + 8) ||
check_canary(m) || check_canary(m + MLEN + 8)) { check_canary(m) || check_canary(m + MLEN + 8)) {
printf("ERROR canary overwritten\n"); fprintf(stderr, "ERROR canary overwritten\n");
return 1; return 1;
} }
} }
@ -143,9 +143,9 @@ static int test_wrong_pk(void) {
// twice // twice
returncode = crypto_sign_open(sm, &mlen, sm, smlen, pk2); returncode = crypto_sign_open(sm, &mlen, sm, smlen, pk2);
if (!returncode) { 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) { if (returncode > 0) {
puts("ERROR return code should be < 0"); fprintf(stderr, "ERROR return code should be < 0");
} }
return 1; return 1;
} }

View File

@ -32,6 +32,7 @@ int main(void) {
uint8_t mi[MAXMLEN]; uint8_t mi[MAXMLEN];
uint8_t sm[MAXMLEN + CRYPTO_BYTES]; uint8_t sm[MAXMLEN + CRYPTO_BYTES];
size_t smlen; size_t smlen;
size_t mlen; size_t mlen;

View File

@ -1,5 +1,7 @@
import functools
import os import os
import subprocess import subprocess
import unittest
def run_subprocess(command, working_dir='.', env=None, expected_returncode=0): 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, # Note we need to capture stdout/stderr from the subprocess,
# then print it, which nose/unittest will then capture and # then print it, which nose/unittest will then capture and
# buffer appropriately # buffer appropriately
print(working_dir + " > " + " ".join(command))
result = subprocess.run( result = subprocess.run(
command, command,
stdout=subprocess.PIPE, stdout=subprocess.PIPE,
@ -22,7 +25,6 @@ def run_subprocess(command, working_dir='.', env=None, expected_returncode=0):
cwd=working_dir, cwd=working_dir,
env=env, env=env,
) )
print(working_dir + " > " + " ".join(command))
print(result.stdout.decode('utf-8')) print(result.stdout.decode('utf-8'))
assert(result.returncode == expected_returncode) assert(result.returncode == expected_returncode)
return result.stdout.decode('utf-8') return result.stdout.decode('utf-8')
@ -35,13 +37,33 @@ def make(*args, working_dir='.', env=None, **kwargs):
Usage: Usage:
make('clean', 'targetb', SCHEME='bla') 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( return run_subprocess(
[ [
make_command, *make_command,
*args,
*['{}={}'.format(k, v) for k, v in kwargs.items()], *['{}={}'.format(k, v) for k, v in kwargs.items()],
*args,
], ],
working_dir=working_dir, working_dir=working_dir,
env=env, 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

View File

@ -9,8 +9,6 @@ import unittest
def test_dynamic_memory(): def test_dynamic_memory():
if sys.platform not in ['linux', 'darwin']:
raise unittest.SkipTest()
for scheme in pqclean.Scheme.all_schemes(): for scheme in pqclean.Scheme.all_schemes():
for implementation in scheme.implementations: for implementation in scheme.implementations:
# Keep this loop outside, to allow multiple assertions # Keep this loop outside, to allow multiple assertions
@ -18,6 +16,7 @@ def test_dynamic_memory():
yield (check_dynamic_memory, implementation, function) yield (check_dynamic_memory, implementation, function)
@helpers.skip_windows()
def check_dynamic_memory(implementation, function): def check_dynamic_memory(implementation, function):
# 'make' will take care of not rebuilding existing library files # 'make' will take care of not rebuilding existing library files
helpers.make(working_dir=implementation.path()) helpers.make(working_dir=implementation.path())

View File

@ -2,7 +2,7 @@ import os
from glob import glob from glob import glob
import pqclean import pqclean
from helpers import run_subprocess from helpers import run_subprocess, skip_windows
def test_formatting(): def test_formatting():
@ -11,6 +11,8 @@ def test_formatting():
yield check_format, implementation 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): def check_format(implementation: pqclean.Implementation):
cfiles = glob(os.path.join(implementation.path(), '*.c')) cfiles = glob(os.path.join(implementation.path(), '*.c'))
hfiles = glob(os.path.join(implementation.path(), '*.h')) hfiles = glob(os.path.join(implementation.path(), '*.h'))

View File

@ -24,17 +24,22 @@ def test_functest_sanitizers():
def check_functest(implementation): def check_functest(implementation):
helpers.make(TYPE=implementation.scheme.type, helpers.make(#'functest',
TYPE=implementation.scheme.type,
SCHEME=implementation.scheme.name, SCHEME=implementation.scheme.name,
IMPLEMENTATION=implementation.name, IMPLEMENTATION=implementation.name,
working_dir=os.path.join('..', 'test')) working_dir=os.path.join('..', 'test'))
helpers.run_subprocess( helpers.run_subprocess(
['./functest_{}_{}'.format(implementation.scheme.name, [os.path.join('..', 'bin', 'functest_{}_{}{}'.format(
implementation.name)], implementation.scheme.name,
implementation.name,
'.exe' if os.name == 'nt' else ''
))],
os.path.join('..', 'bin'), os.path.join('..', 'bin'),
) )
@helpers.skip_windows
def check_functest_sanitizers(implementation): def check_functest_sanitizers(implementation):
env = None env = None
if platform.machine() == 'ppc' and os.environ.get('CC', 'gcc') == 'clang': 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'), working_dir=os.path.join('..', 'test'),
env=env) env=env)
helpers.run_subprocess( helpers.run_subprocess(
['./functest_{}_{}'.format(implementation.scheme.name, [os.path.join('..', 'bin', 'functest_{}_{}{}'.format(
implementation.name)], implementation.scheme.name,
implementation.name,
'.exe' if os.name == 'nt' else ''
))],
os.path.join('..', 'bin'), os.path.join('..', 'bin'),
env=env, env=env,
) )