aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen/builder.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca/codegen/builder.py')
-rw-r--r--pyecsca/codegen/builder.py61
1 files changed, 42 insertions, 19 deletions
diff --git a/pyecsca/codegen/builder.py b/pyecsca/codegen/builder.py
index 2cd572b..e9a9144 100644
--- a/pyecsca/codegen/builder.py
+++ b/pyecsca/codegen/builder.py
@@ -4,7 +4,7 @@ import shutil
import subprocess
from copy import copy
from os import path
-from typing import List, Optional, Tuple, Type, MutableMapping
+from typing import List, Optional, Tuple, Type, MutableMapping, Any
import click
from public import public
@@ -13,7 +13,7 @@ from pyecsca.ec.configuration import (Multiplication, Squaring, Reduction, HashT
from pyecsca.ec.coordinates import CoordinateModel
from pyecsca.ec.formula import Formula, AdditionFormula
from pyecsca.ec.model import CurveModel
-from pyecsca.ec.mult import ScalarMultiplier
+from pyecsca.ec.mult import ScalarMultiplier, AccumulationOrder, ProcessingDirection
from .render import render
from .common import Platform, DeviceConfiguration, MULTIPLIERS, wrap_enum, get_model, get_coords
@@ -40,7 +40,7 @@ def get_multiplier(ctx: click.Context, param, value: Optional[str]) -> Optional[
if value is None:
return None
res = re.match(
- "(?P<name>[a-zA-Z\-]+)\((?P<args>([a-zA-Z_]+ *= *[a-zA-Z0-9]+, ?)*?([a-zA-Z_]+ *= *[a-zA-Z0-9]+)*)\)",
+ "(?P<name>[a-zA-Z\-]+)\((?P<args>([a-zA-Z_]+ *= *[a-zA-Z0-9.]+, ?)*?([a-zA-Z_]+ *= *[a-zA-Z0-9.]+)*)\)",
value)
if not res:
raise click.BadParameter("Couldn't parse multiplier spec: {}.".format(value))
@@ -61,7 +61,10 @@ def get_multiplier(ctx: click.Context, param, value: Optional[str]) -> Optional[
raise click.BadParameter(
"Multiplier {} requires formulas: {}, got {}.".format(mult_class.__name__,
mult_class.requires, classes))
- kwargs = eval("dict(" + args + ")")
+ globs = dict(globals())
+ globs["AccumulationOrder"] = AccumulationOrder
+ globs["ProcessingDirection"] = ProcessingDirection
+ kwargs = eval("dict(" + args + ")", globs)
required = set(
filter(lambda formula: any(isinstance(formula, cls) for cls in mult_class.requires),
formulas))
@@ -74,6 +77,20 @@ def get_multiplier(ctx: click.Context, param, value: Optional[str]) -> Optional[
return mult
+def get_define(ctx: click.Context, param, values: Optional[List[str]]) -> Optional[MutableMapping[str, Any]]:
+ if values is None:
+ return None
+ res = {}
+ for val in values:
+ try:
+ k, v = val.split("=")
+ except:
+ k = val
+ v = 1
+ res[k] = v
+ return res
+
+
@click.group(context_settings={"help_option_names": ["-h", "--help"]})
@click.version_option()
@public
@@ -119,6 +136,8 @@ def main():
show_default=True)
@click.option("--ecdsa/--no-ecdsa", help="Whether to enable ECDSA.", is_flag=True, default=True,
show_default=True)
+@click.option("-D", "--define", help="Set a custom C define.", multiple=True,
+ type=str, callback=get_define)
@click.option("--strip", help="Whether to strip the binary or not.", is_flag=True)
@click.option("--remove/--no-remove", help="Whether to remove the dir.", is_flag=True, default=True,
show_default=True)
@@ -135,7 +154,7 @@ def main():
@click.argument("outdir")
@click.pass_context
@public
-def build_impl(ctx, platform, hash, rand, mul, sqr, red, inv, keygen, ecdh, ecdsa, strip, remove,
+def build_impl(ctx, platform, hash, rand, mul, sqr, red, inv, keygen, ecdh, ecdsa, define, strip, remove,
verbose, model, coords, formulas, scalarmult, outdir):
"""This command builds an ECC implementation.
@@ -153,26 +172,30 @@ def build_impl(ctx, platform, hash, rand, mul, sqr, red, inv, keygen, ecdh, ecds
click.echo("[ ] Rendering...")
config = DeviceConfiguration(model, coords, formulas, scalarmult, hash, rand, mul, sqr, red,
- inv, platform, keygen, ecdh, ecdsa)
+ inv, platform, keygen, ecdh, ecdsa, define)
dir, elf_file, hex_file = render(config)
click.echo("[*] Rendered.")
click.echo("[ ] Building...")
- subprocess.run(["make"], cwd=dir, capture_output=not verbose)
- click.echo("[*] Built.")
-
- if strip:
- subprocess.run(["make", "strip"], cwd=dir, capture_output=not verbose)
- full_elf_path = path.join(dir, elf_file)
- full_hex_path = path.join(dir, hex_file)
- shutil.copy(full_elf_path, outdir)
- shutil.copy(full_hex_path, outdir)
- click.echo(elf_file)
- click.echo(hex_file)
- if remove:
+ result = subprocess.run(["make"], cwd=dir, capture_output=not verbose)
+ if result.returncode != 0:
+ click.echo("[x] Build failed.")
shutil.rmtree(dir)
else:
- click.echo(dir)
+ click.echo("[*] Built.")
+
+ if strip:
+ subprocess.run(["make", "strip"], cwd=dir, capture_output=not verbose)
+ full_elf_path = path.join(dir, elf_file)
+ full_hex_path = path.join(dir, hex_file)
+ shutil.copy(full_elf_path, outdir)
+ shutil.copy(full_hex_path, outdir)
+ click.echo(elf_file)
+ click.echo(hex_file)
+ if remove:
+ shutil.rmtree(dir)
+ else:
+ click.echo(dir)
@main.command("list")