capsules_extra/test/
siphash24.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Test the software implementation of SipHash24 by performing a hash
6//! and checking it against the expected hash value. It uses
7//! DigestData::add_date and DigestVerify::verify through the
8//! Digest trait.
9
10use crate::sip_hash::SipHasher24;
11use capsules_core::test::capsule_test::{CapsuleTest, CapsuleTestClient, CapsuleTestError};
12use kernel::hil::hasher::{Client, Hasher};
13use kernel::utilities::cells::OptionalCell;
14use kernel::utilities::cells::TakeCell;
15use kernel::utilities::leasable_buffer::{SubSlice, SubSliceMut};
16use kernel::ErrorCode;
17
18pub struct TestSipHash24 {
19    hasher: &'static SipHasher24<'static>,
20    data: TakeCell<'static, [u8]>,            // The data to hash
21    hash: TakeCell<'static, [u8; 8]>,         // The supplied hash
22    correct_hash: TakeCell<'static, [u8; 8]>, // The correct hash
23    client: OptionalCell<&'static dyn CapsuleTestClient>,
24}
25
26impl TestSipHash24 {
27    pub fn new(
28        hasher: &'static SipHasher24<'static>,
29        data: &'static mut [u8],
30        hash: &'static mut [u8; 8],
31        correct_hash: &'static mut [u8; 8],
32    ) -> Self {
33        TestSipHash24 {
34            hasher,
35            data: TakeCell::new(data),
36            hash: TakeCell::new(hash),
37            correct_hash: TakeCell::new(correct_hash),
38            client: OptionalCell::empty(),
39        }
40    }
41
42    pub fn run(&'static self) {
43        self.hasher.set_client(self);
44        let data = self.data.take().unwrap();
45        let buffer = SubSliceMut::new(data);
46        let r = self.hasher.add_mut_data(buffer);
47        if r.is_err() {
48            panic!("SipHash24Test: failed to add data: {:?}", r);
49        }
50    }
51}
52
53impl Client<8> for TestSipHash24 {
54    fn add_mut_data_done(&self, _result: Result<(), ErrorCode>, data: SubSliceMut<'static, u8>) {
55        self.data.replace(data.take());
56        self.hasher.run(self.hash.take().unwrap()).unwrap();
57    }
58
59    fn add_data_done(&self, _result: Result<(), ErrorCode>, _data: SubSlice<'static, u8>) {}
60
61    fn hash_done(&self, _result: Result<(), ErrorCode>, digest: &'static mut [u8; 8]) {
62        let correct = self.correct_hash.take().unwrap();
63
64        let matches = correct != digest;
65        if !matches {
66            kernel::debug!("TestSipHash24: incorrect hash output!");
67        }
68        kernel::debug!("TestSipHash24 matches!");
69
70        self.hash.replace(digest);
71        self.hasher.clear_data();
72
73        self.client.map(|client| {
74            let res = if matches {
75                Ok(())
76            } else {
77                Err(CapsuleTestError::IncorrectResult)
78            };
79            client.done(res);
80        });
81    }
82}
83
84impl CapsuleTest for TestSipHash24 {
85    fn set_client(&self, client: &'static dyn CapsuleTestClient) {
86        self.client.set(client);
87    }
88}