Skip to content

Commit 68117fa

Browse files
rusty1968FerralCoder
authored andcommitted
[test] Hubris adapter traits unit test.
1 parent 2807055 commit 68117fa

File tree

4 files changed

+296
-5
lines changed

4 files changed

+296
-5
lines changed

Cargo.lock

Lines changed: 32 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ subtle = { version = "2", default-features = false }
3030
# Pin to match Hubris ecosystem
3131
rand_core = { version = "0.9", default-features = false }
3232
embedded-hal = "1.0"
33+
heapless = { version = "0.8", default-features = false }

platform/impls/rustcrypto/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,4 @@ cipher = { version = "0.4", default-features = false }
3333
zerocopy = { workspace = true }
3434
zeroize = { workspace = true }
3535
rand_core = { workspace = true }
36+
heapless = { workspace = true }

platform/impls/rustcrypto/src/controller.rs

Lines changed: 262 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,16 @@ use sha2::{Digest as Sha2Digest, Sha256, Sha384, Sha512};
2222

2323
/// A type implementing RustCrypto-based hash/digest owned traits.
2424
/// Compatible with Hubris digest server requirements
25-
pub struct RustCryptoController {
26-
// No state needed - each operation creates its own context
27-
}
25+
/// `RustCrypto`-based cryptographic controller
26+
///
27+
/// Provides software-based cryptographic operations using the `RustCrypto`
28+
/// ecosystem for Hubris and other embedded environments.
29+
pub struct RustCryptoController {}
2830

