Browse Source

Maybe working ECC? No way to test.

master
Thomas Kerber 2 months ago
parent
commit
0ff73a7baf
Signed by: Thomas Kerber <t.kerber@ed.ac.uk> GPG Key ID: 8489B911F9ED617B
12 changed files with 555 additions and 77 deletions
  1. 6
    0
      .gitmodules
  2. 32
    59
      Cargo.lock
  3. 1
    2
      Cargo.toml
  4. 46
    0
      ecc/Cargo.lock
  5. 9
    0
      ecc/Cargo.toml
  6. 121
    0
      ecc/src/lib.rs
  7. 12
    0
      libecc-sys/Cargo.toml
  8. 46
    0
      libecc-sys/build.rs
  9. 1
    0
      libecc-sys/libecc
  10. 199
    0
      libecc-sys/src/lib.rs
  11. 44
    16
      src/main.rs
  12. 38
    0
      src/memory.rs

+ 6
- 0
.gitmodules View File

@@ -0,0 +1,6 @@
[submodule "mbed-crypto-sys/mbed-crypto"]
path = mbed-crypto-sys/mbed-crypto
url = https://github.com/ARMmbed/mbed-crypto
[submodule "libecc-sys/libecc"]
path = libecc-sys/libecc
url = https://github.com/ANSSI-FR/libecc

+ 32
- 59
Cargo.lock View File

