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