From 14739bf960d2bc0f27d506ce876adce9323334a3 Mon Sep 17 00:00:00 2001 From: GroM Date: Thu, 8 Feb 2024 19:29:14 +0100 Subject: [PATCH] Add C Hash function wrappers --- ledger_device_sdk/src/hash.rs | 135 ++++++++++++ ledger_device_sdk/src/hash/blake2.rs | 138 +++++++++++++ ledger_device_sdk/src/hash/ripemd.rs | 51 +++++ ledger_device_sdk/src/hash/sha2.rs | 177 ++++++++++++++++ ledger_device_sdk/src/hash/sha3.rs | 296 +++++++++++++++++++++++++++ ledger_device_sdk/src/lib.rs | 1 + ledger_device_sdk/src/testing.rs | 12 +- ledger_device_sdk/tests/ecc_tests.rs | 8 +- 8 files changed, 807 insertions(+), 11 deletions(-) create mode 100644 ledger_device_sdk/src/hash.rs create mode 100644 ledger_device_sdk/src/hash/blake2.rs create mode 100644 ledger_device_sdk/src/hash/ripemd.rs create mode 100644 ledger_device_sdk/src/hash/sha2.rs create mode 100644 ledger_device_sdk/src/hash/sha3.rs diff --git a/ledger_device_sdk/src/hash.rs b/ledger_device_sdk/src/hash.rs new file mode 100644 index 00000000..15c01d02 --- /dev/null +++ b/ledger_device_sdk/src/hash.rs @@ -0,0 +1,135 @@ +use ledger_secure_sdk_sys::{ + cx_hash_final, cx_hash_get_size, cx_hash_no_throw, cx_hash_t, cx_hash_update, + CX_INVALID_PARAMETER, CX_LAST, CX_OK, +}; + +mod blake2; +mod ripemd; +mod sha2; +mod sha3; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum HashError { + InvalidParameter, + InvalidOutputLength, + InternalError, +} + +impl From for HashError { + fn from(x: u32) -> HashError { + match x { + CX_INVALID_PARAMETER => HashError::InvalidParameter, + _ => HashError::InternalError, + } + } +} + +impl From for u32 { + fn from(e: HashError) -> u32 { + e as u32 + } +} + +pub trait HashInit: Sized { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t; + fn as_ctx(&self) -> &cx_hash_t; + fn new() -> Self; + fn get_size(&mut self) -> usize { + unsafe { cx_hash_get_size(self.as_ctx()) } + } + fn hash(mut self, input: &[u8], output: &mut [u8]) -> Result<(), HashError> { + let output_size = self.get_size(); + if output_size > output.len() { + return Err(HashError::InvalidOutputLength); + } + + let err = unsafe { + cx_hash_no_throw( + self.as_ctx_mut(), + CX_LAST, + input.as_ptr(), + input.len(), + output.as_mut_ptr(), + output.len(), + ) + }; + if err != CX_OK { + Err(err.into()) + } else { + Ok(()) + } + } + fn update(&mut self, input: &[u8]) -> Result<(), HashError> { + let err = unsafe { cx_hash_update(self.as_ctx_mut(), input.as_ptr(), input.len()) }; + if err != CX_OK { + Err(err.into()) + } else { + Ok(()) + } + } + fn finalize(mut self, output: &mut [u8]) -> Result<(), HashError> { + let output_size = self.get_size(); + if output_size > output.len() { + return Err(HashError::InvalidOutputLength); + } + + let err = unsafe { cx_hash_final(self.as_ctx_mut(), output.as_mut_ptr()) }; + if err != CX_OK { + Err(err.into()) + } else { + Ok(()) + } + } +} + +#[cfg(test)] +mod tests { + use crate::assert_eq_err as assert_eq; + use crate::hash::sha2::Sha2_256; + use crate::hash::sha3::*; + use crate::hash::HashInit; + use crate::testing::TestType; + use testmacro::test_item as test; + + const TEST_HASH: &[u8; 29] = b"Not your keys, not your coins"; + + #[test] + fn test_hash() { + let mut keccak = Keccak256::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size = keccak.get_size(); + assert_eq!(ouput_size, 32); + + let _ = keccak.hash(TEST_HASH, &mut output); + + let expected = [ + 0x1f, 0x20, 0x7c, 0xd9, 0xfd, 0x9f, 0x0b, 0x09, 0xb0, 0x04, 0x93, 0x6c, 0xa5, 0xe0, + 0xd3, 0x1b, 0xa1, 0x6c, 0xd6, 0x14, 0x53, 0xaa, 0x28, 0x7e, 0x65, 0xaa, 0x88, 0x25, + 0x3c, 0xdc, 0x1c, 0x94, + ]; + assert_eq!(&output, &expected); + } + + #[test] + fn test_sha2_update() { + let mut hasher = Sha2_256::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size = hasher.get_size(); + assert_eq!(ouput_size, 32); + + let _ = hasher.update(TEST_HASH); + + let _ = hasher.finalize(&mut output); + + let expected = [ + 0x52, 0x49, 0x2e, 0x81, 0x92, 0x16, 0xf3, 0x6b, 0x74, 0x7d, 0xd5, 0xda, 0x70, 0x3a, + 0x26, 0x60, 0x14, 0x34, 0x60, 0x42, 0x42, 0xfa, 0xb2, 0x7e, 0x85, 0x51, 0xe7, 0x82, + 0xa5, 0x11, 0x13, 0x40, + ]; + assert_eq!(&output, &expected); + } +} diff --git a/ledger_device_sdk/src/hash/blake2.rs b/ledger_device_sdk/src/hash/blake2.rs new file mode 100644 index 00000000..97db886c --- /dev/null +++ b/ledger_device_sdk/src/hash/blake2.rs @@ -0,0 +1,138 @@ +use super::HashInit; +use ledger_secure_sdk_sys::{cx_blake2b_init_no_throw, cx_blake2b_t, cx_hash_t}; + +#[derive(Default)] +#[allow(non_camel_case_types)] +pub struct Blake2b_256 { + ctx: cx_blake2b_t, +} + +impl HashInit for Blake2b_256 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Blake2b_256 = Default::default(); + let _err = unsafe { cx_blake2b_init_no_throw(&mut ctx.ctx, 256) }; + ctx + } +} + +#[derive(Default)] +#[allow(non_camel_case_types)] +pub struct Blake2b_384 { + ctx: cx_blake2b_t, +} + +impl HashInit for Blake2b_384 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Blake2b_384 = Default::default(); + let _err = unsafe { cx_blake2b_init_no_throw(&mut ctx.ctx, 384) }; + ctx + } +} + +#[derive(Default)] +#[allow(non_camel_case_types)] +pub struct Blake2b_512 { + ctx: cx_blake2b_t, +} + +impl HashInit for Blake2b_512 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Blake2b_512 = Default::default(); + let _err = unsafe { cx_blake2b_init_no_throw(&mut ctx.ctx, 512) }; + ctx + } +} + +#[cfg(test)] +mod tests { + use crate::assert_eq_err as assert_eq; + use crate::hash::blake2::*; + use crate::testing::TestType; + use testmacro::test_item as test; + + const TEST_HASH: &[u8; 29] = b"Not your keys, not your coins"; + + #[test] + fn test_hash_blake2b256() { + let mut blake2 = Blake2b_256::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size = blake2.get_size(); + assert_eq!(ouput_size, 32); + + let _ = blake2.hash(TEST_HASH, &mut output); + + let expected = [ + 0xcd, 0xa6, 0x49, 0x8e, 0x2f, 0x89, 0x71, 0xe8, 0x4e, 0xd5, 0x68, 0x2e, 0x3d, 0x47, + 0x9c, 0xcc, 0x2c, 0xce, 0x7f, 0x37, 0xac, 0x92, 0x9c, 0xa0, 0xb0, 0x41, 0xb2, 0xdd, + 0x06, 0xa9, 0xf3, 0xcb, + ]; + assert_eq!(&output, &expected); + } + + #[test] + fn test_hash_blake2b384() { + let mut blake2 = Blake2b_384::new(); + + let mut output: [u8; 48] = [0u8; 48]; + + let ouput_size = blake2.get_size(); + assert_eq!(ouput_size, 48); + + let _ = blake2.hash(TEST_HASH, &mut output); + + let expected = [ + 0x5f, 0x03, 0x04, 0x77, 0x92, 0x5e, 0x91, 0x29, 0xf9, 0xb8, 0xef, 0xf9, 0x88, 0x29, + 0x04, 0xf4, 0x4f, 0x65, 0x3b, 0xef, 0xf8, 0x21, 0xca, 0x48, 0x68, 0xa7, 0xbe, 0x46, + 0x1c, 0x45, 0x82, 0xb3, 0x3d, 0xd7, 0x7b, 0x9e, 0x91, 0x9a, 0xfe, 0x1c, 0x3b, 0xed, + 0x4b, 0x8f, 0x3c, 0x5d, 0xde, 0x53, + ]; + assert_eq!(&output, &expected); + } + + #[test] + fn test_hash_blake2b512() { + let mut blake2 = Blake2b_512::new(); + + let mut output: [u8; 64] = [0u8; 64]; + + let ouput_size = blake2.get_size(); + assert_eq!(ouput_size, 64); + + let _ = blake2.hash(TEST_HASH, &mut output); + + let expected = [ + 0xc2, 0xe0, 0xfe, 0x8c, 0xb7, 0x83, 0x43, 0x7c, 0x8f, 0x36, 0x89, 0x48, 0xc4, 0x7a, + 0x9c, 0x7c, 0x27, 0xa3, 0xb5, 0x98, 0x7a, 0x2d, 0x1b, 0x3b, 0xab, 0x48, 0x3d, 0xd6, + 0xf6, 0x4c, 0xd1, 0x20, 0x7d, 0x72, 0x62, 0xb5, 0x35, 0xfe, 0x3f, 0x86, 0xad, 0x0c, + 0x5f, 0x33, 0x4e, 0x55, 0x07, 0x64, 0x49, 0x7c, 0x11, 0xd5, 0xbd, 0x6a, 0x44, 0x2a, + 0x9c, 0x2e, 0x6a, 0xab, 0xf9, 0x31, 0xc0, 0xab, + ]; + assert_eq!(&output, &expected); + } +} diff --git a/ledger_device_sdk/src/hash/ripemd.rs b/ledger_device_sdk/src/hash/ripemd.rs new file mode 100644 index 00000000..1782848b --- /dev/null +++ b/ledger_device_sdk/src/hash/ripemd.rs @@ -0,0 +1,51 @@ +use super::HashInit; +use ledger_secure_sdk_sys::{cx_hash_t, cx_ripemd160_init_no_throw, cx_ripemd160_t}; + +#[derive(Default)] +pub struct Ripemd160 { + ctx: cx_ripemd160_t, +} + +impl HashInit for Ripemd160 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Ripemd160 = Default::default(); + let _err = unsafe { cx_ripemd160_init_no_throw(&mut ctx.ctx) }; + ctx + } +} + +#[cfg(test)] +mod tests { + use crate::assert_eq_err as assert_eq; + use crate::hash::ripemd::*; + use crate::testing::TestType; + use testmacro::test_item as test; + + const TEST_HASH: &[u8; 29] = b"Not your keys, not your coins"; + + #[test] + fn test_hash_ripemd160() { + let mut ripemd = Ripemd160::new(); + + let mut output: [u8; 20] = [0u8; 20]; + + let ouput_size = ripemd.get_size(); + assert_eq!(ouput_size, 20); + + let _ = ripemd.hash(TEST_HASH, &mut output); + + let expected = [ + 0x75, 0x0f, 0x75, 0x73, 0x6a, 0x34, 0xac, 0x02, 0xd0, 0x72, 0xec, 0x2a, 0xf5, 0xf7, + 0x1d, 0x16, 0xc2, 0x6f, 0x63, 0x23, + ]; + assert_eq!(&output, &expected); + } +} diff --git a/ledger_device_sdk/src/hash/sha2.rs b/ledger_device_sdk/src/hash/sha2.rs new file mode 100644 index 00000000..74dc1a5b --- /dev/null +++ b/ledger_device_sdk/src/hash/sha2.rs @@ -0,0 +1,177 @@ +use super::HashInit; +use ledger_secure_sdk_sys::{ + cx_hash_t, cx_sha224_init_no_throw, cx_sha256_init_no_throw, cx_sha256_t, + cx_sha384_init_no_throw, cx_sha512_init_no_throw, cx_sha512_t, +}; + +#[derive(Default)] +pub struct Sha2_224 { + ctx: cx_sha256_t, +} + +impl HashInit for Sha2_224 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha2_224 = Default::default(); + let _err = unsafe { cx_sha224_init_no_throw(&mut ctx.ctx) }; + ctx + } +} + +#[derive(Default)] +pub struct Sha2_256 { + ctx: cx_sha256_t, +} + +impl HashInit for Sha2_256 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha2_256 = Default::default(); + let _err = unsafe { cx_sha256_init_no_throw(&mut ctx.ctx) }; + ctx + } +} + +#[derive(Default)] +pub struct Sha2_384 { + ctx: cx_sha512_t, +} + +impl HashInit for Sha2_384 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha2_384 = Default::default(); + let _err = unsafe { cx_sha384_init_no_throw(&mut ctx.ctx) }; + ctx + } +} + +#[derive(Default)] +pub struct Sha2_512 { + ctx: cx_sha512_t, +} + +impl HashInit for Sha2_512 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha2_512 = Default::default(); + let _err = unsafe { cx_sha512_init_no_throw(&mut ctx.ctx) }; + ctx + } +} + +#[cfg(test)] +mod tests { + use crate::assert_eq_err as assert_eq; + use crate::hash::sha2::*; + use crate::testing::TestType; + use testmacro::test_item as test; + + const TEST_HASH: &[u8; 29] = b"Not your keys, not your coins"; + + #[test] + fn test_hash_sha2224() { + let mut sha2 = Sha2_224::new(); + + let mut output: [u8; 28] = [0u8; 28]; + + let ouput_size = sha2.get_size(); + assert_eq!(ouput_size, 28); + + let _ = sha2.hash(TEST_HASH, &mut output); + + let expected = [ + 0x5a, 0x5b, 0xea, 0xa1, 0x3f, 0x5d, 0xf3, 0xd8, 0x5a, 0xc8, 0x62, 0x44, 0x95, 0x9b, + 0xa2, 0x8e, 0xed, 0x08, 0x65, 0xa2, 0xcd, 0x10, 0xd1, 0x5c, 0xce, 0x47, 0x9a, 0x2a, + ]; + assert_eq!(&output, &expected); + } + + #[test] + fn test_hash_sha2256() { + let mut sha2 = Sha2_256::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size = sha2.get_size(); + assert_eq!(ouput_size, 32); + + let _ = sha2.hash(TEST_HASH, &mut output); + + let expected = [ + 0x52, 0x49, 0x2e, 0x81, 0x92, 0x16, 0xf3, 0x6b, 0x74, 0x7d, 0xd5, 0xda, 0x70, 0x3a, + 0x26, 0x60, 0x14, 0x34, 0x60, 0x42, 0x42, 0xfa, 0xb2, 0x7e, 0x85, 0x51, 0xe7, 0x82, + 0xa5, 0x11, 0x13, 0x40, + ]; + assert_eq!(&output, &expected); + } + + #[test] + fn test_hash_sha2384() { + let mut sha2 = Sha2_384::new(); + + let mut output: [u8; 48] = [0u8; 48]; + + let ouput_size = sha2.get_size(); + assert_eq!(ouput_size, 48); + + let _ = sha2.hash(TEST_HASH, &mut output); + + let expected = [ + 0x11, 0xe3, 0xe7, 0xec, 0x0d, 0xc5, 0x81, 0x87, 0x8c, 0x35, 0xc6, 0xc8, 0x07, 0x15, + 0x65, 0x53, 0x26, 0x1d, 0xb1, 0x7e, 0x32, 0x8c, 0xf8, 0x7d, 0x37, 0xbe, 0x05, 0x35, + 0xf8, 0x45, 0x8d, 0x7c, 0xc9, 0x15, 0x74, 0xa2, 0x3f, 0x4f, 0x3e, 0x5f, 0x98, 0x23, + 0xc7, 0xaa, 0x3a, 0xff, 0xf1, 0x59, + ]; + assert_eq!(&output, &expected); + } + + #[test] + fn test_hash_sha2512() { + let mut sha2 = Sha2_512::new(); + + let mut output: [u8; 64] = [0u8; 64]; + + let ouput_size = sha2.get_size(); + assert_eq!(ouput_size, 64); + + let _ = sha2.hash(TEST_HASH, &mut output); + + let expected = [ + 0xf0, 0xe9, 0x96, 0x75, 0x81, 0xc0, 0xdb, 0x4c, 0x8e, 0xc0, 0xeb, 0xb2, 0x53, 0xa7, + 0xff, 0x8d, 0x8a, 0x1a, 0x69, 0x06, 0xbc, 0x1b, 0x76, 0x0c, 0x23, 0x09, 0x9c, 0xc5, + 0xe4, 0xf7, 0xea, 0x19, 0x07, 0x73, 0x57, 0x07, 0x8a, 0x66, 0x6b, 0x45, 0x1c, 0xa2, + 0x32, 0xa4, 0xa7, 0x0c, 0xa1, 0x8d, 0xaa, 0x4e, 0xd0, 0x5a, 0xdd, 0x03, 0x02, 0x05, + 0x04, 0xdf, 0xdd, 0x93, 0x1d, 0x54, 0x6f, 0xfd, + ]; + assert_eq!(&output, &expected); + } +} diff --git a/ledger_device_sdk/src/hash/sha3.rs b/ledger_device_sdk/src/hash/sha3.rs new file mode 100644 index 00000000..115213ff --- /dev/null +++ b/ledger_device_sdk/src/hash/sha3.rs @@ -0,0 +1,296 @@ +use super::HashInit; +use ledger_secure_sdk_sys::{ + cx_hash_t, cx_keccak_init_no_throw, cx_sha3_init_no_throw, cx_sha3_t, + cx_shake128_init_no_throw, cx_shake256_init_no_throw, +}; + +#[derive(Default)] +pub struct Keccak256 { + ctx: cx_sha3_t, +} + +impl HashInit for Keccak256 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Keccak256 = Default::default(); + let _err = unsafe { cx_keccak_init_no_throw(&mut ctx.ctx, 256) }; + ctx + } +} + +#[derive(Default)] +pub struct Sha3_224 { + ctx: cx_sha3_t, +} + +impl HashInit for Sha3_224 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha3_224 = Default::default(); + let _err = unsafe { cx_sha3_init_no_throw(&mut ctx.ctx, 224) }; + ctx + } +} + +#[derive(Default)] +pub struct Sha3_256 { + ctx: cx_sha3_t, +} + +impl HashInit for Sha3_256 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha3_256 = Default::default(); + let _err = unsafe { cx_sha3_init_no_throw(&mut ctx.ctx, 256) }; + ctx + } +} + +#[derive(Default)] +pub struct Sha3_384 { + ctx: cx_sha3_t, +} + +impl HashInit for Sha3_384 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha3_384 = Default::default(); + let _err = unsafe { cx_sha3_init_no_throw(&mut ctx.ctx, 384) }; + ctx + } +} + +#[derive(Default)] +pub struct Sha3_512 { + ctx: cx_sha3_t, +} + +impl HashInit for Sha3_512 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Sha3_512 = Default::default(); + let _err = unsafe { cx_sha3_init_no_throw(&mut ctx.ctx, 512) }; + ctx + } +} + +#[derive(Default)] +pub struct Shake128 { + ctx: cx_sha3_t, +} + +impl HashInit for Shake128 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Shake128 = Default::default(); + let _err = unsafe { cx_shake128_init_no_throw(&mut ctx.ctx, 128) }; + ctx + } +} + +#[derive(Default)] +pub struct Shake256 { + ctx: cx_sha3_t, +} + +impl HashInit for Shake256 { + fn as_ctx_mut(&mut self) -> &mut cx_hash_t { + &mut self.ctx.header + } + + fn as_ctx(&self) -> &cx_hash_t { + &self.ctx.header + } + + fn new() -> Self { + let mut ctx: Shake256 = Default::default(); + let _err = unsafe { cx_shake256_init_no_throw(&mut ctx.ctx, 256) }; + ctx + } +} + +#[cfg(test)] +mod tests { + use crate::assert_eq_err as assert_eq; + use crate::hash::sha3::*; + use crate::testing::TestType; + use testmacro::test_item as test; + + const TEST_HASH: &[u8; 29] = b"Not your keys, not your coins"; + + #[test] + fn test_hash_keccak() { + let mut keccak = Keccak256::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size = keccak.get_size(); + assert_eq!(ouput_size, 32); + + let _ = keccak.hash(TEST_HASH, &mut output); + + let expected = [ + 0x1f, 0x20, 0x7c, 0xd9, 0xfd, 0x9f, 0x0b, 0x09, 0xb0, 0x04, 0x93, 0x6c, 0xa5, 0xe0, + 0xd3, 0x1b, 0xa1, 0x6c, 0xd6, 0x14, 0x53, 0xaa, 0x28, 0x7e, 0x65, 0xaa, 0x88, 0x25, + 0x3c, 0xdc, 0x1c, 0x94, + ]; + assert_eq!(&output, &expected); + } + + #[test] + fn test_hash_sha3224() { + let mut sha3224 = Sha3_224::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size: usize = sha3224.get_size(); + assert_eq!(ouput_size, 28); + + let _ = sha3224.hash(TEST_HASH, &mut output); + + let expected = [ + 0x92, 0xd0, 0x94, 0x85, 0xb4, 0x74, 0xdc, 0x58, 0xcc, 0xbb, 0x03, 0xb5, 0x0e, 0x1c, + 0x1c, 0xe2, 0xab, 0x33, 0xd5, 0xf2, 0xf9, 0xbd, 0xfd, 0xda, 0xcd, 0x88, 0xc6, 0xfc, + ]; + assert_eq!(&output[..28], &expected); + } + + #[test] + fn test_hash_sha3256() { + let mut sha3256 = Sha3_256::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size: usize = sha3256.get_size(); + assert_eq!(ouput_size, 32); + + let _ = sha3256.hash(TEST_HASH, &mut output); + + let expected = [ + 0x80, 0x8b, 0x0a, 0xd9, 0xdd, 0x0f, 0xe7, 0x6f, 0x8d, 0xb4, 0xbb, 0x99, 0xe6, 0x3e, + 0x9d, 0x24, 0xce, 0xa6, 0x4c, 0xfc, 0xdf, 0x93, 0x7a, 0xdb, 0xca, 0x9a, 0xe1, 0x1f, + 0x27, 0x3a, 0x00, 0xb7, + ]; + assert_eq!(&output[..32], &expected); + } + + #[test] + fn test_hash_sha3384() { + let mut sha3384 = Sha3_384::new(); + + let mut output: [u8; 48] = [0u8; 48]; + + let ouput_size: usize = sha3384.get_size(); + assert_eq!(ouput_size, 48); + + let _ = sha3384.hash(TEST_HASH, &mut output); + + let expected = [ + 0x16, 0xdd, 0xbe, 0xd5, 0xf8, 0x95, 0xf9, 0x04, 0xe9, 0xb8, 0xc2, 0x71, 0xe9, 0xa0, + 0x66, 0x7d, 0xa4, 0x35, 0x7e, 0xd9, 0x87, 0x4b, 0x27, 0x23, 0x00, 0xf9, 0xd5, 0x10, + 0x55, 0xd5, 0x6c, 0x65, 0xe3, 0x3d, 0x83, 0xd7, 0xff, 0x8e, 0xab, 0x98, 0x80, 0x60, + 0xe5, 0x9c, 0x1a, 0x34, 0xe7, 0xdc, + ]; + assert_eq!(&output[..48], &expected); + } + + #[test] + fn test_hash_sha3512() { + let mut sha3512 = Sha3_512::new(); + + let mut output: [u8; 64] = [0u8; 64]; + + let ouput_size: usize = sha3512.get_size(); + assert_eq!(ouput_size, 64); + + let _ = sha3512.hash(TEST_HASH, &mut output); + + let expected = [ + 0x4e, 0x81, 0x24, 0xc2, 0xed, 0x1e, 0x9a, 0x1c, 0x60, 0x0f, 0xc0, 0x6b, 0x49, 0xd3, + 0xa3, 0x54, 0x28, 0x81, 0x86, 0x62, 0xf0, 0xcd, 0x95, 0x1d, 0x67, 0x58, 0x3d, 0x8d, + 0x28, 0xab, 0x97, 0x9a, 0x56, 0xab, 0x57, 0xa3, 0x78, 0x15, 0x01, 0x86, 0x6a, 0x00, + 0xf3, 0x89, 0x11, 0x7d, 0x7e, 0x47, 0x84, 0xcd, 0x0c, 0x00, 0x25, 0xad, 0xac, 0xbe, + 0x00, 0xb2, 0xf5, 0xf2, 0x6e, 0x0d, 0x61, 0x59, + ]; + assert_eq!(&output[..64], &expected); + } + + #[test] + fn test_hash_shake128() { + let mut shake128 = Shake128::new(); + + let mut output: [u8; 16] = [0u8; 16]; + + let ouput_size: usize = shake128.get_size(); + assert_eq!(ouput_size, 16); + + let _ = shake128.hash(TEST_HASH, &mut output); + + let expected = [ + 0x45, 0xd9, 0xa1, 0x61, 0x7b, 0x0d, 0x7b, 0xb1, 0xf1, 0x09, 0x63, 0xe1, 0xb0, 0xa5, + 0xaa, 0x2c, + ]; + assert_eq!(&output[..16], &expected); + } + + #[test] + fn test_hash_shake256() { + let mut shake256 = Shake256::new(); + + let mut output: [u8; 32] = [0u8; 32]; + + let ouput_size: usize = shake256.get_size(); + assert_eq!(ouput_size, 32); + + let _ = shake256.hash(TEST_HASH, &mut output); + + let expected = [ + 0x3d, 0x51, 0xd1, 0xfc, 0x5e, 0x2a, 0x3e, 0x4b, 0x9c, 0xdf, 0x2b, 0x03, 0x18, 0xf5, + 0xd1, 0x91, 0x87, 0x4d, 0x52, 0xc1, 0x8c, 0x7b, 0x33, 0x36, 0x52, 0x7b, 0x0b, 0x64, + 0x28, 0xfa, 0xad, 0xf1, + ]; + assert_eq!(&output[..32], &expected); + } +} diff --git a/ledger_device_sdk/src/lib.rs b/ledger_device_sdk/src/lib.rs index 0dae2996..bab04926 100644 --- a/ledger_device_sdk/src/lib.rs +++ b/ledger_device_sdk/src/lib.rs @@ -13,6 +13,7 @@ pub mod ble; #[cfg(feature = "ccid")] pub mod ccid; pub mod ecc; +pub mod hash; pub mod io; pub mod nvm; pub mod random; diff --git a/ledger_device_sdk/src/testing.rs b/ledger_device_sdk/src/testing.rs index 1cebb21c..393c633c 100644 --- a/ledger_device_sdk/src/testing.rs +++ b/ledger_device_sdk/src/testing.rs @@ -53,28 +53,26 @@ pub struct TestType { /// using semihosting. Only reports 'Ok' or 'fail'. #[cfg(feature = "speculos")] pub fn sdk_test_runner(tests: &[&TestType]) { - use core::ffi::c_void; - use ledger_secure_sdk_sys::{pic, pic_rs}; let mut failures = 0; debug_print("--- Tests ---\n"); for test_ in tests { // (ノಠ益ಠ)ノ彡ꓛIꓒ - let test = pic_rs(*test_); + let test = *test_; let modname; let name; unsafe { - let t = pic(test.modname.as_ptr() as *mut c_void) as *const u8; + let t = test.modname.as_ptr() as *const u8; let t = core::ptr::slice_from_raw_parts(t, test.modname.len()); let t: &[u8] = core::mem::transmute(t); modname = core::str::from_utf8_unchecked(t); - let t = pic(test.name.as_ptr() as *mut c_void) as *const u8; + let t = test.name.as_ptr() as *const u8; let t = core::ptr::slice_from_raw_parts(t, test.name.len()); let t: &[u8] = core::mem::transmute(t); name = core::str::from_utf8_unchecked(t); } - let fp = unsafe { pic(test.f as *mut c_void) }; - let fp: fn() -> Result<(), ()> = unsafe { core::mem::transmute(fp) }; + let fp = test.f; + //let fp: fn() -> Result<(), ()> = unsafe { core::mem::transmute(fp) }; let res = fp(); match res { Ok(()) => debug_print("\x1b[1;32m ok \x1b[0m"), diff --git a/ledger_device_sdk/tests/ecc_tests.rs b/ledger_device_sdk/tests/ecc_tests.rs index dcc88f55..036ab4f0 100644 --- a/ledger_device_sdk/tests/ecc_tests.rs +++ b/ledger_device_sdk/tests/ecc_tests.rs @@ -5,7 +5,7 @@ #![test_runner(ledger_device_sdk::testing::sdk_test_runner)] use core::panic::PanicInfo; -use ledger_device_sdk::testing::{debug_print, test_panic, to_hex, TestType}; +use ledger_device_sdk::testing::{test_panic, TestType}; use testmacro::test_item as test; #[panic_handler] @@ -30,7 +30,7 @@ fn test_secp256k1() { let _priv_key = Secp256k1::new(); let _priv_key = Secp256k1::from(&key); - let (priv_key, cc) = Secp256k1::derive_from_path(&PATH); + let (priv_key, _cc) = Secp256k1::derive_from_path(&PATH); let hash = b"Not your Keys, not your Coins"; @@ -47,7 +47,7 @@ fn test_secp256r1() { let _priv_key = Secp256r1::new(); let _priv_key = Secp256r1::from(&key); - let (priv_key, cc) = Secp256r1::derive_from_path(&PATH); + let (priv_key, _cc) = Secp256r1::derive_from_path(&PATH); let hash = b"Not your Keys, not your Coins"; @@ -64,7 +64,7 @@ fn test_stark256() { let _priv_key = Stark256::new(); let _priv_key = Stark256::from(&key); - let (priv_key, cc) = Stark256::derive_from_path(&PATH); + let (priv_key, _cc) = Stark256::derive_from_path(&PATH); let hash = b"Not your Keys, not your Coins";