1use core::cell::Cell;
13use kernel::deferred_call::{DeferredCall, DeferredCallClient};
14
15use kernel::hil::digest::Sha256;
16use kernel::hil::digest::{Client, ClientData, ClientHash, ClientVerify};
17use kernel::hil::digest::{ClientDataHash, ClientDataVerify, DigestDataHash, DigestDataVerify};
18use kernel::hil::digest::{Digest, DigestData, DigestHash, DigestVerify};
19use kernel::utilities::cells::{MapCell, OptionalCell};
20use kernel::utilities::leasable_buffer::SubSlice;
21use kernel::utilities::leasable_buffer::SubSliceMut;
22use kernel::utilities::leasable_buffer::SubSliceMutImmut;
23use kernel::ErrorCode;
24
25#[derive(Clone, Copy, PartialEq)]
26pub enum State {
27 Idle,
28 Data,
29 Hash,
30 Verify,
31 CancelData,
32 CancelHash,
33 CancelVerify,
34}
35
36const SHA_BLOCK_LEN_BYTES: usize = 64;
37const SHA_256_OUTPUT_LEN_BYTES: usize = 32;
38const NUM_ROUND_CONSTANTS: usize = 64;
39
40const ROUND_CONSTANTS: [u32; NUM_ROUND_CONSTANTS] = [
41 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
42 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
43 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
44 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
45 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
46 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
47 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
48 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
49];
50
51pub struct Sha256Software<'a> {
52 state: Cell<State>,
53
54 client: OptionalCell<&'a dyn Client<SHA_256_OUTPUT_LEN_BYTES>>,
55 input_data: OptionalCell<SubSliceMutImmut<'static, u8>>,
56 data_buffer: MapCell<[u8; SHA_BLOCK_LEN_BYTES]>,
57 buffered_length: Cell<usize>,
58 total_length: Cell<usize>,
59
60 output_data: Cell<Option<&'static mut [u8; SHA_256_OUTPUT_LEN_BYTES]>>,
62
63 hash_values: Cell<[u32; 8]>,
64 deferred_call: DeferredCall,
65}
66
67impl Sha256Software<'_> {
68 pub fn new() -> Self {
69 let s = Self {
70 state: Cell::new(State::Idle),
71 client: OptionalCell::empty(),
72 input_data: OptionalCell::empty(),
73 data_buffer: MapCell::new([0; SHA_BLOCK_LEN_BYTES]),
74 buffered_length: Cell::new(0),
75 total_length: Cell::new(0),
76
77 output_data: Cell::new(None),
78 hash_values: Cell::new([0; 8]),
79
80 deferred_call: DeferredCall::new(),
81 };
82 s.initialize();
83 s
84 }
85
86 pub fn busy(&self) -> bool {
87 match self.state.get() {
88 State::Idle => false,
89 _ => true,
90 }
91 }
92
93 fn initialize(&self) {
94 let new_state = match self.state.get() {
95 State::Idle => State::Idle,
96 State::Data | State::CancelData => State::CancelData,
97 State::Hash | State::CancelHash => State::CancelHash,
98 State::Verify | State::CancelVerify => State::CancelVerify,
99 };
100 self.state.set(new_state);
101
102 self.buffered_length.set(0);
103 self.total_length.set(0);
104 self.data_buffer.map(|b| {
105 for i in 0..SHA_BLOCK_LEN_BYTES {
106 b[i] = 0;
107 }
108 });
109 self.hash_values.set([
110 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab,
111 0x5be0cd19,
112 ]);
113 }
114
115 fn complete_sha256(&self) {
117 let mut buffered_length = self.buffered_length.get();
118 if buffered_length == 64 {
123 self.data_buffer.map(|b| {
124 self.compute_block(b);
125 for i in 0..SHA_BLOCK_LEN_BYTES {
126 b[i] = 0;
127 }
128 });
129 buffered_length -= 64;
130 }
131 if buffered_length < 64 {
132 self.data_buffer.map(|b| {
133 for i in buffered_length..SHA_BLOCK_LEN_BYTES {
134 b[i] = 0;
135 }
136 });
137 }
138
139 self.data_buffer.map(|b| {
140 b.get_mut(buffered_length).map(|d| *d = 0x80);
142 buffered_length += 1;
144 if buffered_length > 56 {
149 for i in buffered_length..SHA_BLOCK_LEN_BYTES {
150 b[i] = 0;
151 }
152 self.compute_block(b);
153 for i in 0..SHA_BLOCK_LEN_BYTES {
154 b[i] = 0;
155 }
156 buffered_length = 0;
157 }
158 let total_length = self.total_length.get();
159 let length64 = (total_length * 8) as u64;
160 let len_high: u32 = (length64 >> 32) as u32;
161 let len_low: u32 = (length64 & 0xffffffff) as u32;
162 b[56] = (len_high >> 24 & 0xff) as u8;
163 b[57] = (len_high >> 16 & 0xff) as u8;
164 b[58] = (len_high >> 8 & 0xff) as u8;
165 b[59] = (len_high >> 0 & 0xff) as u8;
166 b[60] = (len_low >> 24 & 0xff) as u8;
167 b[61] = (len_low >> 16 & 0xff) as u8;
168 b[62] = (len_low >> 8 & 0xff) as u8;
169 b[63] = (len_low >> 0 & 0xff) as u8;
170 self.compute_block(b);
171 });
172 }
173
174 fn compute_sha256(&self) {
182 if let Some(mut data) = self.input_data.take() {
183 let data_length = data.len();
184 self.total_length.set(self.total_length.get() + data_length);
185 let mut buffered_length = self.buffered_length.get();
186 if buffered_length != 0 {
187 self.data_buffer.map(|b| {
190 let copy_len = if data_length + buffered_length >= SHA_BLOCK_LEN_BYTES {
191 SHA_BLOCK_LEN_BYTES - buffered_length
192 } else {
193 data_length
194 };
195
196 for i in 0..copy_len {
197 b[i + buffered_length] = data[i];
198 }
199 data.slice(copy_len..data.len());
200 buffered_length += copy_len;
201
202 if buffered_length == SHA_BLOCK_LEN_BYTES {
203 self.compute_block(b);
204 buffered_length = 0;
205 }
206 });
207 }
208 while data.len() >= 64 {
210 self.compute_buffer(&data[0..64]);
211 data.slice(64..data.len());
212 }
213 if data.len() != 0 {
215 self.data_buffer.map(|b| {
216 for i in 0..data.len() {
217 b[i] = data[i];
218 }
219 buffered_length = data.len();
220 data.slice(data.len()..data.len());
222 });
223 }
224 self.input_data.set(data);
225 self.buffered_length.set(buffered_length);
226 } else { }
228 }
229
230 fn right_rotate(&self, x: u32, rotate: u32) -> u32 {
231 (x >> rotate) | (x << (32 - rotate))
232 }
233
234 fn compute_buffer(&self, buffer: &[u8]) {
236 let mut message_schedule: [u32; 64] = [0; 64];
240 for i in 0..16 {
241 let val: u32 = (buffer[i * 4 + 0] as u32) << 24
242 | (buffer[i * 4 + 1] as u32) << 16
243 | (buffer[i * 4 + 2] as u32) << 8
244 | (buffer[i * 4 + 3] as u32);
245 message_schedule[i] = val;
246 }
247 self.perform_sha(&mut message_schedule);
248 }
249
250 fn compute_block(&self, data: &[u8; 64]) {
251 self.compute_buffer(data);
252 }
253
254 fn perform_sha(&self, message_schedule: &mut [u32; 64]) {
255 for i in 16..64 {
257 let mut s0 = self.right_rotate(message_schedule[i - 15], 7);
258 s0 ^= self.right_rotate(message_schedule[i - 15], 18);
259 s0 ^= message_schedule[i - 15] >> 3;
260 let mut s1 = self.right_rotate(message_schedule[i - 2], 17);
261 s1 ^= self.right_rotate(message_schedule[i - 2], 19);
262 s1 ^= message_schedule[i - 2] >> 10;
263 message_schedule[i] = message_schedule[i - 16] + s0 + message_schedule[i - 7] + s1;
264 }
265
266 let mut hashes = self.hash_values.get();
268 for i in 0..64 {
269 let s1 = self.right_rotate(hashes[4], 6)
270 ^ self.right_rotate(hashes[4], 11)
271 ^ self.right_rotate(hashes[4], 25);
272 let ch = (hashes[4] & hashes[5]) ^ ((!hashes[4]) & hashes[6]);
273 let constant = ROUND_CONSTANTS[i];
274 let temp1 = hashes[7] + s1 + ch + constant + message_schedule[i];
275 let s0 = self.right_rotate(hashes[0], 2)
276 ^ self.right_rotate(hashes[0], 13)
277 ^ self.right_rotate(hashes[0], 22);
278 let maj = (hashes[0] & hashes[1]) ^ (hashes[0] & hashes[2]) ^ (hashes[1] & hashes[2]);
279 let temp2 = s0 + maj;
280
281 hashes[7] = hashes[6];
282 hashes[6] = hashes[5];
283 hashes[5] = hashes[4];
284 hashes[4] = hashes[3].wrapping_add(temp1);
285 hashes[3] = hashes[2];
286 hashes[2] = hashes[1];
287 hashes[1] = hashes[0];
288 hashes[0] = temp1.wrapping_add(temp2);
289 }
290
291 let mut new_hashes = self.hash_values.get();
292 for i in 0..8 {
293 new_hashes[i] = new_hashes[i].wrapping_add(hashes[i]);
294 }
295 self.hash_values.set(new_hashes);
296 }
297}
298
299impl<'a> DigestData<'a, 32> for Sha256Software<'a> {
300 fn add_data(
301 &self,
302 data: SubSlice<'static, u8>,
303 ) -> Result<(), (ErrorCode, SubSlice<'static, u8>)> {
304 if self.busy() {
305 Err((ErrorCode::BUSY, data))
306 } else {
307 self.state.set(State::Data);
308 self.deferred_call.set();
309 self.input_data.set(SubSliceMutImmut::Immutable(data));
310 self.compute_sha256();
311 Ok(())
312 }
313 }
314
315 fn add_mut_data(
316 &self,
317 data: SubSliceMut<'static, u8>,
318 ) -> Result<(), (ErrorCode, SubSliceMut<'static, u8>)> {
319 if self.busy() {
320 Err((ErrorCode::BUSY, data))
321 } else {
322 self.state.set(State::Data);
323 self.deferred_call.set();
324 self.input_data.set(SubSliceMutImmut::Mutable(data));
325 self.compute_sha256();
326 Ok(())
327 }
328 }
329
330 fn clear_data(&self) {
331 self.initialize();
332 }
333
334 fn set_data_client(&'a self, _client: &'a (dyn ClientData<32> + 'a)) {
335 unimplemented!()
336 }
337}
338
339impl<'a> DigestHash<'a, 32> for Sha256Software<'a> {
340 fn run(
341 &'a self,
342 digest: &'static mut [u8; 32],
343 ) -> Result<(), (ErrorCode, &'static mut [u8; 32])> {
344 if self.busy() {
345 Err((ErrorCode::BUSY, digest))
346 } else {
347 self.state.set(State::Hash);
348 self.complete_sha256();
349 for i in 0..8 {
350 let val = self.hash_values.get()[i];
351 digest[4 * i + 3] = (val >> 0 & 0xff) as u8;
352 digest[4 * i + 2] = (val >> 8 & 0xff) as u8;
353 digest[4 * i + 1] = (val >> 16 & 0xff) as u8;
354 digest[4 * i + 0] = (val >> 24 & 0xff) as u8;
355 }
356 self.output_data.set(Some(digest));
357 self.deferred_call.set();
358 Ok(())
359 }
360 }
361
362 fn set_hash_client(&'a self, _client: &'a (dyn ClientHash<32> + 'a)) {
363 unimplemented!()
364 }
365}
366
367impl<'a> DigestVerify<'a, 32> for Sha256Software<'a> {
368 fn verify(
369 &'a self,
370 compare: &'static mut [u8; 32],
371 ) -> Result<(), (ErrorCode, &'static mut [u8; 32])> {
372 if self.busy() {
373 Err((ErrorCode::BUSY, compare))
374 } else {
375 self.state.set(State::Verify);
376 self.complete_sha256();
377 self.output_data.set(Some(compare));
378 self.deferred_call.set();
379 Ok(())
380 }
381 }
382
383 fn set_verify_client(&'a self, _client: &'a (dyn ClientVerify<32> + 'a)) {
384 unimplemented!()
385 }
386}
387
388impl<'a> Digest<'a, 32> for Sha256Software<'a> {
389 fn set_client(&'a self, client: &'a dyn Client<32>) {
390 self.client.set(client);
391 }
392}
393
394impl DeferredCallClient for Sha256Software<'_> {
395 fn handle_deferred_call(&self) {
396 let prior = self.state.get();
397 self.state.set(State::Idle);
398 match prior {
399 State::Idle => {}
400 State::Verify => {
401 let output = self.output_data.replace(None).unwrap();
404 let mut pass = true;
405 for i in 0..8 {
406 let hashval = self.hash_values.get()[i];
407 if output[4 * i + 3] != (hashval >> 0 & 0xff) as u8
408 || output[4 * i + 2] != (hashval >> 8 & 0xff) as u8
409 || output[4 * i + 1] != (hashval >> 16 & 0xff) as u8
410 || output[4 * i + 0] != (hashval >> 24 & 0xff) as u8
411 {
412 pass = false;
413 break;
414 }
415 }
416 self.state.set(State::Idle);
417 self.clear_data();
418 self.client.map(|c| {
419 c.verification_done(Ok(pass), output);
420 });
421 }
422 State::Data => {
423 let data = self.input_data.take().unwrap();
425 self.state.set(State::Idle);
426 match data {
427 SubSliceMutImmut::Mutable(buffer) => {
428 self.client.map(|client| {
429 client.add_mut_data_done(Ok(()), buffer);
430 });
431 }
432 SubSliceMutImmut::Immutable(buffer) => {
433 self.client.map(|client| {
434 client.add_data_done(Ok(()), buffer);
435 });
436 }
437 }
438 }
439 State::Hash => {
440 let output = self.output_data.replace(None).unwrap();
442 self.state.set(State::Idle);
443 self.clear_data();
444 self.client.map(|c| {
445 c.hash_done(Ok(()), output);
446 });
447 }
448 State::CancelData => {
449 self.state.set(State::Idle);
450 self.clear_data();
451 let data = self.input_data.take().unwrap();
452 match data {
453 SubSliceMutImmut::Mutable(buffer) => {
454 self.client.map(|client| {
455 client.add_mut_data_done(Err(ErrorCode::CANCEL), buffer);
456 });
457 }
458 SubSliceMutImmut::Immutable(buffer) => {
459 self.client.map(|client| {
460 client.add_data_done(Err(ErrorCode::CANCEL), buffer);
461 });
462 }
463 }
464 }
465 State::CancelVerify => {
466 self.state.set(State::Idle);
467 self.clear_data();
468 let output = self.output_data.replace(None).unwrap();
469 self.client.map(|client| {
470 client.verification_done(Err(ErrorCode::CANCEL), output);
471 });
472 }
473 State::CancelHash => {
474 self.state.set(State::Idle);
475 self.clear_data();
476 let output = self.output_data.replace(None).unwrap();
477 self.client.map(|client| {
478 client.hash_done(Err(ErrorCode::CANCEL), output);
479 });
480 }
481 }
482 }
483
484 fn register(&'static self) {
485 self.deferred_call.register(self);
486 }
487}
488
489impl Sha256 for Sha256Software<'_> {
490 fn set_mode_sha256(&self) -> Result<(), ErrorCode> {
492 Ok(())
493 }
494}
495
496impl<'a> DigestDataHash<'a, 32> for Sha256Software<'a> {
497 fn set_client(&'a self, _client: &'a dyn ClientDataHash<32>) {
498 unimplemented!()
499 }
500}
501
502impl<'a> DigestDataVerify<'a, 32> for Sha256Software<'a> {
503 fn set_client(&'a self, _client: &'a dyn ClientDataVerify<32>) {
504 unimplemented!()
505 }
506}