capsules_extra/test/
md5.rs1use core::cell::Cell;
11use core::cmp;
12
13use capsules_core::test::capsule_test::{CapsuleTest, CapsuleTestClient};
14use kernel::ErrorCode;
15use kernel::debug;
16use kernel::hil::digest;
17use kernel::utilities::cells::{OptionalCell, TakeCell};
18use kernel::utilities::leasable_buffer::SubSlice;
19use kernel::utilities::leasable_buffer::SubSliceMut;
20
21pub struct TestMd5<'a, H: digest::Digest<'a, 16>> {
22 sha: &'a H,
23 data: TakeCell<'static, [u8]>, hash: TakeCell<'static, [u8; 16]>, position: Cell<usize>, correct: Cell<bool>, client: OptionalCell<&'static dyn CapsuleTestClient>,
28}
29
30const CHUNK_SIZE: usize = 12;
34
35impl<'a, H: digest::Digest<'a, 16> + digest::Md5> TestMd5<'a, H> {
36 pub fn new(
37 sha: &'a H,
38 data: &'static mut [u8],
39 hash: &'static mut [u8; 16],
40 correct: bool,
41 ) -> Self {
42 TestMd5 {
43 sha,
44 data: TakeCell::new(data),
45 hash: TakeCell::new(hash),
46 position: Cell::new(0),
47 correct: Cell::new(correct),
48 client: OptionalCell::empty(),
49 }
50 }
51
52 pub fn run(&'a self) {
53 let r = self.sha.set_mode_md5();
54 if r.is_err() {
55 panic!("Md5Test: failed to set mode: {:?}", r)
56 }
57 self.sha.set_client(self);
58 let data = self.data.take().unwrap();
59 let chunk_size = cmp::min(CHUNK_SIZE, data.len());
60 self.position.set(chunk_size);
61 let mut buffer = SubSliceMut::new(data);
62 buffer.slice(0..chunk_size);
63 let r = self.sha.add_mut_data(buffer);
64 if r.is_err() {
65 panic!("Md5Test: failed to add data: {:?}", r);
66 }
67 }
68}
69
70impl<'a, H: digest::Digest<'a, 16>> digest::ClientData<16> for TestMd5<'a, H> {
71 fn add_data_done(&self, _result: Result<(), ErrorCode>, _data: SubSlice<'static, u8>) {
72 unimplemented!()
73 }
74
75 fn add_mut_data_done(&self, result: Result<(), ErrorCode>, mut data: SubSliceMut<'static, u8>) {
76 if data.len() != 0 {
77 let r = self.sha.add_mut_data(data);
78 if r.is_err() {
79 panic!("Md5Test: failed to add data: {:?}", r);
80 }
81 } else {
82 data.reset();
83 if self.position.get() < data.len() {
84 let new_position = cmp::min(data.len(), self.position.get() + CHUNK_SIZE);
85 data.slice(self.position.get()..new_position);
86 debug!(
87 "Md5Test: Setting slice to {}..{}",
88 self.position.get(),
89 new_position
90 );
91 let r = self.sha.add_mut_data(data);
92 if r.is_err() {
93 panic!("Md5Test: failed to add data: {:?}", r);
94 }
95 self.position.set(new_position);
96 } else {
97 data.reset();
98 self.data.put(Some(data.take()));
99 match result {
100 Ok(()) => {
101 let v = self.sha.verify(self.hash.take().unwrap());
102 if v.is_err() {
103 panic!("Md5Test: failed to verify: {:?}", v);
104 }
105 }
106 Err(e) => {
107 panic!("Md5Test: adding data failed: {:?}", e);
108 }
109 }
110 }
111 }
112 }
113}
114
115impl<'a, H: digest::Digest<'a, 16>> digest::ClientVerify<16> for TestMd5<'a, H> {
116 fn verification_done(&self, result: Result<bool, ErrorCode>, compare: &'static mut [u8; 16]) {
117 self.hash.put(Some(compare));
118 debug!("Md5Test: Verification result: {:?}", result);
119 match result {
120 Ok(success) => {
121 if success != self.correct.get() {
122 panic!(
123 "Md5Test: Verification should have been {}, was {}",
124 self.correct.get(),
125 success
126 );
127 } else {
128 self.client.map(|client| {
129 client.done(Ok(()));
130 });
131 }
132 }
133 Err(e) => {
134 panic!("Md5Test: Error in verification: {:?}", e);
135 }
136 }
137 }
138}
139
140impl<'a, H: digest::Digest<'a, 16>> digest::ClientHash<16> for TestMd5<'a, H> {
141 fn hash_done(&self, _result: Result<(), ErrorCode>, _digest: &'static mut [u8; 16]) {}
142}
143
144impl<'a, H: digest::Digest<'a, 16>> CapsuleTest for TestMd5<'a, H> {
145 fn set_client(&self, client: &'static dyn CapsuleTestClient) {
146 self.client.set(client);
147 }
148}