Skip to content

Commit

Permalink
Merge pull request #514 from betrusted-io/curve25519
Browse files Browse the repository at this point in the history
Curve25519
  • Loading branch information
bunnie committed Mar 24, 2024
2 parents 72fda56 + 1cc0a71 commit a6ff652
Show file tree
Hide file tree
Showing 8 changed files with 60 additions and 74 deletions.
3 changes: 3 additions & 0 deletions .cargo/config
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,6 @@ rustflags = ["--cfg", "crossbeam_no_atomic_64"]
# "-C", "link-arg=-shared",
# "--cfg", "crossbeam_no_atomic_64"
# ]

[target.riscv32imac-unknown-xous-elf]
rustflags = ["--cfg", 'curve25519_dalek_backend="u32e_backend"']
34 changes: 10 additions & 24 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ sha2_legacy = { git = "https://github.com/RustCrypto/hashes.git", tag = "sha2-v0
[patch.crates-io.aes]
path = "services/aes"

#[patch.crates-io.curve25519-dalek]
#git = "https://github.com/betrusted-io/curve25519-dalek.git"
#branch = "main"
#path = "../curve25519-dalek/curve25519-dalek" # when doing local dev work
[patch.crates-io.curve25519-dalek]
git = "https://github.com/betrusted-io/curve25519-dalek.git"
branch = "main"
# path = "../curve25519-dalek/curve25519-dalek" # when doing local dev work
# feature overrides are specified at the crate level

[patch."https://github.com/betrusted-io/xous-engine-25519.git"]
Expand Down
6 changes: 3 additions & 3 deletions services/root-keys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ keyboard = { path = "../keyboard" }
sha2 = { version = "0.10.8" }
digest = "0.10.7"
aes = { path = "../aes" }
engine-25519 = { path = "../engine-25519" }
byteorder = "1.4.3" # used by keywrap
# engine-25519 = { path = "../engine-25519" }
byteorder = "1.4.3" # used by keywrap
# hardware acceleration adaptations are inserted into a fork of the main branch.
hex = { version = "0.4.3", default-features = false, features = [] }

[dependencies.curve25519-dalek]
version = "=4.1.1" # note this is patched to our fork in ./Cargo.toml
version = "=4.1.2" # note this is patched to our fork in ./Cargo.toml
default-features = false

[dependencies.ed25519-dalek]
Expand Down
2 changes: 2 additions & 0 deletions services/root-keys/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2382,6 +2382,8 @@ fn main() -> ! {
log::error!("couldn't convert opcode");
}
}
// de-allocate the engine at the end of root-keys, so other crates can use it.
curve25519_dalek::backend::serial::u32e::free_engine();
}
// clean up our program
log::trace!("main loop exit, destroying servers");
Expand Down
9 changes: 4 additions & 5 deletions services/shellchat/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ sha2 = { version = "0.10.8" }
digest = "0.10.7"
aes = { path = "../aes" }
cipher = "0.4.4"
engine-25519 = { path = "../engine-25519" }
spinor = { path = "../spinor" }
root-keys = { path = "../root-keys" }
jtag = { path = "../jtag" }
Expand Down Expand Up @@ -101,17 +100,17 @@ random-pick = { version = "1.2.16", optional = true }
hex = { version = "0.4.3", default-features = false, features = [] }
#sha2 = {version = "0.9.5", default-features = false, features = []}
[dependencies.curve25519-dalek]
version = "=4.1.1" # note this is patched to our fork in ./Cargo.toml
version = "=4.1.2" # note this is patched to our fork in ./Cargo.toml
default-features = false

[dependencies.x25519-dalek]
version = "2.0.1"
version = "=2.0.1"
# TODO: static_secrets is only needed by the engine tests. Ideally, we would put the static_secrets version in dev deps only
default-features = false
features = ["static_secrets"]

[dependencies.ed25519-dalek]
version = "2.1.0"
version = "=2.1.0"
#path = "../../../ed25519-dalek"
default-features = false
features = ["rand_core"]
Expand Down Expand Up @@ -153,4 +152,4 @@ rand-api = []
locktests = [
] # for debugging some specific `std` tests cherry-picked out of the test suite
simple-tls = ["rustls", "webpki-roots"]
default = [] # "debugprint"
default = ["benchmarks"] # "debugprint"
70 changes: 33 additions & 37 deletions services/shellchat/src/cmds/engine.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use core::sync::atomic::{AtomicU32, Ordering};

#[cfg(feature = "engine-ll")]
use engine_25519::*;
use num_traits::*;
use xous_ipc::String;
Expand Down Expand Up @@ -38,7 +39,13 @@ fn vector_read(word_offset: usize) -> u32 {
u32::from_le_bytes(bytes)
}

