From 99f81adc5505071a434706827d5dfa80f577957c Mon Sep 17 00:00:00 2001 From: kaczmarczyck <43844792+kaczmarczyck@users.noreply.github.com> Date: Fri, 5 May 2023 22:38:56 +0200 Subject: [PATCH] RustCrypto in TockEnv (#625) * Adds a rust_crypto feature to Tock * -O3 for RustCrypto --- Cargo.lock | 307 +++++++++++++++++- Cargo.toml | 6 + deploy.py | 7 + examples/crypto_bench.rs | 90 ++--- libraries/opensk/Cargo.toml | 21 +- .../opensk/src/api/crypto/rust_crypto.rs | 1 + 6 files changed, 365 insertions(+), 67 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 11dd7d8..d236ccc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "aes" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433cfd6710c9986c576a25ca913c39d66a6474107b406f34f91d4a8923395241" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + [[package]] name = "aho-corasick" version = "0.7.19" @@ -23,12 +34,33 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + [[package]] name = "bumpalo" version = "3.8.0" @@ -41,6 +73,15 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + [[package]] name = "cc" version = "1.0.73" @@ -53,6 +94,31 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + +[[package]] +name = "const-oid" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" + +[[package]] +name = "cpufeatures" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c1eaa2012c47becbbad2ab175484c2a84d1185b566fb2cc5b8707343dfe58" +dependencies = [ + "libc", +] + [[package]] name = "crypto" version = "0.1.0" @@ -70,6 +136,28 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c2538c4e68e52548bacb3e83ac549f903d44f011ac9d5abb5e132e67d0808f7" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "ctap2" version = "1.0.0" @@ -95,12 +183,67 @@ dependencies = [ "uuid", ] +[[package]] +name = "der" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e58dffcdcc8ee7b22f0c1f71a69243d7c2d9ad87b5a14361f2424a1565c219" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a48e5d537b8a30c0b023116d981b16334be1485af7ca68db3a2b7024cbc957fd" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", +] + [[package]] name = "ed25519-compact" version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bee9df587982575886a8682edcee11877894349a805f25629c27f63abe3e9ae8" +[[package]] +name = "elliptic-curve" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75c71eaa367f2e5d556414a8eea812bc62985c879748d6403edabd9cb03f16e7" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + [[package]] name = "enum-iterator" version = "0.6.0" @@ -121,6 +264,16 @@ dependencies = [ "syn", ] +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + [[package]] name = "foreign-types" version = "0.3.2" @@ -136,6 +289,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + [[package]] name = "getrandom" version = "0.2.7" @@ -147,12 +311,50 @@ dependencies = [ "wasi", ] +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + [[package]] name = "hex" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + [[package]] name = "itoa" version = "0.4.8" @@ -273,14 +475,20 @@ checksum = "2f7254b99e31cad77da24b08ebf628882739a608578bb1bcdfc1f9c21260d7c0" name = "opensk" version = "1.0.0" dependencies = [ + "aes", "arrayref", "byteorder", + "cbc", "crypto", "ed25519-compact", + "hkdf", + "hmac", "openssl", + "p256", "persistent_store", "rand", "rand_core", + "sha2", "sk-cbor", "subtle", "uuid", @@ -326,10 +534,32 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + [[package]] name = "persistent_store" version = "0.1.0" +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.25" @@ -342,6 +572,15 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "primeorder" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8d3875361e28f7753baefef104386e7aa47642c93023356d97fdef4003bfb5" +dependencies = [ + "elliptic-curve", +] + [[package]] name = "proc-macro2" version = "1.0.43" @@ -366,7 +605,6 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ - "libc", "rand_chacha", "rand_core", ] @@ -407,6 +645,16 @@ version = "0.6.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244" +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + [[package]] name = "ring" version = "0.16.20" @@ -428,6 +676,20 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" +[[package]] +name = "sec1" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0aec48e813d6b90b15f0b8948af3c63483992dee44c03e9930b3eebdabe046e" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + [[package]] name = "serde" version = "1.0.145" @@ -459,6 +721,27 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core", +] + [[package]] name = "sk-cbor" version = "0.1.2" @@ -469,6 +752,16 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" +[[package]] +name = "spki" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37a5be806ab6f127c3da44b7378837ebf01dadca8510a0e572460216b228bd0e" +dependencies = [ + "base64ct", + "der", +] + [[package]] name = "subtle" version = "2.4.1" @@ -518,6 +811,12 @@ dependencies = [ "syn", ] +[[package]] +name = "typenum" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" + [[package]] name = "unicode-ident" version = "1.0.4" @@ -551,6 +850,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" diff --git a/Cargo.toml b/Cargo.toml index 2a534e6..6663961 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ with_ctap1 = ["crypto/with_ctap1", "opensk/with_ctap1"] with_nfc = ["libtock_drivers/with_nfc"] vendor_hid = ["opensk/vendor_hid"] ed25519 = ["ed25519-compact", "opensk/ed25519"] +rust_crypto = ["opensk/rust_crypto"] [dev-dependencies] enum-iterator = "0.6.0" @@ -60,3 +61,8 @@ panic = "abort" lto = true # Link Time Optimization usually reduces size of binaries and static libraries opt-level = "z" codegen-units = 1 + +[profile.release.package] +aes = { opt-level = 3 } +sha2 = { opt-level = 3 } +p256 = { opt-level = 3 } diff --git a/deploy.py b/deploy.py index a235e51..68665cb 100755 --- a/deploy.py +++ b/deploy.py @@ -1091,6 +1091,13 @@ if __name__ == "__main__": help=("Compiles the OpenSK application without backward compatible " "support for U2F/CTAP1 protocol."), ) + main_parser.add_argument( + "--rust-crypto", + action="append_const", + const="rust_crypto", + dest="features", + help=("Compiles the OpenSK application with RustCrypto implementations."), + ) main_parser.add_argument( "--nfc", action="append_const", diff --git a/examples/crypto_bench.rs b/examples/crypto_bench.rs index 9ff9326..abd5e5e 100644 --- a/examples/crypto_bench.rs +++ b/examples/crypto_bench.rs @@ -21,13 +21,17 @@ extern crate lang_items; use alloc::format; use alloc::vec::Vec; use core::fmt::Write; -use crypto::{aes256, cbc, ecdsa, sha256, Hash256}; -use ctap2::env::tock::TockRng; +use core::hint::black_box; +use ctap2::env::tock::{TockEnv, TockRng}; use libtock_console::{Console, ConsoleWriter}; use libtock_drivers::result::FlexUnwrap; use libtock_drivers::timer; use libtock_drivers::timer::{Timer, Timestamp}; use libtock_runtime::{set_main, stack_size, TockSyscalls}; +use opensk::api::crypto::aes256::Aes256; +use opensk::api::crypto::ecdsa::SecretKey as _; +use opensk::api::crypto::sha256::Sha256; +use opensk::env::{AesKey, EcdsaSk, Sha}; stack_size! {0x2000} set_main! {main} @@ -47,56 +51,42 @@ fn main() { writeln!(console, "Clock frequency: {:?} Hz", timer.clock_frequency()).unwrap(); // AES - bench(&mut console, &timer, "aes256::EncryptionKey::new", || { - aes256::EncryptionKey::new(&[0; 32]); + bench(&mut console, &timer, "Aes256::new", || { + black_box(AesKey::>::new(&[0; 32])); }); - let ek = aes256::EncryptionKey::new(&[0; 32]); - bench(&mut console, &timer, "aes256::DecryptionKey::new", || { - aes256::DecryptionKey::new(&ek); - }); - let dk = aes256::DecryptionKey::new(&ek); + let aes_key = AesKey::>::new(&[0; 32]); - bench( - &mut console, - &timer, - "aes256::EncryptionKey::encrypt_block", - || { - ek.encrypt_block(&mut [0; 16]); - }, - ); - bench( - &mut console, - &timer, - "aes256::DecryptionKey::decrypt_block", - || { - dk.decrypt_block(&mut [0; 16]); - }, - ); + bench(&mut console, &timer, "Aes256::encrypt_block", || { + aes_key.encrypt_block(&mut [0; 16]); + }); + bench(&mut console, &timer, "Aes256::decrypt_block", || { + aes_key.decrypt_block(&mut [0; 16]); + }); // CBC let mut blocks = Vec::new(); - for i in 0..8 { + for i in 0..6 { blocks.resize(1 << (i + 4), 0); bench( &mut console, &timer, - &format!("cbc::cbc_encrypt({} bytes)", blocks.len()), + &format!("Aes256::encrypt_cbc({} bytes)", blocks.len()), || { - cbc::cbc_encrypt(&ek, [0; 16], &mut blocks); + aes_key.encrypt_cbc(&[0; 16], &mut blocks); }, ); } drop(blocks); let mut blocks = Vec::new(); - for i in 0..8 { + for i in 0..6 { blocks.resize(1 << (i + 4), 0); bench( &mut console, &timer, - &format!("cbc::cbc_decrypt({} bytes)", blocks.len()), + &format!("Aes256::decrypt_cbc({} bytes)", blocks.len()), || { - cbc::cbc_decrypt(&dk, [0; 16], &mut blocks); + aes_key.decrypt_cbc(&[0; 16], &mut blocks); }, ); } @@ -104,46 +94,30 @@ fn main() { // SHA-256 let mut contents = Vec::new(); - for i in 0..8 { + for i in 0..6 { contents.resize(16 << i, 0); bench( &mut console, &timer, - &format!("sha256::Sha256::update({} bytes)", contents.len()), + &format!("Sha256::digest({} bytes)", contents.len()), || { - let mut sha = sha256::Sha256::new(); - sha.update(&contents); - let mut dummy_hash = [0; 32]; - sha.finalize(&mut dummy_hash); + Sha::>::digest(&contents); }, ); } drop(contents); // ECDSA - bench(&mut console, &timer, "ecdsa::SecKey::gensk", || { - ecdsa::SecKey::gensk(&mut rng); + bench(&mut console, &timer, "Ecdsa::SecretKey::random", || { + EcdsaSk::>::random(&mut rng); }); - let k = ecdsa::SecKey::gensk(&mut rng); - bench(&mut console, &timer, "ecdsa::SecKey::genpk", || { - k.genpk(); + let sk = EcdsaSk::>::random(&mut rng); + bench(&mut console, &timer, "Ecdsa::SecretKey::public_key", || { + black_box(sk.public_key()); + }); + bench(&mut console, &timer, "Ecdsa::SecretKey::sign", || { + sk.sign(&[]); }); - bench( - &mut console, - &timer, - "ecdsa::SecKey::sign_rng::", - || { - k.sign_rng::(&[], &mut rng); - }, - ); - bench( - &mut console, - &timer, - "ecdsa::SecKey::sign_rfc6979::", - || { - k.sign_rfc6979::(&[]); - }, - ); writeln!(console, "****************************************").unwrap(); writeln!(console, "All the benchmarks are done.\nHave a nice day!").unwrap(); diff --git a/libraries/opensk/Cargo.toml b/libraries/opensk/Cargo.toml index 964bae5..60a9d2a 100644 --- a/libraries/opensk/Cargo.toml +++ b/libraries/opensk/Cargo.toml @@ -20,19 +20,24 @@ arrayref = "0.3.6" subtle = { version = "2.2", default-features = false, features = ["nightly"] } arbitrary = { version = "0.4.7", features = ["derive"], optional = true } ed25519-compact = { version = "1", default-features = false, optional = true } -p256 = { version = "0.13.0", features = ["ecdh"], optional = true } rand_core = "0.6.4" -rand = { version = "0.8.5", optional = true } -sha2 = { version = "0.10.6", optional = true } -hmac = { version = "0.12.1", optional = true } -hkdf = { version = "0.12.3", optional = true } -aes = { version = "0.8.2", optional = true } -cbc = { version = "0.1.2", optional = true } +rand = { version = "0.8.5", default-features = false, optional = true } +sha2 = { version = "0.10.6", default-features = false, optional = true } +hmac = { version = "0.12.1", default-features = false, optional = true } +hkdf = { version = "0.12.3", default-features = false, optional = true } +aes = { version = "0.8.2", default-features = false, optional = true } +cbc = { version = "0.1.2", default-features = false, optional = true } zeroize = { version = "1.5.7", features = ["derive"] } +[dependencies.p256] +version = "0.13.0" +default-features = false +features = ["alloc", "ecdh", "ecdsa"] +optional = true + [features] debug_ctap = [] -std = ["crypto/std", "persistent_store/std", "rand"] +std = ["crypto/std", "persistent_store/std", "rand/std_rng"] with_ctap1 = ["crypto/with_ctap1"] vendor_hid = [] fuzz = ["arbitrary", "std"] diff --git a/libraries/opensk/src/api/crypto/rust_crypto.rs b/libraries/opensk/src/api/crypto/rust_crypto.rs index 794d30c..a70199c 100644 --- a/libraries/opensk/src/api/crypto/rust_crypto.rs +++ b/libraries/opensk/src/api/crypto/rust_crypto.rs @@ -33,6 +33,7 @@ use aes::cipher::generic_array::GenericArray; use aes::cipher::{ BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, KeyInit, KeyIvInit, }; +use alloc::vec::Vec; use core::convert::TryFrom; use hmac::digest::FixedOutput; use hmac::Mac;