From 192e76ad49d5f45975b9620b651e5e82e5bd05de Mon Sep 17 00:00:00 2001 From: Brad Campbell Date: Thu, 22 Jun 2023 10:40:32 -0400 Subject: [PATCH] hmac-sha256: add test --- .../nrf52840dk/src/test/hmac_sha256_test.rs | 58 +++++++++++++ boards/nordic/nrf52840dk/src/test/mod.rs | 1 + capsules/extra/src/test/hmac_sha256.rs | 87 +++++++++++++++++++ capsules/extra/src/test/mod.rs | 1 + 4 files changed, 147 insertions(+) create mode 100644 boards/nordic/nrf52840dk/src/test/hmac_sha256_test.rs create mode 100644 capsules/extra/src/test/hmac_sha256.rs diff --git a/boards/nordic/nrf52840dk/src/test/hmac_sha256_test.rs b/boards/nordic/nrf52840dk/src/test/hmac_sha256_test.rs new file mode 100644 index 0000000000..b9ceba9480 --- /dev/null +++ b/boards/nordic/nrf52840dk/src/test/hmac_sha256_test.rs @@ -0,0 +1,58 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +//! This tests a software HMAC-SHA256 implementation. To run this test, add this +//! line to the imix boot sequence: +//! +//! ``` +//! test::hmac_sha256_test::run_hmacsha256(); +//! ``` + +use capsules_extra::hmac_sha256::HmacSha256Software; +use capsules_extra::sha256::Sha256Software; +use capsules_extra::test::hmac_sha256::TestHmacSha256; +use kernel::deferred_call::DeferredCallClient; +use kernel::hil::digest::Digest; +use kernel::static_init; + +pub unsafe fn run_hmacsha256() { + let t = static_init_test_hmacsha256(); + t.run(); +} + +pub static mut DIGEST_DATA: [u8; 32] = [0; 32]; + +// Test from https://en.wikipedia.org/wiki/HMAC#Examples +pub static mut WIKI_STR: [u8; 43] = *b"The quick brown fox jumps over the lazy dog"; +pub static mut WIKI_KEY: [u8; 3] = *b"key"; +pub static mut WIKI_HMAC: [u8; 32] = [ + 0xf7, 0xbc, 0x83, 0xf4, 0x30, 0x53, 0x84, 0x24, 0xb1, 0x32, 0x98, 0xe6, 0xaa, 0x6f, 0xb1, 0x43, + 0xef, 0x4d, 0x59, 0xa1, 0x49, 0x46, 0x17, 0x59, 0x97, 0x47, 0x9d, 0xbc, 0x2d, 0x1a, 0x3c, 0xd8, +]; + +unsafe fn static_init_test_hmacsha256() -> &'static TestHmacSha256 { + let sha256_hash_buf = static_init!([u8; 64], [0; 64]); + + let sha256 = static_init!(Sha256Software<'static>, Sha256Software::new()); + sha256.register(); + + let hmacsha256 = static_init!( + HmacSha256Software<'static, Sha256Software<'static>>, + HmacSha256Software::new(sha256, sha256_hash_buf) + ); + sha256.set_client(hmacsha256); + + let test = static_init!( + TestHmacSha256, + TestHmacSha256::new( + hmacsha256, + &mut WIKI_KEY, + &mut WIKI_STR, + &mut DIGEST_DATA, + &mut WIKI_HMAC + ) + ); + + test +} diff --git a/boards/nordic/nrf52840dk/src/test/mod.rs b/boards/nordic/nrf52840dk/src/test/mod.rs index f7b26e330b..4929973fbf 100644 --- a/boards/nordic/nrf52840dk/src/test/mod.rs +++ b/boards/nordic/nrf52840dk/src/test/mod.rs @@ -3,4 +3,5 @@ // Copyright Tock Contributors 2023. pub(crate) mod aes_test; +pub(crate) mod hmac_sha256_test; pub(crate) mod siphash24_test; diff --git a/capsules/extra/src/test/hmac_sha256.rs b/capsules/extra/src/test/hmac_sha256.rs new file mode 100644 index 0000000000..5646a0f80b --- /dev/null +++ b/capsules/extra/src/test/hmac_sha256.rs @@ -0,0 +1,87 @@ +// Licensed under the Apache License, Version 2.0 or the MIT License. +// SPDX-License-Identifier: Apache-2.0 OR MIT +// Copyright Tock Contributors 2022. + +//! Test the software implementation of HMAC-SHA256 by performing a hash and +//! checking it against the expected hash value. + +use crate::hmac_sha256::HmacSha256Software; +use crate::sha256::Sha256Software; +use kernel::hil::digest; +use kernel::hil::digest::HmacSha256; +use kernel::hil::digest::{DigestData, DigestDataHash, DigestHash}; +use kernel::utilities::cells::TakeCell; +use kernel::utilities::leasable_buffer::LeasableBuffer; +use kernel::utilities::leasable_buffer::LeasableMutableBuffer; +use kernel::ErrorCode; + +pub struct TestHmacSha256 { + hmac: &'static HmacSha256Software<'static, Sha256Software<'static>>, + key: TakeCell<'static, [u8]>, // The key to use for HMAC + data: TakeCell<'static, [u8]>, // The data to hash + digest: TakeCell<'static, [u8; 32]>, // The supplied hash + correct: &'static [u8; 32], // The supplied hash +} + +impl TestHmacSha256 { + pub fn new( + hmac: &'static HmacSha256Software<'static, Sha256Software<'static>>, + key: &'static mut [u8], + data: &'static mut [u8], + digest: &'static mut [u8; 32], + correct: &'static mut [u8; 32], + ) -> Self { + TestHmacSha256 { + hmac, + key: TakeCell::new(key), + data: TakeCell::new(data), + digest: TakeCell::new(digest), + correct, + } + } + + pub fn run(&'static self) { + self.hmac.set_client(self); + let key = self.key.take().unwrap(); + let r = self.hmac.set_mode_hmacsha256(key); + if r.is_err() { + panic!("HmacSha256Test: failed to set key: {:?}", r); + } + let data = self.data.take().unwrap(); + let buffer = LeasableMutableBuffer::new(data); + let r = self.hmac.add_mut_data(buffer); + if r.is_err() { + panic!("HmacSha256Test: failed to add data: {:?}", r); + } + } +} + +impl digest::ClientData<32> for TestHmacSha256 { + fn add_data_done(&self, _result: Result<(), ErrorCode>, _data: LeasableBuffer<'static, u8>) { + unimplemented!() + } + + fn add_mut_data_done( + &self, + _result: Result<(), ErrorCode>, + data: LeasableMutableBuffer<'static, u8>, + ) { + self.data.replace(data.take()); + + let r = self.hmac.run(self.digest.take().unwrap()); + if r.is_err() { + panic!("HmacSha256Test: failed to run HMAC: {:?}", r); + } + } +} + +impl digest::ClientHash<32> for TestHmacSha256 { + fn hash_done(&self, _result: Result<(), ErrorCode>, digest: &'static mut [u8; 32]) { + for i in 0..32 { + if self.correct[i] != digest[i] { + panic!("HmacSha256Test: incorrect HMAC output!"); + } + } + kernel::debug!("HMAC-SHA256 matches!"); + } +} diff --git a/capsules/extra/src/test/mod.rs b/capsules/extra/src/test/mod.rs index 2f918e5634..a2687eed8a 100644 --- a/capsules/extra/src/test/mod.rs +++ b/capsules/extra/src/test/mod.rs @@ -6,6 +6,7 @@ pub mod aes; pub mod aes_ccm; pub mod aes_gcm; pub mod crc; +pub mod hmac_sha256; pub mod kv_system; pub mod sha256; pub mod siphash24;