fn run_vectors(engine: &mut Engine25519) -> (usize, usize) {
fn run_vectors() -> (usize, usize) {
use curve25519_dalek::backend::serial::u32e::*;
ensure_engine();
// safety: it's safe because it's after ensure_engine()
let ucode_hw = unsafe { get_ucode() };
let rf_hw = unsafe { get_rf() };

let mut test_offset: usize = 0x0;
let mut passes: usize = 0;
let mut fails: usize = 0;
Expand All @@ -58,17 +65,9 @@ fn run_vectors(engine: &mut Engine25519) -> (usize, usize) {
let num_vectors = (vector_read(test_offset) >> 0) & 0x3F_FFFF;
test_offset += 1;

let mut job = Job {
id: None,
uc_start: load_addr,
uc_len: code_len,
ucode: [0; 1024],
rf: [0; RF_SIZE_IN_U32],
window: Some(window as u8),
};

for i in load_addr as usize..(load_addr + code_len) as usize {
job.ucode[i] = vector_read(test_offset);
let mut mcode = Vec::<i32>::new();
for _i in load_addr as usize..(load_addr + code_len) as usize {
mcode.push(vector_read(test_offset) as i32);
test_offset += 1;
}

Expand All @@ -79,32 +78,20 @@ fn run_vectors(engine: &mut Engine25519) -> (usize, usize) {
// a test suite can have numerous vectors against a common code base
for argcnt in 0..num_args {
for word in 0..8 {
job.rf[(/* window * 32 * 8 + */argcnt * 8 + word) as usize] = vector_read(test_offset);
rf_hw[(window * 32 * 8 + argcnt * 8 + word) as usize] = vector_read(test_offset);
test_offset += 1;
}
}

let mut passed = true;
log::trace!("spawning job");
match engine.spawn_job(job) {
Ok(rf_result) => {
for word in 0..8 {
let expect = vector_read(test_offset);
test_offset += 1;
let actual = rf_result[(/* window * 32 * 8 + */31 * 8 + word) as usize];
if expect != actual {
log::error!("e/a {:08x}/{:08x}", expect, actual);
passed = false;
}
}
}
Err(e) => {
log::error!(
"system error {:?} in running test vector: {}/0x{:x}",
e,
vector,
test_offset
);
run_job(ucode_hw, rf_hw, &mcode, window as usize);
for word in 0..8 {
let expect = vector_read(test_offset);
test_offset += 1;
let actual = rf_hw[(window * 32 * 8 + 31 * 8 + word) as usize];
if expect != actual {
log::error!("e/a {:08x}/{:08x}", expect, actual);
passed = false;
}
}
Expand All @@ -121,6 +108,7 @@ fn run_vectors(engine: &mut Engine25519) -> (usize, usize) {
}
}
}
curve25519_dalek::backend::serial::u32e::free_engine();
(passes, fails)
}
/*
Expand All @@ -134,8 +122,6 @@ pub fn benchmark_thread(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
let xns = xous_names::XousNames::new().unwrap();
let callback_conn = xns.request_connection_blocking(crate::SERVER_NAME_SHELLCHAT).unwrap();

let mut engine = engine_25519::Engine25519::new();

let mut trng = trng::Trng::new(&xns).unwrap();

loop {
Expand All @@ -146,7 +132,7 @@ pub fn benchmark_thread(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
let mut passes = 0;
let mut fails = 0;
for _ in 0..TEST_ITERS {
let (p, f) = run_vectors(&mut engine);
let (p, f) = run_vectors();
passes += p;
fails += f;
}
Expand Down Expand Up @@ -299,6 +285,7 @@ impl Engine {
.unwrap();
Engine {
susres: susres::Susres::new_without_hook(&xns).unwrap(),
// this is a dummy and hangs if engine-ll is not an active feature
benchmark_cid: xous::connect(sid).unwrap(),
start_time: None,
}
Expand All @@ -317,16 +304,18 @@ impl<'a> ShellCmdApi<'a> for Engine {
) -> Result<Option<String<1024>>, xous::Error> {
use core::fmt::Write;
let mut ret = String::<1024>::new();
#[cfg(feature = "engine-ll")]
let helpstring = "engine [check] [bench] [benchdh] [susres] [dh] [ed] [wycheproof]";
#[cfg(not(feature = "engine-ll"))]
let helpstring = "engine [susres] [dh] [ed] [wycheproof]";

let mut tokens = args.as_str().unwrap().split(' ');

if let Some(sub_cmd) = tokens.next() {
match sub_cmd {
"check" => {
let mut engine = engine_25519::Engine25519::new();
log::debug!("running vectors");
let (passes, fails) = run_vectors(&mut engine);
let (passes, fails) = run_vectors();

write!(ret, "Engine passed {} vectors, failed {} vectors", passes, fails).unwrap();
}
Expand Down Expand Up @@ -364,13 +353,18 @@ impl<'a> ShellCmdApi<'a> for Engine {
write!(ret, "Interrupted Engine hardware benchmark with a suspend/resume").unwrap();
}
"dh" => {
log::info!("starting DH test");
use x25519_dalek::{EphemeralSecret, PublicKey};
let alice_secret = EphemeralSecret::random_from_rng(&mut env.trng);
log::info!("1");
let alice_public = PublicKey::from(&alice_secret);
let bob_secret = EphemeralSecret::random_from_rng(&mut env.trng);
let bob_public = PublicKey::from(&bob_secret);
log::info!("2");
let alice_shared_secret = alice_secret.diffie_hellman(&bob_public);
log::info!("3");
let bob_shared_secret = bob_secret.diffie_hellman(&alice_public);
log::info!("4");
let mut pass = true;
for (&alice, &bob) in
alice_shared_secret.as_bytes().iter().zip(bob_shared_secret.as_bytes().iter())
Expand Down Expand Up @@ -571,6 +565,8 @@ impl<'a> ShellCmdApi<'a> for Engine {
} else {
write!(ret, "{}", helpstring).unwrap();
}
// de-allocate the engine at the end of the test, so other processes can grab it
curve25519_dalek::backend::serial::u32e::free_engine();
Ok(Some(ret))
}

Expand Down
2 changes: 1 addition & 1 deletion xtask/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
"root-keys",
"trng",
"[email protected]",
"engine-25519",
// "engine-25519",
"jtag",
// GUI front end
"status",
Expand Down

0 comments on commit a6ff652

Please sign in to comment.