capsules_extra/test/
hmac_sha512.rs1use capsules_core::test::capsule_test::{CapsuleTest, CapsuleTestClient, CapsuleTestError};
9use kernel::ErrorCode;
10use kernel::hil::digest;
11use kernel::hil::digest::HmacSha512;
12use kernel::utilities::cells::OptionalCell;
13use kernel::utilities::cells::TakeCell;
14use kernel::utilities::leasable_buffer::SubSlice;
15use kernel::utilities::leasable_buffer::SubSliceMut;
16
17const HMAC_SHA512_DIGEST_LEN: usize = 64;
18
19pub struct TestHmacSha512<'a, H: digest::Digest<'a, HMAC_SHA512_DIGEST_LEN>> {
20 hmac: &'a H,
21 key: TakeCell<'static, [u8]>, data: TakeCell<'static, [u8]>, digest: TakeCell<'static, [u8; HMAC_SHA512_DIGEST_LEN]>, correct: &'static [u8; HMAC_SHA512_DIGEST_LEN], client: OptionalCell<&'static dyn CapsuleTestClient>,
26}
27
28impl<'a, H: digest::Digest<'a, HMAC_SHA512_DIGEST_LEN> + HmacSha512> TestHmacSha512<'a, H> {
29 pub fn new(
30 hmac: &'a H,
31 key: &'static mut [u8],
32 data: &'static mut [u8],
33 digest: &'static mut [u8; HMAC_SHA512_DIGEST_LEN],
34 correct: &'static [u8; HMAC_SHA512_DIGEST_LEN],
35 ) -> Self {
36 TestHmacSha512 {
37 hmac,
38 key: TakeCell::new(key),
39 data: TakeCell::new(data),
40 digest: TakeCell::new(digest),
41 correct,
42 client: OptionalCell::empty(),
43 }
44 }
45
46 pub fn run(&'static self) {
47 kernel::hil::digest::Digest::set_client(self.hmac, self);
48 let key = self.key.take().unwrap();
49 let r = self.hmac.set_mode_hmacsha512(key);
50 if r.is_err() {
51 panic!("HmacSha512Test: failed to set key: {:?}", r);
52 }
53 let data = self.data.take().unwrap();
54 let buffer = SubSliceMut::new(data);
55 let r = self.hmac.add_mut_data(buffer);
56 if r.is_err() {
57 panic!("HmacSha512Test: failed to add data: {:?}", r);
58 }
59 }
60}
61
62impl<'a, H: digest::Digest<'a, HMAC_SHA512_DIGEST_LEN> + HmacSha512>
63 digest::ClientData<HMAC_SHA512_DIGEST_LEN> for TestHmacSha512<'a, H>
64{
65 fn add_data_done(&self, _result: Result<(), ErrorCode>, _data: SubSlice<'static, u8>) {
66 unimplemented!()
67 }
68
69 fn add_mut_data_done(&self, result: Result<(), ErrorCode>, data: SubSliceMut<'static, u8>) {
70 self.data.replace(data.take());
71
72 match result {
73 Ok(()) => {}
74 Err(e) => {
75 kernel::debug!("HmacSha512Test: failed to add data: {:?}", e);
76 self.client.map(|client| {
77 client.done(Err(CapsuleTestError::ErrorCode(e)));
78 });
79 return;
80 }
81 }
82
83 let r = self.hmac.run(self.digest.take().unwrap());
84 match r {
85 Ok(()) => {}
86 Err((e, d)) => {
87 kernel::debug!("HmacSha512Test: failed to run HMAC: {:?}", e);
88
89 self.digest.replace(d);
90 self.client.map(|client| {
91 client.done(Err(CapsuleTestError::ErrorCode(e)));
92 });
93 }
94 }
95 }
96}
97
98impl<'a, H: digest::Digest<'a, HMAC_SHA512_DIGEST_LEN> + HmacSha512>
99 digest::ClientHash<HMAC_SHA512_DIGEST_LEN> for TestHmacSha512<'a, H>
100{
101 fn hash_done(
102 &self,
103 _result: Result<(), ErrorCode>,
104 digest: &'static mut [u8; HMAC_SHA512_DIGEST_LEN],
105 ) {
106 let mut error = false;
107 for i in 0..HMAC_SHA512_DIGEST_LEN {
108 if self.correct[i] != digest[i] {
109 error = true;
110 break;
111 }
112 }
113 if !error {
114 kernel::debug!("HMAC-SHA512 matches!");
115 self.client.map(|client| {
116 client.done(Ok(()));
117 });
118 } else {
119 kernel::debug!("HmacSha512Test: incorrect HMAC output!");
120 self.client.map(|client| {
121 client.done(Err(CapsuleTestError::IncorrectResult));
122 });
123 }
124 }
125}
126
127impl<'a, H: digest::Digest<'a, HMAC_SHA512_DIGEST_LEN> + HmacSha512>
128 digest::ClientVerify<HMAC_SHA512_DIGEST_LEN> for TestHmacSha512<'a, H>
129{
130 fn verification_done(
131 &self,
132 _result: Result<bool, ErrorCode>,
133 _compare: &'static mut [u8; HMAC_SHA512_DIGEST_LEN],
134 ) {
135 }
136}
137
138impl<'a, H: digest::Digest<'a, HMAC_SHA512_DIGEST_LEN> + HmacSha512> CapsuleTest
139 for TestHmacSha512<'a, H>
140{
141 fn set_client(&self, client: &'static dyn CapsuleTestClient) {
142 self.client.set(client);
143 }
144}