#!/usr/bin/env python3 import os import sys import stat import argparse import shutil import random import subprocess import shutil def build(algo_dir, template_dir, build_dir): if os.path.isdir(build_dir): return None print("Building in %s" % build_dir) # copy all the files from the submitted algorithm into the build directory shutil.copytree(algo_dir, build_dir) # remove the test vectors generator if it is there c = os.path.join(build_dir, "genkat_aead.c") if os.path.exists(c): os.remove(c) # find all c and h files, since they will be added to the makefile hfiles = [] cfiles = [] for r, d, f in os.walk(build_dir): for file in f: if file.endswith(".c"): cfiles.append(file) elif file.endswith(".h"): hfiles.append(file) # copy all the files from the template directory into the build directory for f in os.listdir(template_dir): dst = os.path.join(build_dir, f) src = os.path.join(template_dir, f) if os.path.isfile(src) or os.path.islink(src): shutil.copy2(src, dst) elif os.path.isdir(src): shutil.copytree(src, dst) else: raise Exception("I don't know what %s is" % src) # prepare the environmental variables for the makefile env = os.environ env['SRC_FILES'] = ' '.join(cfiles) env['HDR_FILES'] = ' '.join(hfiles) # enter the directory and execute the makefile wd = os.getcwd() os.chdir(build_dir) try: if os.path.isfile('./configure'): p = subprocess.Popen(["./configure"]) p.wait() assert p.returncode == 0 p = subprocess.Popen(['make']) p.wait() assert p.returncode == 0 if os.path.isfile('./cleanup'): p = subprocess.Popen(["./cleanup"]) p.wait() assert p.returncode == 0 finally: sys.stdout.flush() sys.stderr.flush() os.chdir(wd) # if execution arrives here, the build was successful return build_dir # Find test vectors in directory or one of the parent directories def find_test_vectors(d): kat = None while True: if d == '': raise Exception("Test vector not found") for f in os.listdir(d): if f.startswith("LWC_AEAD_KAT_") and f.endswith(".txt"): if kat is not None: raise Exception("Multiple test vectors?") kat = f if kat is None: d = os.path.split(d)[0] else: break kat = os.path.join(d, kat) return kat def main(argv): submissions_dir = "all-lwc-submission-files" include_list = None # Parse the arguments argparser = argparse.ArgumentParser( description='Compiles all LWC submissions for a given template') argparser.add_argument('-v', '--verbose', action='count') argparser.add_argument('-t', '--template', default='templates/linux') argparser.add_argument('-b', '--build-dir') argparser.add_argument('-i', '--include', action='append') args = argparser.parse_args(argv[1:]) template_dir = args.template build_root_dir = args.build_dir include_list = args.include print("Using template %s" % template_dir) subs = os.listdir(submissions_dir) # get all the submissions by looking for files named "api.h" subfiles = [] for submission in subs: implementations_dir = os.path.join(submissions_dir, submission, "Implementations", "crypto_aead") if not os.path.isdir(implementations_dir): continue if "NOT ACCEPTED" in implementations_dir: continue print() print("### %s ###" % submission) c = 0 # r=root, d=directories, f = files for r, d, f in os.walk(implementations_dir): for file in f: if file == "api.h": f = os.path.join(r, file) subfiles.append(f) c += 1 if c == 0: raise Exception("No implementations found") if include_list is not None: print("Include list has %d entries" % len(include_list)) files = [] for f in subfiles: # Source directory d d = os.path.split(f)[0] assert os.path.isdir(d) print(d) # Test vectors file t t = find_test_vectors(d) print(t) # base name n pieces = f.split(os.sep) n = pieces[1] + "." + ".".join(pieces[4:-1]) print(n) # if include_list was provided, skip elements not in the list if include_list is not None: if not n in include_list: continue # Put all in a tuple and count files.append((t, d, n)) # For testing, we only do the first 1 #files = files[:1] print("%d algorithms will be compiled" % len(files)) if not os.path.isdir(build_root_dir): os.mkdir(build_root_dir) print() # Write a script that executes all the tests one after the other test_script_path = os.path.join(build_root_dir, "test_all.sh") with open(test_script_path, 'w') as test_script: test_script.write("#!/bin/sh\n") test_script.write("mkdir -p logs\n") test_script.write("mkdir -p measurements\n") for i, (t, d, name) in enumerate(files): print() print(d) try: build_dir = os.path.join(build_root_dir, name) b = build(d, template_dir, build_dir) if b is None: continue test_script.write("\n\necho \"TEST NUMBER %03d: TESTING %s\"\n" % (i, d)) test_script.write("python3 -u ./test.py %s %s 2> %s | tee %s\n" % ( t, os.path.join(b, 'test'), os.path.join(b, 'test_stderr.log'), os.path.join(b, 'test_stdout.log')) ) shutil.copyfile(t, os.path.join(b, 'LWC_AEAD_KAT.txt')) print("COMPILATION SUCCESS FOR %s" % d) except Exception as ex: print("COMPILATION FAILED FOR %s" % d) print(ex) st = os.stat(test_script_path) os.chmod(test_script_path, st.st_mode | stat.S_IEXEC) print() print() print("Now execute ' %s ' to start the test" % test_script_path) if __name__ == "__main__": sys.exit(main(sys.argv))