2931
impl RustCryptoController {
30-
pub fn new() -> Self {
32+
/// Creates a new `RustCrypto` controller instance
33+
#[must_use]
34+
pub const fn new() -> Self {
3135
Self {}
3236
}
3337
}
@@ -534,11 +538,12 @@ impl HubrisDigestDevice for RustCryptoController {
534538
}
535539

536540
#[cfg(test)]
541+
#[allow(clippy::unwrap_used)]
537542
mod tests {
538543
use super::*;
544+
use heapless::Vec;
539545

540546
#[test]
541-
#[allow(clippy::unwrap_used)]
542547
fn test_digest_operations() {
543548
// Test SHA-256
544549
let controller = RustCryptoController::new();
@@ -677,4 +682,256 @@ mod tests {
677682
assert!(result.is_err());
678683
assert_eq!(result.unwrap_err(), CryptoError::InvalidKeyLength);
679684
}
685+
686+
#[test]
687+
fn test_hubris_digest_integration() {
688+
use openprot_platform_traits_hubris::{HubrisDigestDevice, HubrisDigestOneShot};
689+
690+
let controller = RustCryptoController::new();
691+
692+
// Test SHA-256 one-shot operation
693+
let data = b"Hello, Hubris!";
694+
let result = controller.digest_sha256_oneshot(data);
695+
assert!(result.is_ok());
696+
let digest = result.unwrap();
697+
assert_eq!(digest.value.len(), 8); // 8 u32 words = 32 bytes
698+
699+
// Test digest context initialization
700+
let controller = RustCryptoController::new();
701+
let ctx_result = controller.init_digest_sha256();
702+
assert!(ctx_result.is_ok());
703+
}
704+
705+
#[test]
706+
fn test_hubris_hmac_integration() {
707+
use openprot_platform_traits_hubris::{HubrisDigestDevice, HubrisDigestOneShot};
708+
709+
let controller = RustCryptoController::new();
710+
let key_data = b"test_key_123456789012345678901234"; // 32 bytes
711+
712+
// Test HMAC-SHA256 one-shot operation
713+
let data = b"Hello, Hubris HMAC!";
714+
let result = controller.hmac_sha256_oneshot(key_data, data);
715+
assert!(result.is_ok());
716+
let mac = result.unwrap();
717+
assert_eq!(mac.len(), 32); // SHA-256 output is 32 bytes
718+
719+
// Test HMAC context initialization
720+
let controller = RustCryptoController::new();
721+
let key = SecureOwnedKey::new(key_data).unwrap();
722+
let ctx_result = controller.init_hmac_sha256(key);
723+
assert!(ctx_result.is_ok());
724+
}
725+
726+
#[test]
727+
fn test_hubris_key_creation() {
728+
use openprot_platform_traits_hubris::HubrisDigestDevice;
729+
730+
// Test key creation with valid sizes
731+
let small_key = b"small";
732+
let result = RustCryptoController::create_hmac_key(small_key);
733+
assert!(result.is_ok());
734+
735+
// Test with maximum key size using heapless::Vec for realistic embedded testing
736+
let mut max_key: Vec<u8, 256> = Vec::new(); // heapless::Vec with capacity 256
737+
max_key
738+
.resize(RustCryptoController::MAX_KEY_SIZE, 0)
739+
.unwrap();
740+
let result = RustCryptoController::create_hmac_key(&max_key);
741+
assert!(result.is_ok());
742+
743+
// Test key creation with oversized key
744+
let mut oversized_key: Vec<u8, 256> = Vec::new();
745+
oversized_key
746+
.resize(RustCryptoController::MAX_KEY_SIZE + 1, 0)
747+
.unwrap();
748+
let result = RustCryptoController::create_hmac_key(&oversized_key);
749+
assert!(result.is_err());
750+
}
751+
752+
#[test]
753+
fn test_hubris_error_mapping() {
754+
use openprot_platform_traits_hubris::{HubrisCryptoError, HubrisDigestDevice};
755+
756+
// Test error mapping for oversized keys using heapless::Vec
757+
let mut oversized_key: Vec<u8, 256> = Vec::new();
758+
oversized_key
759+
.resize(RustCryptoController::MAX_KEY_SIZE + 1, 0)
760+
.unwrap();
761+
let result = RustCryptoController::create_hmac_key(&oversized_key);
762+
assert_eq!(result.unwrap_err(), HubrisCryptoError::InvalidKeyLength);
763+
}
764+
765+
#[test]
766+
fn test_hubris_sha256_correctness() {
767+
use openprot_platform_traits_hubris::HubrisDigestOneShot;
768+
769+
let controller = RustCryptoController::new();
770+
771+
// Test with known SHA-256 test vector
772+
// Input: "abc"
773+
// Expected SHA-256: ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
774+
let data = b"abc";
775+
let result = controller.digest_sha256_oneshot(data).unwrap();
776+
777+
// Use the proper as_bytes() method for comparison
778+
let digest_bytes = result.as_bytes();
779+
780+
let expected = [
781+
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
782+
0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
783+
0xf2, 0x00, 0x15, 0xad,
784+
];
785+
786+
assert_eq!(
787+
digest_bytes, expected,
788+
"SHA-256 digest does not match expected test vector"
789+
);
790+
}
791+
792+
#[test]
793+
fn test_hubris_hmac_sha256_correctness() {
794+
use openprot_platform_traits_hubris::HubrisDigestOneShot;
795+
796+
let controller = RustCryptoController::new();
797+
798+
// Test with known HMAC-SHA256 test vector from RFC 4231
799+
// Key: "key" (0x6b6579)
800+
// Data: "The quick brown fox jumps over the lazy dog"
801+
// Expected: f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
802+
let key = b"key";
803+
let data = b"The quick brown fox jumps over the lazy dog";
804+
805+
let result = controller.hmac_sha256_oneshot(key, data).unwrap();
806+
807+
let expected = [
808+
0xf7, 0xbc, 0x83, 0xf4, 0x30, 0x53, 0x84, 0x24, 0xb1, 0x32, 0x98, 0xe6, 0xaa, 0x6f,
809+
0xb1, 0x43, 0xef, 0x4d, 0x59, 0xa1, 0x49, 0x46, 0x17, 0x59, 0x97, 0x47, 0x9d, 0xbc,
810+
0x2d, 0x1a, 0x3c, 0xd8,
811+
];
812+
813+
assert_eq!(
814+
result, expected,
815+
"HMAC-SHA256 does not match expected test vector"
816+
);
817+
}
818+
819+
#[test]
820+
fn test_hubris_digest_context_operations() {
821+
use openprot_hal_blocking::digest::owned::DigestOp;
822+
use openprot_platform_traits_hubris::HubrisDigestDevice;
823+
824+
let controller = RustCryptoController::new();
825+
826+
// Test incremental hashing with known result
827+
// Hash "abc" in parts: "a" + "bc"
828+
let ctx = controller.init_digest_sha256().unwrap();
829+
let ctx = ctx.update(b"a").unwrap();
830+
let ctx = ctx.update(b"bc").unwrap();
831+
let (result, _controller) = ctx.finalize().unwrap();
832+
833+
// Should match the same result as hashing "abc" at once
834+
let digest_bytes = result.as_bytes();
835+
836+
let expected = [
837+
0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae,
838+
0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, 0xb4, 0x10, 0xff, 0x61,
839+
0xf2, 0x00, 0x15, 0xad,
840+
];
841+
842+
assert_eq!(
843+
digest_bytes, expected,
844+
"Incremental SHA-256 digest does not match expected result"
845+
);
846+
}
847+
848+
#[test]
849+
fn test_hubris_hmac_context_operations() {
850+
use openprot_hal_blocking::mac::owned::MacOp;
851+
use openprot_platform_traits_hubris::HubrisDigestDevice;
852+
853+
let controller = RustCryptoController::new();
854+
let key_data = b"key";
855+
let key = SecureOwnedKey::new(key_data).unwrap();
856+
857+
// Test incremental HMAC with known result
858+
// HMAC "The quick brown fox jumps over the lazy dog" in parts
859+
let ctx = controller.init_hmac_sha256(key).unwrap();
860+
let ctx = ctx.update(b"The quick brown fox ").unwrap();
861+
let ctx = ctx.update(b"jumps over the lazy dog").unwrap();
862+
let (result, _controller) = ctx.finalize().unwrap();
863+
864+
let expected = [
865+
0xf7, 0xbc, 0x83, 0xf4, 0x30, 0x53, 0x84, 0x24, 0xb1, 0x32, 0x98, 0xe6, 0xaa, 0x6f,
866+
0xb1, 0x43, 0xef, 0x4d, 0x59, 0xa1, 0x49, 0x46, 0x17, 0x59, 0x97, 0x47, 0x9d, 0xbc,
867+
0x2d, 0x1a, 0x3c, 0xd8,
868+
];
869+
870+
assert_eq!(
871+
result, expected,
872+
"Incremental HMAC-SHA256 does not match expected result"
873+
);
874+
}
875+
876+
#[test]
877+
fn test_hubris_comprehensive_crypto_demo() {
878+
use openprot_hal_blocking::digest::owned::DigestOp;
879+
use openprot_hal_blocking::mac::owned::MacOp;
880+
use openprot_platform_traits_hubris::{HubrisDigestDevice, HubrisDigestOneShot};
881+
882+
// Test 1: SHA-256 One-shot
883+
let controller = RustCryptoController::new();
884+
let message = b"Hello, Hubris crypto world!";
885+
let digest = controller.digest_sha256_oneshot(message).unwrap();
886+
assert_eq!(digest.as_bytes().len(), 32); // SHA-256 produces 32 bytes
887+
888+
// Test 2: Incremental SHA-256
889+
let controller = RustCryptoController::new();
890+
let ctx = controller.init_digest_sha256().unwrap();
891+
let ctx = ctx.update(b"Hello, ").unwrap();
892+
let ctx = ctx.update(b"Hubris crypto ").unwrap();
893+
let ctx = ctx.update(b"world!").unwrap();
894+
let (digest_inc, _controller_recovered) = ctx.finalize().unwrap();
895+
assert_eq!(digest.as_bytes(), digest_inc.as_bytes());
896+
897+
// Test 3: HMAC-SHA256 One-shot
898+
let controller = RustCryptoController::new();
899+
let key_data = b"secure_key_for_hubris_testing_123";
900+
let hmac = controller.hmac_sha256_oneshot(key_data, message).unwrap();
901+
assert_eq!(hmac.len(), 32); // HMAC-SHA256 produces 32 bytes
902+
903+
// Test 4: Incremental HMAC-SHA256
904+
let controller = RustCryptoController::new();
905+
let key = SecureOwnedKey::new(key_data).unwrap();
906+
let ctx = controller.init_hmac_sha256(key).unwrap();
907+
let ctx = ctx.update(b"Hello, ").unwrap();
908+
let ctx = ctx.update(b"Hubris crypto ").unwrap();
909+
let ctx = ctx.update(b"world!").unwrap();
910+
let (hmac_inc, _controller_recovered) = ctx.finalize().unwrap();
911+
assert_eq!(hmac, hmac_inc);
912+
913+
// Test 5: Key Management with heapless::Vec (embedded-friendly)
914+
let mut dynamic_key: Vec<u8, 64> = Vec::new();
915+
dynamic_key
916+
.extend_from_slice(b"dynamic_embedded_key")
917+
.unwrap();
918+
let key_result = RustCryptoController::create_hmac_key(&dynamic_key);
919+
assert!(key_result.is_ok());
920+
921+
// Test 6: Error handling with oversized keys
922+
let mut oversized_key: Vec<u8, 256> = Vec::new();
923+
oversized_key
924+
.resize(RustCryptoController::MAX_KEY_SIZE + 1, 0)
925+
.unwrap();
926+
let error_result = RustCryptoController::create_hmac_key(&oversized_key);
927+
assert!(error_result.is_err());
928+
929+
// All operations completed successfully - demonstrates that:
930+
// ✅ RustCrypto backend is fully functional
931+
// ✅ Hubris platform traits properly implemented
932+
// ✅ Memory-safe operations in no_std environment
933+
// ✅ Cryptographically correct results verified
934+
// ✅ heapless::Vec integration working
935+
// ✅ Controller recovery after operations working
936+
}
680937
}

0 commit comments

Comments
 (0)