Skip to content
File

Blob: firmware/crates/esp32-radio/src/platform/crypto/self_test.rs

rust103 lines
1//! Small public-vector startup checks for the private native boundary.
2use super::{hashes::Hashes, native, srtp};
3use dimpl::{
4 HashAlgorithm,
5 crypto::{Buf, HashProvider},
6};
7use radio_webrtc::crypto::SrtpProvider;
8 
9#[cfg(feature = "crypto-self-test")]
10mod extended;
11 
12pub(super) fn run() {
13 #[cfg(feature = "crypto-self-test")]
14 extended::run();
15 let reference = str0m_rust_crypto::default_provider();
16 let iv = [0x13; 12];
17 let aad = [0xab; 12];
18 for length in [16, 32] {
19 // Public synthetic keys and inputs; never used for a network session.
20 let key = vec![0x42; length];
21 let mut native_round = [0; 32];
22 let mut reference_round = [0; 32];
23 let mut block = [0; 16];
24 native::ecb(&key, &[0; 16], &mut block).expect("native AES-ECB self-test");
25 if length == 16 {
26 srtp::Provider.srtp_aes_128_ecb_round(&key, &[0; 16], &mut native_round);
27 reference
28 .srtp_provider
29 .srtp_aes_128_ecb_round(&key, &[0; 16], &mut reference_round);
30 } else {
31 srtp::Provider.srtp_aes_256_ecb_round(&key, &[0; 16], &mut native_round);
32 reference
33 .srtp_provider
34 .srtp_aes_256_ecb_round(&key, &[0; 16], &mut reference_round);
35 }
36 assert!(
37 native_round == reference_round && block == reference_round[..16],
38 "AES-ECB self-test mismatch"
39 );
40 for n in [0, 1, 17, 1275] {
41 let clear = vec![0x5a; n];
42 let mut expected = vec![0; n + 16];
43 if length == 16 {
44 reference
45 .srtp_provider
46 .aead_aes_128_gcm()
47 .create_cipher(key[..].try_into().unwrap(), true)
48 .encrypt(&iv, &aad, &clear, &mut expected)
49 .expect("reference GCM");
50 } else {
51 reference
52 .srtp_provider
53 .aead_aes_256_gcm()
54 .create_cipher(key[..].try_into().unwrap(), true)
55 .encrypt(&iv, &aad, &clear, &mut expected)
56 .expect("reference GCM");
57 }
58 let mut buffer = clear.clone();
59 buffer.resize(n + 16, 0);
60 native::gcm_in_place(false, &key, &iv, &aad, &mut buffer, n)
61 .expect("GCM encryption self-test");
62 assert!(buffer == expected, "GCM encryption self-test mismatch");
63 native::gcm_in_place(true, &key, &iv, &aad, &mut buffer, n + 16)
64 .expect("GCM decryption self-test");
65 assert!(buffer[..n] == clear, "GCM decryption self-test mismatch");
66 buffer.copy_from_slice(&expected);
67 buffer[n + 15] ^= 1;
68 assert!(
69 native::gcm_in_place(true, &key, &iv, &aad, &mut buffer, n + 16).is_err(),
70 "GCM accepted a bad tag"
71 );
72 assert!(
73 buffer[..n].iter().all(|byte| *byte == 0),
74 "GCM retained unauthenticated plaintext"
75 );
76 }
77 }
78 for algorithm in [HashAlgorithm::SHA256, HashAlgorithm::SHA384] {
79 let mut actual = Hashes.create_hash(algorithm);
80 let mut expected = dimpl::crypto::rust_crypto::default_provider()
81 .hash_provider
82 .create_hash(algorithm);
83 let mut a = Buf::new();
84 let mut b = Buf::new();
85 for part in [b"a".as_slice(), b"bc", &[0x5a; 1275]] {
86 actual.update(part);
87 expected.update(part);
88 actual.clone_and_finalize(&mut a);
89 expected.clone_and_finalize(&mut b);
90 assert!(a[..] == b[..], "SHA snapshot self-test mismatch");
91 }
92 }
93 let mut mac = [0; 20];
94 native::hmac(160, b"public test key", &[b"a", b"bc"], &mut mac).expect("native HMAC self-test");
95 assert!(
96 mac == reference
97 .sha1_hmac_provider
98 .sha1_hmac(b"public test key", &[b"abc"]),
99 "HMAC self-test mismatch"
100 );
101 super::super::log("Crypto boundary self-tests passed");
102}