@@ -54,17 +54,6 @@ dependencies = [
"rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "block-buffer"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "block-cipher-trait"
version = "0.6.2"
@@ -73,19 +62,6 @@ dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "block-padding"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "byte-tools"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "byteorder"
version = "1.3.2"
@@ -96,6 +72,11 @@ name = "cast"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "cc"
version = "1.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "cortex-m"
version = "0.6.0"
@@ -123,15 +104,20 @@ dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
"quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "digest"
version = "0.8.1"
name = "cty"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "ecc"
version = "0.1.0"
dependencies = [
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libecc-sys 0.1.0",
]

[[package]]
@@ -145,7 +131,7 @@ dependencies = [

[[package]]
name = "embedded-graphics"
version = "0.5.1"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
@@ -157,11 +143,6 @@ dependencies = [
"void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "fake-simd"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "generic-array"
version = "0.12.3"
@@ -177,14 +158,21 @@ dependencies = [
"aes 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cortex-m-rt 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"embedded-graphics 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ssd1306 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"ecc 0.1.0",
"embedded-graphics 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"ssd1306 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"stm32f4 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"stm32f4xx-hal 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "libecc-sys"
version = "0.1.0"
dependencies = [
"cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)",
"cty 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "memchr"
version = "2.2.1"
@@ -272,20 +260,9 @@ name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "sha2"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "ssd1306"
version = "0.2.5"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"embedded-graphics 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -325,7 +302,7 @@ dependencies = [

[[package]]
name = "syn"
version = "0.15.39"
version = "0.15.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -389,20 +366,17 @@ dependencies = [
"checksum aligned 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a316c7ea8e1e9ece54862c992def5a7ac14de9f5832b69d71760680efeeefa"
"checksum as-slice 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "293dac66b274fab06f95e7efb05ec439a6b70136081ea522d270bc351ae5bb27"
"checksum bare-metal 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "a3caf393d93b2d453e80638d0674597020cef3382ada454faacd43d1a55a735a"
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
"checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09"
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
"checksum cast 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427"
"checksum cc 1.0.38 (registry+https://github.com/rust-lang/crates.io-index)" = "ce400c638d48ee0e9ab75aef7997609ec57367ccfe1463f21bf53c3eca67bf46"
"checksum cortex-m 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f3c18719fdc57db65668bfc977db9a0fa1a41d718c5d9cd4f652c9d4b0e0956a"
"checksum cortex-m-rt 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)" = "0e14454e26edbefb4d567ad7e71959b62268d28567e83f9a30fe21c3987af58c"
"checksum cortex-m-rt-macros 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d7ae692573e0acccb1579fef1abf5a5bf1d2f3f0149a22b16870ec9309aee25f"
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
"checksum cty 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "151a4ee37fd024fa6a134a4b506977504fa5dd378f6b7c797818ee41c7b2c23e"
"checksum embedded-graphics 0.4.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b2e7ee289ac88cbeea6f749cd72c6eb4cdeb801f4ea26795aace97b9776a2db2"
"checksum embedded-graphics 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "252cbe910fbd453d227e45232e2787b68b6bdff9a8fd2a1a79d0b10cf44e5d45"
"checksum embedded-graphics 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "704679bfcb66cc748ec185ae62ccd5b03311a53793372e2abf1ff9a7e9875ff7"
"checksum embedded-hal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ee4908a155094da7723c2d60d617b820061e3b4efcc3d9e293d206a5a76c170b"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum nb 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b1411551beb3c11dedfb0a90a0fa256b47d28b9ec2cdff34c25a2fa59e45dbdc"
@@ -417,12 +391,11 @@ dependencies = [
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
"checksum ssd1306 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4a726e2934812c6233a521c469c3ee6b2c3f1a74d7d100e7262b1964f7ad03d1"
"checksum ssd1306 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "57d818022001ebca8cec28b230700660a3f6a027123c8193c5e76e9764d087f3"
"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
"checksum stm32f4 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3cf6415d9b74bf664bdd154daf9bd84289aafdca8a8d7ece011fa5eb92fb7422"
"checksum stm32f4xx-hal 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdee466aa95237fec6962f3709cff5478e6de70de8c758271ec612c7a65fe42"
"checksum syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d960b829a55e56db167e861ddb43602c003c7be0bee1d345021703fac2fb7c"
"checksum syn 0.15.40 (registry+https://github.com/rust-lang/crates.io-index)" = "bc945221ccf4a7e8c31222b9d1fc77aefdd6638eb901a6ce457a3dc29d4c31e8"
"checksum tinybmp 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "503e3fde7e36b1aa2345af8a3af0086c9b01d9db07b24f3fb0aab07316b9fa10"
"checksum tinytga 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc9485052c1f4b541d888f1d564dd9957671e0c21da9bca0c9824c1123e03f07"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"

+ 1
- 2
Cargo.toml View File

@@ -9,9 +9,8 @@ opt-level = 's'
lto = true

[dependencies]
digest = "0.8.1"
aes = "0.3.2"
sha2 = { version = "0.8.0", default-features = false }
ecc = { path = "ecc" }
stm32f4xx-hal = { version = "0.5.0", features = ["stm32f401", "rt"] }
stm32f4 = "0.7.1"
cortex-m-rt = "0.6.9"

+ 46
- 0
ecc/Cargo.lock View File

@@ -0,0 +1,46 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "cc"
version = "1.0.37"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "cty"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"

[[package]]
name = "generic-array"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "libecc"
version = "0.1.0"
dependencies = [
"generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libecc-sys 0.1.0",
]

[[package]]
name = "libecc-sys"
version = "0.1.0"
dependencies = [
"cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
"cty 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]

[[package]]
name = "typenum"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"

[metadata]
"checksum cc 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "39f75544d7bbaf57560d2168f28fd649ff9c76153874db88bdbdfd839b1a7e7d"
"checksum cty 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "151a4ee37fd024fa6a134a4b506977504fa5dd378f6b7c797818ee41c7b2c23e"
"checksum generic-array 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ed1e761351b56f54eb9dcd0cfaca9fd0daecf93918e1cfc01c8a3d26ee7adcd"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"

+ 9
- 0
ecc/Cargo.toml View File

@@ -0,0 +1,9 @@
[package]
name = "ecc"
version = "0.1.0"
authors = ["Thomas Kerber <tk@drwx.org>"]
edition = "2018"

[dependencies]
generic-array = "0.12.3"
libecc-sys = { path = "../libecc-sys" }

+ 121
- 0
ecc/src/lib.rs View File

@@ -0,0 +1,121 @@
#![no_std]

extern crate libecc_sys;
extern crate generic_array;

use libecc_sys::*;
use core::mem::uninitialized;
use generic_array::GenericArray;
use generic_array::typenum::{UInt, UTerm, B0, B1};

pub struct KeyPair(ec_key_pair);
pub struct PrivateKey(ec_priv_key);
pub struct PublicKey(ec_pub_key);

pub struct Curve(ec_params);
pub struct Signer(ec_sign_context);

type KeySize = UInt<UInt<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>, B0>, B0>;
const KEYSIZE: usize = 48;
type SigSize = UInt<KeySize, B0>;
const SIGSIZE: usize = 96;

extern {
#[no_mangle]
#[allow(improper_ctypes)]
fn random_bytes(buf: &mut [u8]);
}

#[no_mangle]
extern "C" fn get_random(buf: *mut u8, len: u16) {
unsafe {
random_bytes(::core::slice::from_raw_parts_mut(buf, len as usize));
}
}

impl Curve {
pub fn init() -> Self {
let mut params: ec_params;
unsafe {
params = uninitialized();
import_params(&mut params, ec_get_curve_params_by_type(SECP384R1));
}
Curve(params)
}

pub fn generate_keypair(&self) -> KeyPair {
let mut kp: ec_key_pair;
unsafe {
kp = uninitialized();
ec_key_pair_gen(&mut kp, &self.0, ECDSA);
}
KeyPair(kp)
}

pub fn import_keypair(&self, key: &GenericArray<u8, KeySize>) -> KeyPair {
let mut kp: ec_key_pair;
unsafe {
kp = uninitialized();
ec_key_pair_import_from_priv_key_buf(
&mut kp,
&self.0,
key.as_slice().as_ptr(),
key.as_slice().len() as u8,
ECDSA);
}
KeyPair(kp)
}
}

impl KeyPair {
pub fn join(priv_key: PrivateKey, pub_key: PublicKey) -> KeyPair {
KeyPair(ec_key_pair {
priv_key: priv_key.0,
pub_key: pub_key.0,
})
}

pub fn split(self) -> (PrivateKey, PublicKey) {
(PrivateKey(self.0.priv_key), PublicKey(self.0.pub_key))
}
}

impl PrivateKey {
pub fn export(&self) -> GenericArray<u8, KeySize> {
let mut buf: [u8; KEYSIZE];
unsafe {
buf = uninitialized();
ec_priv_key_export_to_buf(
&self.0,
buf[..].as_mut_ptr(),
KEYSIZE as u8);
}
GenericArray::clone_from_slice(&buf[..])
}
}

impl Signer {
pub fn new(kp: &KeyPair) -> Self {
let mut ctx: ec_sign_context;
unsafe {
ctx = uninitialized();
ec_sign_init(&mut ctx, &kp.0, ECDSA, SHA384);
}
Signer(ctx)
}

pub fn update(&mut self, buf: &[u8]) {
unsafe {
ec_sign_update(&mut self.0, buf.as_ptr(), buf.len() as u32);
}
}

pub fn sign(mut self) -> GenericArray<u8, SigSize> {
let mut sig: [u8; SIGSIZE];
unsafe {
sig = uninitialized();
ec_sign_finalize(&mut self.0, sig.as_mut_ptr(), sig.len() as u8);
}
GenericArray::clone_from_slice(&sig[..])
}
}

+ 12
- 0
libecc-sys/Cargo.toml View File

@@ -0,0 +1,12 @@
[package]
name = "libecc-sys"
version = "0.1.0"
authors = [ "Thomas Kerber <tk@drwx.org>" ]
build = "build.rs"
edition = "2018"

[dependencies]
cty = "0.2.0"

[build-dependencies]
cc = "1.0.37"

+ 46
- 0
libecc-sys/build.rs View File

@@ -0,0 +1,46 @@
extern crate cc;

const FILES: &'static [&'static str] = &[
"libecc/src/fp/fp_pow.c",
"libecc/src/fp/fp.c",
"libecc/src/fp/fp_add.c",
"libecc/src/fp/fp_mul_redc1.c",
"libecc/src/fp/fp_montgomery.c",
"libecc/src/fp/fp_mul.c",
"libecc/src/fp/fp_rand.c",
"libecc/src/nn/nn_add.c",
"libecc/src/nn/nn_modinv.c",
"libecc/src/nn/nn_div.c",
"libecc/src/nn/nn.c",
"libecc/src/nn/nn_logical.c",
"libecc/src/nn/nn_mul_redc1.c",
"libecc/src/nn/nn_rand.c",
"libecc/src/nn/nn_mul.c",
"libecc/src/utils/utils.c",
"libecc/src/utils/print_nn.c",
"libecc/src/utils/print_fp.c",
"libecc/src/curves/ec_params.c",
"libecc/src/curves/ec_shortw.c",
"libecc/src/curves/prj_pt_monty.c",
"libecc/src/curves/aff_pt.c",
"libecc/src/curves/curves.c",
"libecc/src/curves/prj_pt.c",
"libecc/src/utils/print_curves.c",
"libecc/src/hash/sha384.c",
"libecc/src/hash/hash_algs.c",
"libecc/src/sig/ecdsa.c",
"libecc/src/sig/sig_algs.c",
"libecc/src/sig/ec_key.c",
"libecc/src/utils/print_keys.c",
];

fn main() {
cc::Build::new()
.files(FILES.iter())
.define("WITH_LIBECC_CONFIG_OVERRIDE", None)
.define("WITH_CURVE_SECP384R1", None)
.define("WITH_HASH_SHA384", None)
.define("WITH_SIG_ECDSA", None)
.pic(false)
.compile("libsign.a");
}

+ 1
- 0
libecc-sys/libecc

@@ -0,0 +1 @@
Subproject commit b181cd4c7cdfe2d24480c19b8815867a7de3ca6a

+ 199
- 0
libecc-sys/src/lib.rs View File

@@ -0,0 +1,199 @@
#![no_std]
#![allow(non_camel_case_types, non_snake_case)]

extern crate cty;

pub use cty::{c_int, c_void};

const FIELD_SIZE: usize = (384 / 8 + ::core::mem::size_of::<usize>() - 1) /
::core::mem::size_of::<usize>();
const SHA384_STATE_SIZE: usize = 8;
const SHA384_BLOCK_SIZE: usize = 128;
const MAX_CURVE_OID_LEN: usize = 32;
const MAX_CURVE_NAME_LEN: usize = 32;

type bitcnt_t = u16;
#[repr(C)]
struct ec_sig_mapping { _private: [u8; 0] }
#[repr(C)]
struct hash_mapping { _private: [u8; 0] }
#[repr(C)]
struct sha384_context {
sha384_total: [u64; 2],
sha384_state: [u64; SHA384_STATE_SIZE],
sha384_buffer: [u8; SHA384_BLOCK_SIZE],
}
type hash_context = sha384_context;
#[repr(C)]
struct ecdsa_verify_data {
r: nn,
s: nn,
h_ctx: hash_context,
magic: usize,
}
type sig_sign_data = ecdsa_verify_data;
#[repr(C)]
pub struct ec_sign_context {
ctx_magic: usize,
key_pair: *const ec_key_pair,
rand: extern fn(out: *mut nn, q: *const nn) -> c_int,
h: *const hash_mapping,
sig: *const ec_sig_mapping,
sign_data: sig_sign_data,
}
#[repr(C)]
struct ec_shortw_crv { _private: [u8; 0] }
#[repr(C)]
struct fp_ctx { _private: [u8; 0] }
#[repr(C)]
//FIXME! Can't be empty (gets stack allocated!)
pub struct ec_params {
ec_fp: fp_ctx,
ec_curve: ec_shortw_crv,
ec_curve_poitns: nn,
ec_gen: prj_pt,
ec_gen_order: nn,
ec_gen_order_bitlen: bitcnt_t,
ec_gen_cofactor: nn,
curve_oid: [u8; MAX_CURVE_OID_LEN],
curve_name: [u8; MAX_CURVE_NAME_LEN],
}
#[repr(C)]
pub struct ec_str_params { _private: [u8; 0] }

#[repr(C)]
struct nn {
val: [usize; FIELD_SIZE],
magic : usize,
wlen: u8,
}

#[repr(C)]
struct fp {
fp_val: nn,
ctx: *const fp_ctx,
magic: usize,
}

#[repr(C)]
struct prj_pt {
X: fp,
Y: fp,
Z: fp,
crv: *const ec_shortw_crv,
magic: usize,
}

#[repr(C)]
pub struct ec_priv_key {
key_type: ec_sig_alg_type,
params: *const ec_params,
x: nn,
magic: usize,
}

#[repr(C)]
pub struct ec_pub_key {
key_type: ec_sig_alg_type,
params: *const ec_params,
y: prj_pt,
magic: usize,
}

#[repr(C)]
pub struct ec_key_pair {
pub priv_key: ec_priv_key,
pub pub_key: ec_pub_key,
}

#[repr(C)]
pub enum ec_sig_alg_type {
UNKNOWN_SIG_ALG = 0,
ECDSA = 1,
}

pub use ec_sig_alg_type::*;

#[repr(C)]
pub enum hash_alg_type {
UNKNOWN_HASH_ALG = 0,
SHA384 = 3,
}

pub use hash_alg_type::*;

#[repr(C)]
pub enum ec_curve_type {
UNKNOWN_CURVE = 0,
SECP384R1 = 5,
}

pub use ec_curve_type::*;

extern "C" {
pub fn init_pubkey_from_privkey(
pub_key: *mut ec_pub_key,
priv_key: *mut ec_priv_key,
) -> c_int;
pub fn ec_sign_init(
ctx: *mut ec_sign_context,
key_pair: *const ec_key_pair,
sig_type: ec_sig_alg_type,
hash_type: hash_alg_type,
) -> c_int;
pub fn ec_sign_update(
ctx: *mut ec_sign_context,
chunk: *const u8,
chunklen: u32,
) -> c_int;
pub fn ec_sign_finalize(
ctx: *mut ec_sign_context,
sig: *mut u8,
siglen: u8,
) -> c_int;
pub fn ec_priv_key_is_initialized(A: *const ec_priv_key) -> c_int;
pub fn ec_priv_key_import_from_buf(
priv_key: *mut ec_priv_key,
params: *const ec_params,
priv_key_buf: *const u8,
priv_key_buf_len: u8,
ec_key_alg: ec_sig_alg_type,
) -> c_void;
pub fn ec_priv_key_export_to_buf(
priv_key: *const ec_priv_key,
priv_key_buf: *mut u8,
priv_key_buf_len: u8,
) -> c_int;
pub fn ec_pub_key_is_initialized(A: *const ec_pub_key) -> c_int;
pub fn ec_pub_key_import_from_buf(
pub_key: *mut ec_pub_key,
params: *const ec_params,
pub_key_buf: *const u8,
pub_key_buf_len: u8,
ec_key_alg: ec_sig_alg_type,
) -> c_void;
pub fn ec_pub_key_export_to_buf(
pub_key: *const ec_pub_key,
pub_key_buf: *mut u8,
pub_key_buf_len: u8,
) -> c_int;
pub fn key_pair_is_initialized(A: *const ec_key_pair) -> c_int;
pub fn ec_key_pair_import_from_priv_key_buf(
kp: *mut ec_key_pair,
params: *const ec_params,
priv_key: *const u8,
priv_key_len: u8,
ec_key_alg: ec_sig_alg_type,
) -> c_int;
pub fn ec_key_pair_gen(
kp: *mut ec_key_pair,
params: *const ec_params,
ec_key_alg: ec_sig_alg_type,
) -> c_int;
pub fn import_params(
out_params: *mut ec_params,
in_str_params: *const ec_str_params,
) -> c_void;
pub fn ec_get_curve_params_by_type(ec_type: ec_curve_type)
-> *const ec_str_params;
}

+ 44
- 16
src/main.rs View File

@@ -8,23 +8,46 @@ extern crate cortex_m_rt as rt;
extern crate ssd1306;
extern crate embedded_graphics;
extern crate aes;
extern crate sha2;
extern crate digest;
extern crate ecc;

mod memory;

use cortex_m_rt::entry;
use stm32f4::stm32f401 as chip;
use hal::prelude::*;
use hal::timer::Timer;
use hal::nb::block;
use hal::i2c::I2c;
use ssd1306::prelude::*;
use ssd1306::Builder;
use core::fmt::Write;
use digest::Digest;
use sha2::Sha512;
//use hal::i2c::I2c;
//use ssd1306::prelude::*;
//use ssd1306::Builder;
//use core::fmt::Write;
use aes::block_cipher_trait::generic_array::GenericArray;
use aes::block_cipher_trait::BlockCipher;
use aes::Aes256;
use ecc::{Curve, Signer};

fn ctr_otp(cipher: &Aes256, ctr: &mut u32) -> GenericArray<u8, <Aes256 as BlockCipher>::BlockSize> {
let mut block = GenericArray::clone_from_slice(&[0u8; 16]);
for (n, b) in ctr.to_ne_bytes()[..].iter().zip(block.iter_mut()) {
*b = *n;
}
cipher.encrypt_block(&mut block);
*ctr = u32::wrapping_add(*ctr, 1);
block
}

#[no_mangle]
// Warning: AES_SECRET_KEY must be initialised with true entropy first!
extern fn random_bytes(buf: &mut [u8]) {
let key = GenericArray::from_slice(&memory::AES_SECRET_KEY[..]);
let cipher = Aes256::new(&key);
for i in 0..((buf.len() + 15) / 16) {
let rnd = ctr_otp(&cipher, &mut memory::AES_RND);
for (src, dst) in rnd.iter().zip(buf[i*16..].iter_mut()) {
*dst = *src;
}
}
}

// use `main` as the entry point of this application
#[entry]
@@ -46,8 +69,10 @@ fn main() -> ! {
// Configure gpio C pin 13 as a push-pull output.
let mut red_led = gpiob.pb2.into_push_pull_output();
let mut green_led = gpiob.pb12.into_push_pull_output();
let kp = Curve::init().import_keypair(
GenericArray::from_slice(&memory::ECDSA_SECRET_KEY[..]));
// Configure the syst timer to trigger an update every second
let mut timer = Timer::syst(cp.SYST, 100.hz(), clocks);
let mut timer = Timer::syst(cp.SYST, 1.hz(), clocks);
//let scl = gpiob.pb8.into_alternate_af4();
//let sda = gpiob.pb9.into_alternate_af4();
//let i2c = I2c::i2c1(
@@ -67,19 +92,22 @@ fn main() -> ! {
loop {
block!(timer.wait()).unwrap();
i = u32::wrapping_add(i, 1);
let mut hasher = Sha512::new();
hasher.input(&i.to_ne_bytes()[..]);
let hash = hasher.result();
let key = GenericArray::from_slice(&hash[..32]);
let mut block = GenericArray::clone_from_slice(&hash[32..48]);
let key = GenericArray::from_slice(&[0u8; 32]);
let mut block = GenericArray::clone_from_slice(&[0u8; 16]);
for (n, b) in i.to_ne_bytes()[..].iter().zip(block.iter_mut()) {
*b = *n;
}
let cipher = Aes256::new(&key);
cipher.encrypt_block(&mut block);
if (hash[0] & 1) != 0 {
let mut signer = Signer::new(&kp);
signer.update(&block[..]);
let sig = signer.sign();
if (sig[0] & 1) != 0 {
red_led.set_high();
} else {
red_led.set_low();
}
if (hash[0] & 2) != 0 {
if (sig[0] & 2) != 0 {
green_led.set_high();
} else {
green_led.set_low();

+ 38
- 0
src/memory.rs View File

@@ -0,0 +1,38 @@
use core::ops::{Deref, DerefMut};

const FLASH_BASEADDR: usize = 0x0800_0000;
// We reserve 256k for the main program.
const DATA_OFFSET: usize = 0x0004_0000;

pub const AES_SECRET_KEY: StaticRef<[u8; 32]> = unsafe {
StaticRef::new((FLASH_BASEADDR + DATA_OFFSET) as *mut [u8;32])
};

pub const AES_RND: StaticRef<u32> = unsafe {
StaticRef::new((FLASH_BASEADDR + DATA_OFFSET + 32) as *mut u32)
};

pub const AES_CTR: StaticRef<u32> = unsafe {
StaticRef::new((FLASH_BASEADDR + DATA_OFFSET + 36) as *mut u32)
};

pub const ECDSA_SECRET_KEY: StaticRef<[u8; 64]> = unsafe {
StaticRef::new((FLASH_BASEADDR + DATA_OFFSET + 40) as *mut [u8; 64])
};

pub struct StaticRef<T>(*mut T);

impl<T> StaticRef<T> {
pub const unsafe fn new(ptr: *mut T) -> Self {
StaticRef(ptr)
}
}

impl<T> Deref for StaticRef<T> {
type Target = T;
fn deref(&self) -> &T { unsafe { &*self.0 } }
}

impl<T> DerefMut for StaticRef<T> {
fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.0 } }
}

Loading…
Cancel
Save