11//! Development-related functionality
22use crate :: {
3- Aead , AeadInOut , Nonce , Payload , Tag , TagPosition , array:: typenum:: Unsigned , inout:: InOutBuf ,
3+ Aead , AeadInOut , Payload , Tag , TagPosition , array:: typenum:: Unsigned , inout:: InOutBuf ,
44} ;
55pub use blobby;
6+ use crypto_common:: KeyInit ;
7+
8+ /// AEAD test vector
9+ #[ derive( Debug , Clone , Copy ) ]
10+ pub struct TestVector {
11+ /// Initialization key
12+ pub key : & ' static [ u8 ] ,
13+ /// Nonce
14+ pub nonce : & ' static [ u8 ] ,
15+ /// Additional associated data
16+ pub aad : & ' static [ u8 ] ,
17+ /// Plaintext
18+ pub plaintext : & ' static [ u8 ] ,
19+ /// Ciphertext
20+ pub ciphertext : & ' static [ u8 ] ,
21+ /// Whether the test vector should pass (`[1]`) or fail (`[0]`)
22+ pub pass : & ' static [ u8 ] ,
23+ }
624
725/// Run AEAD test for the provided passing test vector
8- pub fn run_pass_test < C : AeadInOut > (
9- cipher : & C ,
10- nonce : & Nonce < C > ,
11- aad : & [ u8 ] ,
12- pt : & [ u8 ] ,
13- ct : & [ u8 ] ,
26+ pub fn pass_test < C : AeadInOut + KeyInit > (
27+ & TestVector {
28+ key,
29+ nonce,
30+ aad,
31+ plaintext,
32+ ciphertext,
33+ pass,
34+ } : & TestVector ,
1435) -> Result < ( ) , & ' static str > {
36+ assert_eq ! ( pass, & [ 1 ] ) ;
37+ let nonce = nonce. try_into ( ) . expect ( "wrong nonce size" ) ;
38+ let cipher = <C as KeyInit >:: new_from_slice ( key) . expect ( "failed to initialize the cipher" ) ;
39+
1540 let res = cipher
16- . encrypt ( nonce, Payload { aad, msg : pt } )
41+ . encrypt (
42+ nonce,
43+ Payload {
44+ aad,
45+ msg : plaintext,
46+ } ,
47+ )
1748 . map_err ( |_| "encryption failure" ) ?;
18- if res != ct {
49+ if res != ciphertext {
1950 return Err ( "encrypted data is different from target ciphertext" ) ;
2051 }
2152
2253 let res = cipher
23- . decrypt ( nonce, Payload { aad, msg : ct } )
54+ . decrypt (
55+ nonce,
56+ Payload {
57+ aad,
58+ msg : ciphertext,
59+ } ,
60+ )
2461 . map_err ( |_| "decryption failure" ) ?;
25- if res != pt {
62+ if res != plaintext {
2663 return Err ( "decrypted data is different from target plaintext" ) ;
2764 }
2865
2966 let ( ct, tag) = match C :: TAG_POSITION {
3067 TagPosition :: Prefix => {
31- let ( tag, ct) = ct . split_at ( C :: TagSize :: USIZE ) ;
68+ let ( tag, ct) = ciphertext . split_at ( C :: TagSize :: USIZE ) ;
3269 ( ct, tag)
3370 }
34- TagPosition :: Postfix => ct . split_at ( pt . len ( ) ) ,
71+ TagPosition :: Postfix => ciphertext . split_at ( plaintext . len ( ) ) ,
3572 } ;
3673 let tag: & Tag < C > = tag. try_into ( ) . expect ( "tag has correct length" ) ;
3774
3875 // Fill output buffer with "garbage" to test that its data does not get read during encryption
39- let mut buf: alloc:: vec:: Vec < u8 > = ( 0 ..pt . len ( ) ) . map ( |i| i as u8 ) . collect ( ) ;
40- let inout_buf = InOutBuf :: new ( pt , & mut buf) . expect ( "pt and buf have the same length" ) ;
76+ let mut buf: alloc:: vec:: Vec < u8 > = ( 0 ..plaintext . len ( ) ) . map ( |i| i as u8 ) . collect ( ) ;
77+ let inout_buf = InOutBuf :: new ( plaintext , & mut buf) . expect ( "pt and buf have the same length" ) ;
4178
4279 let calc_tag = cipher
4380 . encrypt_inout_detached ( nonce, aad, inout_buf)
@@ -50,27 +87,43 @@ pub fn run_pass_test<C: AeadInOut>(
5087 }
5188
5289 // Fill output buffer with "garbage"
53- buf. iter_mut ( ) . enumerate ( ) . for_each ( |( i, v) | * v = i as u8 ) ;
90+ buf. iter_mut ( )
91+ . enumerate ( )
92+ . for_each ( |( i, v) : ( usize , & mut u8 ) | * v = i as u8 ) ;
5493
5594 let inout_buf = InOutBuf :: new ( ct, & mut buf) . expect ( "ct and buf have the same length" ) ;
5695 cipher
5796 . decrypt_inout_detached ( nonce, aad, inout_buf, tag)
5897 . map_err ( |_| "decrypt_inout_detached: decryption failure" ) ?;
59- if pt != buf {
98+ if plaintext != buf {
6099 return Err ( "decrypt_inout_detached: plaintext mismatch" ) ;
61100 }
62101
63102 Ok ( ( ) )
64103}
65104
66105/// Run AEAD test for the provided failing test vector
67- pub fn run_fail_test < C : AeadInOut > (
68- cipher : & C ,
69- nonce : & Nonce < C > ,
70- aad : & [ u8 ] ,
71- ct : & [ u8 ] ,
106+ pub fn fail_test < C : AeadInOut + KeyInit > (
107+ & TestVector {
108+ key,
109+ nonce,
110+ aad,
111+ ciphertext,
112+ pass,
113+ ..
114+ } : & TestVector ,
72115) -> Result < ( ) , & ' static str > {
73- let res = cipher. decrypt ( nonce, Payload { aad, msg : ct } ) ;
116+ assert_eq ! ( pass, & [ 0 ] ) ;
117+ let nonce = nonce. try_into ( ) . expect ( "wrong nonce size" ) ;
118+ let cipher = <C as KeyInit >:: new_from_slice ( key) . expect ( "failed to initialize the cipher" ) ;
119+
120+ let res = cipher. decrypt (
121+ nonce,
122+ Payload {
123+ aad,
124+ msg : ciphertext,
125+ } ,
126+ ) ;
74127 if res. is_ok ( ) {
75128 Err ( "decryption must return error" )
76129 } else {
@@ -84,33 +137,29 @@ macro_rules! new_test {
84137 ( $name: ident, $test_name: expr, $cipher: ty $( , ) ?) => {
85138 #[ test]
86139 fn $name( ) {
87- use $crate:: KeyInit ;
88- use $crate:: dev:: blobby:: Blob6Iterator ;
89-
90- let data = include_bytes!( concat!( "data/" , $test_name, ".blb" ) ) ;
91- for ( i, row) in Blob6Iterator :: new( data) . unwrap( ) . enumerate( ) {
92- let [ key, nonce, aad, pt, ct, status] = row. unwrap( ) ;
93- let key = key. try_into( ) . expect( "wrong key size" ) ;
94- let nonce = nonce. try_into( ) . expect( "wrong nonce size" ) ;
95- let cipher = <$cipher as KeyInit >:: new( key) ;
96-
97- let res = match status {
98- [ 0 ] => $crate:: dev:: run_fail_test( & cipher, nonce, aad, ct) ,
99- [ 1 ] => $crate:: dev:: run_pass_test( & cipher, nonce, aad, pt, ct) ,
100- _ => panic!( "invalid value for pass flag" ) ,
140+ use $crate:: dev:: TestVector ;
141+
142+ $crate:: dev:: blobby:: parse_into_structs!(
143+ include_bytes!( concat!( "data/" , $test_name, ".blb" ) ) ;
144+ static TEST_VECTORS : & [
145+ TestVector { key, nonce, aad, plaintext, ciphertext, pass }
146+ ] ;
147+ ) ;
148+
149+ for ( i, tv) in TEST_VECTORS . iter( ) . enumerate( ) {
150+ let pass = tv. pass[ 0 ] == 1 ;
151+ let res = if pass {
152+ $crate:: dev:: pass_test:: <$cipher>( tv)
153+ } else {
154+ $crate:: dev:: fail_test:: <$cipher>( tv)
101155 } ;
102- let mut pass = status [ 0 ] == 1 ;
156+
103157 if let Err ( reason) = res {
104158 panic!(
105159 "\n \
106160 Failed test #{i}\n \
107161 reason:\t {reason:?}\n \
108- key:\t {key:?}\n \
109- nonce:\t {nonce:?}\n \
110- aad:\t {aad:?}\n \
111- plaintext:\t {pt:?}\n \
112- ciphertext:\t {ct:?}\n \
113- pass:\t {pass}\n "
162+ test vector:\t {tv:?}\n "
114163 ) ;
115164 }
116165 }
0 commit comments