diff options
Diffstat (limited to 'pyecsca/codegen')
| -rw-r--r-- | pyecsca/codegen/bn/bn.c | 8 | ||||
| -rw-r--r-- | pyecsca/codegen/builder.py | 11 | ||||
| -rw-r--r-- | pyecsca/codegen/client.py | 32 | ||||
| -rw-r--r-- | pyecsca/codegen/hal/hal.h | 12 | ||||
| -rw-r--r-- | pyecsca/codegen/templates/main.c | 40 |
5 files changed, 76 insertions, 27 deletions
diff --git a/pyecsca/codegen/bn/bn.c b/pyecsca/codegen/bn/bn.c index 0d83731..53777db 100644 --- a/pyecsca/codegen/bn/bn.c +++ b/pyecsca/codegen/bn/bn.c @@ -202,6 +202,7 @@ bn_err bn_red_decode(bn_t *one, const bn_t *mod, const red_t *red) { } bn_err bn_red_add(const bn_t *one, const bn_t *other, const bn_t *mod, const red_t *red, bn_t *out) { +#ifdef BN_NON_CONST bn_err err; if ((err = mp_add(one, other, out)) != BN_OKAY) { return err; @@ -211,9 +212,13 @@ bn_err bn_red_add(const bn_t *one, const bn_t *other, const bn_t *mod, const red } else { return err; } +#else + return mp_addmod(one, other, mod, out); +#endif } bn_err bn_red_sub(const bn_t *one, const bn_t *other, const bn_t *mod, const red_t *red, bn_t *out) { +#ifdef BN_NON_CONST bn_err err; if ((err = mp_sub(one, other, out)) != BN_OKAY) { return err; @@ -225,6 +230,9 @@ bn_err bn_red_sub(const bn_t *one, const bn_t *other, const bn_t *mod, const red return mp_sub(out, mod, out); } return err; +#else + return mp_submod(one, other, mod, out); +#endif } bn_err bn_red_neg(const bn_t *one, const bn_t *mod, const red_t *red, bn_t *out) { diff --git a/pyecsca/codegen/builder.py b/pyecsca/codegen/builder.py index 54d4475..8ed7022 100644 --- a/pyecsca/codegen/builder.py +++ b/pyecsca/codegen/builder.py @@ -8,7 +8,8 @@ from typing import List, Optional, Tuple, Type, MutableMapping import click from public import public -from pyecsca.ec.configuration import Multiplication, Squaring, Reduction, HashType, RandomMod +from pyecsca.ec.configuration import (Multiplication, Squaring, Reduction, HashType, RandomMod, + Inversion) from pyecsca.ec.coordinates import CoordinateModel from pyecsca.ec.formula import Formula, AdditionFormula from pyecsca.ec.model import CurveModel @@ -108,6 +109,10 @@ def main(): type=click.Choice(Reduction.names()), callback=wrap_enum(Reduction), help="Modular reduction algorithm to use.") +@click.option("--inv", envvar="INV", default="GCD", show_default=True, + type=click.Choice(Inversion.names()), + callback=wrap_enum(Inversion), + help="Modular inversion algorithm to use.") @click.option("--keygen/--no-keygen", help="Whether to enable keygen.", is_flag=True, default=True, show_default=True) @click.option("--ecdh/--no-ecdh", help="Whether to enable ECDH.", is_flag=True, default=True, @@ -130,7 +135,7 @@ def main(): @click.argument("outdir") @click.pass_context @public -def build_impl(ctx, platform, hash, rand, mul, sqr, red, keygen, ecdh, ecdsa, strip, remove, +def build_impl(ctx, platform, hash, rand, mul, sqr, red, inv, keygen, ecdh, ecdsa, strip, remove, verbose, model, coords, formulas, scalarmult, outdir): """This command builds an ECC implementation. @@ -147,7 +152,7 @@ def build_impl(ctx, platform, hash, rand, mul, sqr, red, keygen, ecdh, ecdsa, st raise click.BadParameter("ECDSA needs an addition formula. None was supplied.") config = DeviceConfiguration(model, coords, formulas, scalarmult, hash, rand, mul, sqr, red, - platform, keygen, ecdh, ecdsa) + inv, platform, keygen, ecdh, ecdsa) dir, elf_file, hex_file = render(config) subprocess.run(["make"], cwd=dir, capture_output=not verbose) diff --git a/pyecsca/codegen/client.py b/pyecsca/codegen/client.py index 2a906d3..f8e7008 100644 --- a/pyecsca/codegen/client.py +++ b/pyecsca/codegen/client.py @@ -119,8 +119,9 @@ def cmd_set_pubkey(pubkey: Point) -> str: @public -def cmd_scalar_mult(scalar: int) -> str: - return "m" + hexlify(encode_data(None, {"s": encode_scalar(scalar)})).decode() +def cmd_scalar_mult(scalar: int, point: Point) -> str: + return "m" + hexlify(encode_data(None, {"s": encode_scalar(scalar), + "w": encode_point(point.to_affine())})).decode() @public @@ -201,8 +202,8 @@ class ImplTarget(SimpleSerialTarget): self.send_cmd(SMessage.from_raw(cmd_set_pubkey(pubkey)), self.timeout) self.pubkey = pubkey - def scalar_mult(self, scalar: int) -> Point: - resp = self.send_cmd(SMessage.from_raw(cmd_scalar_mult(scalar)), self.timeout) + def scalar_mult(self, scalar: int, point: Point) -> Point: + resp = self.send_cmd(SMessage.from_raw(cmd_scalar_mult(scalar, point)), self.timeout) result = resp["w"] plen = ((self.params.curve.prime.bit_length() + 7) // 8) * 2 params = {var: Mod(int(result.data[i * plen:(i + 1) * plen], 16), self.params.curve.prime) @@ -272,6 +273,7 @@ class HostTarget(ImplTarget, BinaryTarget): @click.option("--fw", help="The firmware. Either a .hex file for a device platform or .elf for HOST platform.", required=True) +@click.option("--timeout", type=int, default=15000) @click.argument("model", required=True, type=click.Choice(["shortw", "montgom", "edwards", "twisted"]), callback=get_model) @@ -280,19 +282,19 @@ class HostTarget(ImplTarget, BinaryTarget): @click.version_option() @click.pass_context @public -def main(ctx, platform, fw, model, coords): +def main(ctx, platform, fw, timeout, model, coords): """ A tool for communicating with built and flashed ECC implementations. """ ctx.ensure_object(dict) ctx.obj["fw"] = fw if platform != Platform.HOST: - ctx.obj["target"] = DeviceTarget(model, coords, platform) + ctx.obj["target"] = DeviceTarget(model, coords, platform, timeout=timeout) else: if fw is None or not path.isfile(fw): click.secho("Binary is required if the target is the host.", fg="red", err=True) raise click.Abort - ctx.obj["target"] = HostTarget(model, coords, binary=fw) + ctx.obj["target"] = HostTarget(model, coords, binary=fw, timeout=timeout) def get_curve(ctx: click.Context, param, value: Optional[str]) -> DomainParameters: @@ -306,22 +308,21 @@ def get_curve(ctx: click.Context, param, value: Optional[str]) -> DomainParamete @main.command("gen") -@click.option("--timeout", type=int, default=15000) @click.argument("curve", required=True, callback=get_curve) @click.pass_context @public -def generate(ctx: click.Context, timeout, curve): +def generate(ctx: click.Context, curve): """Generate a keypair on a curve.""" ctx.ensure_object(dict) target: ImplTarget = ctx.obj["target"] if isinstance(target, Flashable): target.flash(ctx.obj["fw"]) - target.timeout = timeout target.connect() target.set_params(curve) start = time() click.echo(target.generate()) click.echo(time() - start) + target.quit() target.disconnect() @@ -347,41 +348,38 @@ def get_pubkey(ctx: click.Context, param, value: Optional[str]) -> Point: @main.command("ecdh") -@click.option("--timeout", type=int, default=15000) @click.argument("curve", required=True, callback=get_curve) @click.argument("pubkey", required=True, callback=get_pubkey) @click.pass_context @public -def ecdh(ctx: click.Context, timeout, curve, pubkey): +def ecdh(ctx: click.Context, curve, pubkey): """Perform ECDH with a given public key.""" ctx.ensure_object(dict) target: ImplTarget = ctx.obj["target"] if isinstance(target, Flashable): target.flash(ctx.obj["fw"]) - target.timeout = timeout target.connect() target.set_params(curve) target.generate() click.echo(hexlify(target.ecdh(pubkey))) + target.quit() target.disconnect() @main.command("ecdsa-sign") -@click.option("--timeout", type=int, default=15000) @click.argument("curve", required=True, callback=get_curve) @click.pass_context @public -def ecdsa_sign(ctx: click.Context, timeout, curve): +def ecdsa_sign(ctx: click.Context, curve): ctx.ensure_object(dict) # TODO @main.command("ecdsa-verify") -@click.option("--timeout", type=int, default=15000) @click.argument("curve", required=True, callback=get_curve) @click.pass_context @public -def ecdsa_verify(ctx: click.Context, timeout, curve): +def ecdsa_verify(ctx: click.Context, curve): ctx.ensure_object(dict) # TODO diff --git a/pyecsca/codegen/hal/hal.h b/pyecsca/codegen/hal/hal.h index fc7fc37..51f9130 100644 --- a/pyecsca/codegen/hal/hal.h +++ b/pyecsca/codegen/hal/hal.h @@ -41,4 +41,16 @@ void platform_init(void); #error "Unsupported HAL Type" #endif +#define NOP() __asm__ __volatile__ ("nop"); +#define _2(a) a;a +#define NOP_2() _2(NOP()) +#define NOP_4() _2(_2(NOP())) +#define NOP_8() _2(_2(_2(NOP()))) +#define NOP_16() _2(_2(_2(_2(NOP())))) +#define NOP_32() _2(_2(_2(_2(_2(NOP()))))) +#define NOP_64() _2(_2(_2(_2(_2(_2(NOP())))))) +#define NOP_128() _2(_2(_2(_2(_2(_2(_2(NOP()))))))) +#define NOP_256() _2(_2(_2(_2(_2(_2(_2(_2(NOP())))))))) +#define NOP_512() _2(_2(_2(_2(_2(_2(_2(_2(_2(NOP()))))))))) + #endif //HAL_H_ diff --git a/pyecsca/codegen/templates/main.c b/pyecsca/codegen/templates/main.c index f3c6de6..2a0d575 100644 --- a/pyecsca/codegen/templates/main.c +++ b/pyecsca/codegen/templates/main.c @@ -200,9 +200,21 @@ static uint8_t cmd_set_pubkey(uint8_t *data, uint16_t len) { } static void parse_scalar_mult(const char *path, const uint8_t *data, size_t len, void *arg) { - bn_t *scalar = (bn_t *)arg; + fat_t *affine = (fat_t *) arg; + if (strcmp(path, "wx") == 0) { + affine[0].len = len; + affine[0].value = malloc(len); + memcpy(affine[0].value, data, len); + return; + } + if (strcmp(path, "wy") == 0) { + affine[1].len = len; + affine[1].value = malloc(len); + memcpy(affine[1].value, data, len); + return; + } if (strcmp(path, "s") == 0) { - bn_from_bin(data, len, scalar); + bn_from_bin(data, len, (bn_t *) affine[2].value); return; } } @@ -210,13 +222,26 @@ static void parse_scalar_mult(const char *path, const uint8_t *data, size_t len, static uint8_t cmd_scalar_mult(uint8_t *data, uint16_t len) { // perform base point scalar mult with supplied scalar. bn_t scalar; bn_init(&scalar); - parse_data(data, len, "", parse_scalar_mult, (void *) &scalar); + point_t *other = point_new(); + fat_t affine[3] = {fat_empty, fat_empty, {0, (void *) &scalar}}; + parse_data(data, len, "", parse_scalar_mult, (void *) affine); size_t coord_size = bn_to_bin_size(&curve->p); + bn_t ox; bn_init(&ox); + bn_t oy; bn_init(&oy); + bn_from_bin(affine[0].value, affine[0].len, &ox); + bn_from_bin(affine[1].value, affine[1].len, &oy); + bn_red_encode(&ox, &curve->p, &curve->p_red); + bn_red_encode(&oy, &curve->p, &curve->p_red); + point_from_affine(&ox, &oy, curve, other); + bn_clear(&ox); + bn_clear(&oy); + free(affine[0].value); + free(affine[1].value); point_t *result = point_new(); - scalar_mult(&scalar, curve->generator, curve, result); - //point_red_decode(result, curve); + scalar_mult(&scalar, other, curve, result); + point_red_decode(result, curve); uint8_t res[coord_size * {{ curve_variables | length }}]; {%- for variable in curve_variables %} @@ -224,6 +249,7 @@ static uint8_t cmd_scalar_mult(uint8_t *data, uint16_t len) { {%- endfor %} bn_clear(&scalar); point_free(result); + point_free(other); simpleserial_put('w', coord_size * {{ curve_variables | length }}, res); return 0; @@ -496,9 +522,9 @@ int main(void) { simpleserial_addcmd('t', MAX_SS_LEN, cmd_set_trigger); simpleserial_addcmd('d', MAX_SS_LEN, cmd_debug); - led_ok(1); + //led_ok(1); while(simpleserial_get()); - led_ok(0); + //led_ok(0); bn_clear(&privkey); curve_free(curve); |
