Skip to content
File

Blob: firmware/vendor/str0m/tests/crypto-compliance.rs

rust524 lines
1/// Test algorithm implementations for the CryptoProvider
2///
3/// This contains tests run against the installed crypto provider to verify
4/// hash, cipher and signature implementations against known test vectors.
5use str0m::crypto::CryptoProvider;
6 
7mod common;
8use common::init_crypto_default;
9 
10fn get_provider() -> &'static CryptoProvider {
11 init_crypto_default();
12 CryptoProvider::get_default().unwrap()
13}
14 
15/// Convert an ASCII hex array into a byte array at compile time.
16macro_rules! hex_as_bytes {
17 ($input:expr) => {{
18 const fn from_hex_char(c: u8) -> u8 {
19 match c {
20 b'0'..=b'9' => c - b'0',
21 b'a'..=b'f' => c - b'a' + 10,
22 b'A'..=b'F' => c - b'A' + 10,
23 _ => panic!("Invalid hex character"),
24 }
25 }
26 
27 const INPUT: &[u8] = $input;
28 const LEN: usize = INPUT.len();
29 const OUTPUT_LEN: usize = LEN / 2;
30 
31 const fn convert() -> [u8; OUTPUT_LEN] {
32 assert!(LEN % 2 == 0, "Hex string length must be even");
33 
34 let mut out = [0u8; OUTPUT_LEN];
35 let mut i = 0;
36 while i < LEN {
37 out[i / 2] = (from_hex_char(INPUT[i]) << 4) | from_hex_char(INPUT[i + 1]);
38 i += 2;
39 }
40 out
41 }
42 
43 convert()
44 }};
45}
46 
47mod sha256 {
48 fn verify_test_vector(input: &[u8], expected: &[u8; 32]) {
49 let sha256_provider = super::get_provider().sha256_provider;
50 let hash = sha256_provider.sha256(input);
51 assert_eq!(hash, *expected);
52 }
53 
54 #[test]
55 fn test_hello_world() {
56 verify_test_vector(
57 b"hello world",
58 &hex_as_bytes!(b"b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"),
59 );
60 }
61 
62 #[test]
63 fn test_empty() {
64 // SHA-256 of "" - NIST test vector
65 verify_test_vector(
66 b"",
67 &hex_as_bytes!(b"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"),
68 );
69 }
70 
71 #[test]
72 fn test_abc() {
73 // SHA-256 of "abc" - NIST test vector
74 verify_test_vector(
75 b"abc",
76 &hex_as_bytes!(b"ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"),
77 );
78 }
79}
80 
81mod sha1_hmac {
82 fn verify_test_vector(key: &[u8], payloads: &[&[u8]], expected: &[u8; 20]) {
83 let sha1_hmac_provider = super::get_provider().sha1_hmac_provider;
84 let hmac = sha1_hmac_provider.sha1_hmac(key, payloads);
85 assert_eq!(hmac, *expected);
86 }
87 
88 #[test]
89 fn test_rfc2202_test_case_1() {
90 verify_test_vector(
91 &[0x0b; 20],
92 &[b"Hi There"],
93 &hex_as_bytes!(b"b617318655057264e28bc0b6fb378c8ef146be00"),
94 );
95 }
96 
97 #[test]
98 fn test_rfc2202_test_case_2() {
99 verify_test_vector(
100 b"Jefe",
101 &[b"what do ya want for nothing?"],
102 &hex_as_bytes!(b"effcdf6ae5eb2fa2d27416d5f184df9c259a7c79"),
103 );
104 }
105 
106 #[test]
107 fn test_rfc2202_test_case_3() {
108 verify_test_vector(
109 &[0xaa; 20],
110 &[&[0xddu8; 50]],
111 &hex_as_bytes!(b"125d7342b9ac11cd91a39af48aa17b4f63f175d3"),
112 );
113 }
114 
115 #[test]
116 fn test_rfc2202_test_case_4() {
117 verify_test_vector(
118 &[
119 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
120 24, 25,
121 ],
122 &[&[0xcdu8; 50]],
123 &hex_as_bytes!(b"4c9007f4026250c6bc8414f9bf50c86c2d7235da"),
124 );
125 }
126 
127 #[test]
128 fn test_rfc2202_test_case_5() {
129 verify_test_vector(
130 &[0x0c; 20],
131 &[b"Test With Truncation"],
132 &hex_as_bytes!(b"4c1a03424b55e07fe7f27be1d58bb9324a9a5a04"),
133 );
134 }
135 
136 #[test]
137 fn test_rfc2202_test_case_6() {
138 verify_test_vector(
139 &[0xaa; 80],
140 &[b"Test Using Larger Than Block-Size Key - Hash Key First"],
141 &hex_as_bytes!(b"aa4ae5e15272d00e95705637ce8a3b55ed402112"),
142 );
143 }
144 
145 #[test]
146 fn test_rfc2202_test_case_7() {
147 verify_test_vector(
148 &[0xaa; 80],
149 &[
150 b"Test Using Larger Than Block-Size Key and Larger ",
151 b"Than One Block-Size Data",
152 ],
153 &hex_as_bytes!(b"e8e99d0f45237d786d6bbaa7965c7808bbff1a91"),
154 );
155 }
156}
157 
158mod aes_128_cm_sha1_80 {
159 fn verify_test_vector(
160 key: [u8; 16],
161 iv: [u8; 16],
162 encrypt: bool,
163 input: &[u8],
164 expected: &[u8],
165 ) {
166 let srtp_provider = super::get_provider().srtp_provider;
167 let cipher_provider = srtp_provider.aes_128_cm_sha1_80();
168 let mut cipher = cipher_provider.create_cipher(key, encrypt);
169 
170 let mut output = vec![0u8; input.len()];
171 if encrypt {
172 cipher.encrypt(&iv, input, &mut output).unwrap();
173 } else {
174 cipher.decrypt(&iv, input, &mut output).unwrap();
175 }
176 assert_eq!(expected, &output)
177 }
178 
179 // AES-128-CTR Test Vectors from NIST SP 800-38A
180 // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
181 // Section F.5.1
182 
183 #[test]
184 fn test_ctr_encrypt() {
185 verify_test_vector(
186 hex_as_bytes!(b"2b7e151628aed2a6abf7158809cf4f3c"),
187 hex_as_bytes!(b"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
188 true,
189 &hex_as_bytes!(b"6bc1bee22e409f96e93d7e117393172a"),
190 &hex_as_bytes!(b"874d6191b620e3261bef6864990db6ce"),
191 );
192 }
193 
194 #[test]
195 fn test_decrypt() {
196 verify_test_vector(
197 hex_as_bytes!(b"2b7e151628aed2a6abf7158809cf4f3c"),
198 hex_as_bytes!(b"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
199 false,
200 &hex_as_bytes!(b"874d6191b620e3261bef6864990db6ce"),
201 &hex_as_bytes!(b"6bc1bee22e409f96e93d7e117393172a"),
202 );
203 }
204 
205 #[test]
206 fn test_multiple_blocks() {
207 verify_test_vector(
208 hex_as_bytes!(b"2b7e151628aed2a6abf7158809cf4f3c"),
209 hex_as_bytes!(b"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff"),
210 true,
211 &hex_as_bytes!(
212 b"6bc1bee22e409f96e93d7e117393172a\
213 ae2d8a571e03ac9c9eb76fac45af8e51\
214 30c81c46a35ce411e5fbc1191a0a52ef"
215 ),
216 &hex_as_bytes!(
217 b"874d6191b620e3261bef6864990db6ce\
218 9806f66b7970fdff8617187bb9fffdff\
219 5ae4df3edbd5d35e5b4f09020db03eab"
220 ),
221 );
222 }
223}
224 
225mod aead_aes_128_gcm {
226 fn verify_test_vector(
227 key: [u8; 16],
228 iv: [u8; 12],
229 encrypt: bool,
230 aads: &[&[u8]],
231 input: &[u8],
232 expected: &[u8],
233 ) {
234 let srtp_provider = super::get_provider().srtp_provider;
235 let cipher_provider = srtp_provider.aead_aes_128_gcm();
236 let mut cipher = cipher_provider.create_cipher(key, encrypt);
237 
238 let output_len = if encrypt {
239 input.len() + 16
240 } else {
241 input.len() - 16
242 };
243 let mut output = vec![0u8; output_len];
244 if encrypt {
245 cipher.encrypt(&iv, aads[0], input, &mut output).unwrap();
246 } else {
247 cipher.decrypt(&iv, aads, input, &mut output).unwrap();
248 }
249 assert_eq!(expected, &output)
250 }
251 
252 // AES-128-GCM Test Vectors from NIST SP 800-38D
253 // https://csrc.nist.gov/publications/detail/sp/800-38d/final
254 // Test Case 4
255 
256 #[test]
257 fn test_encrypt() {
258 verify_test_vector(
259 hex_as_bytes!(b"feffe9928665731c6d6a8f9467308308"),
260 hex_as_bytes!(b"cafebabefacedbaddecaf888"),
261 true,
262 &[&hex_as_bytes!(
263 b"feedfacedeadbeeffeedfacedeadbeef\
264 abaddad2"
265 )],
266 &hex_as_bytes!(
267 b"d9313225f88406e5a55909c5aff5269a\
268 86a7a9531534f7da2e4c303d8a318a72\
269 1c3c0c95956809532fcf0e2449a6b525\
270 b16aedf5aa0de657ba637b39"
271 ),
272 &hex_as_bytes!(
273 b"42831ec2217774244b7221b784d0d49c\
274 e3aa212f2c02a4e035c17e2329aca12e\
275 21d514b25466931c7d8f6a5aac84aa05\
276 1ba30b396a0aac973d58e091\
277 5bc94fbc3221a5db94fae95ae7121a47"
278 ),
279 );
280 }
281 
282 #[test]
283 fn test_decrypt() {
284 verify_test_vector(
285 hex_as_bytes!(b"feffe9928665731c6d6a8f9467308308"),
286 hex_as_bytes!(b"cafebabefacedbaddecaf888"),
287 false,
288 &[&hex_as_bytes!(
289 b"feedfacedeadbeeffeedfacedeadbeef\
290 abaddad2"
291 )],
292 &hex_as_bytes!(
293 b"42831ec2217774244b7221b784d0d49c\
294 e3aa212f2c02a4e035c17e2329aca12e\
295 21d514b25466931c7d8f6a5aac84aa05\
296 1ba30b396a0aac973d58e091\
297 5bc94fbc3221a5db94fae95ae7121a47"
298 ),
299 &hex_as_bytes!(
300 b"d9313225f88406e5a55909c5aff5269a\
301 86a7a9531534f7da2e4c303d8a318a72\
302 1c3c0c95956809532fcf0e2449a6b525\
303 b16aedf5aa0de657ba637b39"
304 ),
305 );
306 }
307 
308 #[test]
309 fn test_decrypt_invalid_tag() {
310 let srtp_provider = super::get_provider().srtp_provider;
311 let cipher_provider = srtp_provider.aead_aes_128_gcm();
312 let mut cipher = cipher_provider
313 .create_cipher(hex_as_bytes!(b"feffe9928665731c6d6a8f9467308308"), false);
314 
315 let mut output = vec![0u8; 1024];
316 let result = cipher.decrypt(
317 &hex_as_bytes!(b"cafebabefacedbaddecaf888"),
318 &[&hex_as_bytes!(
319 b"feedfacedeadbeeffeedfacedeadbeef\
320 abaddad2"
321 )],
322 &hex_as_bytes!(
323 b"42831ec2217774244b7221b784d0d49c\
324 e3aa212f2c02a4e035c17e2329aca12e\
325 21d514b25466931c7d8f6a5aac84aa05\
326 1ba30b396a0aac973d58e091\
327 000000000000000000000000000000"
328 ),
329 &mut output,
330 );
331 assert!(result.is_err());
332 }
333}
334 
335mod aead_aes_256_gcm {
336 fn verify_test_vector(
337 key: [u8; 32],
338 iv: [u8; 12],
339 encrypt: bool,
340 aads: &[&[u8]],
341 input: &[u8],
342 expected: &[u8],
343 ) {
344 let srtp_provider = super::get_provider().srtp_provider;
345 let cipher_provider = srtp_provider.aead_aes_256_gcm();
346 let mut cipher = cipher_provider.create_cipher(key, encrypt);
347 
348 let output_len = if encrypt {
349 input.len() + 16
350 } else {
351 input.len() - 16
352 };
353 let mut output = vec![0u8; output_len];
354 if encrypt {
355 cipher.encrypt(&iv, aads[0], input, &mut output).unwrap();
356 } else {
357 cipher.decrypt(&iv, aads, input, &mut output).unwrap();
358 }
359 assert_eq!(expected, &output)
360 }
361 
362 // AES-256-GCM Test Vectors from NIST SP 800-38D
363 // Test Case 16
364 
365 #[test]
366 fn test_encrypt() {
367 verify_test_vector(
368 hex_as_bytes!(
369 b"feffe9928665731c6d6a8f9467308308\
370 feffe9928665731c6d6a8f9467308308"
371 ),
372 hex_as_bytes!(b"cafebabefacedbaddecaf888"),
373 true,
374 &[&hex_as_bytes!(
375 b"feedfacedeadbeeffeedfacedeadbeef\
376 abaddad2"
377 )],
378 &hex_as_bytes!(
379 b"d9313225f88406e5a55909c5aff5269a\
380 86a7a9531534f7da2e4c303d8a318a72\
381 1c3c0c95956809532fcf0e2449a6b525\
382 b16aedf5aa0de657ba637b39"
383 ),
384 &hex_as_bytes!(
385 b"522dc1f099567d07f47f37a32a84427d\
386 643a8cdcbfe5c0c97598a2bd2555d1aa\
387 8cb08e48590dbb3da7b08b1056828838\
388 c5f61e6393ba7a0abcc9f662\
389 76fc6ece0f4e1768cddf8853bb2d551b"
390 ),
391 );
392 }
393 
394 #[test]
395 fn test_decrypt() {
396 verify_test_vector(
397 hex_as_bytes!(
398 b"feffe9928665731c6d6a8f9467308308\
399 feffe9928665731c6d6a8f9467308308"
400 ),
401 hex_as_bytes!(b"cafebabefacedbaddecaf888"),
402 false,
403 &[&hex_as_bytes!(
404 b"feedfacedeadbeeffeedfacedeadbeef\
405 abaddad2"
406 )],
407 &hex_as_bytes!(
408 b"522dc1f099567d07f47f37a32a84427d\
409 643a8cdcbfe5c0c97598a2bd2555d1aa\
410 8cb08e48590dbb3da7b08b1056828838\
411 c5f61e6393ba7a0abcc9f662\
412 76fc6ece0f4e1768cddf8853bb2d551b"
413 ),
414 &hex_as_bytes!(
415 b"d9313225f88406e5a55909c5aff5269a\
416 86a7a9531534f7da2e4c303d8a318a72\
417 1c3c0c95956809532fcf0e2449a6b525\
418 b16aedf5aa0de657ba637b39"
419 ),
420 );
421 }
422}
423 
424mod srtp_aes_128_ecb_round {
425 const TEST_KEY: [u8; 16] = hex_as_bytes!(b"2b7e151628aed2a6abf7158809cf4f3c");
426 
427 fn verify_test_vector(key: &[u8], input: &[u8], expected: &[u8]) {
428 let srtp_provider = super::get_provider().srtp_provider;
429 let mut out = [0u8; 2048];
430 srtp_provider.srtp_aes_128_ecb_round(key, input, out.as_mut_slice());
431 assert_eq!(expected, &out[0..input.len()])
432 }
433 
434 // Test vectors from NIST SP 800-38A:
435 // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
436 
437 #[test]
438 fn test_vec_1() {
439 verify_test_vector(
440 &TEST_KEY,
441 &hex_as_bytes!(b"6bc1bee22e409f96e93d7e117393172a"),
442 &hex_as_bytes!(b"3ad77bb40d7a3660a89ecaf32466ef97"),
443 );
444 }
445 
446 #[test]
447 fn test_vec_2() {
448 verify_test_vector(
449 &TEST_KEY,
450 &hex_as_bytes!(b"ae2d8a571e03ac9c9eb76fac45af8e51"),
451 &hex_as_bytes!(b"f5d3d58503b9699de785895a96fdbaaf"),
452 );
453 }
454 
455 #[test]
456 fn test_vec_3() {
457 verify_test_vector(
458 &TEST_KEY,
459 &hex_as_bytes!(b"30c81c46a35ce411e5fbc1191a0a52ef"),
460 &hex_as_bytes!(b"43b1cd7f598ece23881b00e3ed030688"),
461 );
462 }
463 
464 #[test]
465 fn test_vec_4() {
466 verify_test_vector(
467 &TEST_KEY,
468 &hex_as_bytes!(b"f69f2445df4f9b17ad2b417be66c3710"),
469 &hex_as_bytes!(b"7b0c785e27e8ad3f8223207104725dd4"),
470 );
471 }
472}
473 
474mod srtp_aes_256_ecb_round {
475 const TEST_KEY: [u8; 32] =
476 hex_as_bytes!(b"603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4");
477 
478 fn verify_test_vector(key: &[u8], input: &[u8], expected: &[u8]) {
479 let srtp_provider = super::get_provider().srtp_provider;
480 let mut out = [0u8; 2048];
481 srtp_provider.srtp_aes_256_ecb_round(key, input, out.as_mut_slice());
482 assert_eq!(expected, &out[0..input.len()])
483 }
484 
485 // Test vectors from NIST SP 800-38A:
486 // https://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38a.pdf
487 
488 #[test]
489 fn test_vec_1() {
490 verify_test_vector(
491 &TEST_KEY,
492 &hex_as_bytes!(b"6bc1bee22e409f96e93d7e117393172a"),
493 &hex_as_bytes!(b"f3eed1bdb5d2a03c064b5a7e3db181f8"),
494 );
495 }
496 
497 #[test]
498 fn test_vec_2() {
499 verify_test_vector(
500 &TEST_KEY,
501 &hex_as_bytes!(b"ae2d8a571e03ac9c9eb76fac45af8e51"),
502 &hex_as_bytes!(b"591ccb10d410ed26dc5ba74a31362870"),
503 );
504 }
505 
506 #[test]
507 fn test_vec_3() {
508 verify_test_vector(
509 &TEST_KEY,
510 &hex_as_bytes!(b"30c81c46a35ce411e5fbc1191a0a52ef"),
511 &hex_as_bytes!(b"b6ed21b99ca6f4f9f153e7b1beafed1d"),
512 );
513 }
514 
515 #[test]
516 fn test_vec_4() {
517 verify_test_vector(
518 &TEST_KEY,
519 &hex_as_bytes!(b"f69f2445df4f9b17ad2b417be66c3710"),
520 &hex_as_bytes!(b"23304b7a39f9f3ff067d8d8f9e24ecc7"),
521 );
522 }
523}