feat(alg): ffi for sha2 of algc
This commit is contained in:
parent
3331e89179
commit
1b582ba202
13 changed files with 159 additions and 29 deletions
|
@ -1,8 +1,8 @@
|
|||
[target.thumbv6m-none-eabi]
|
||||
runner = 'probe-rs run --chip STM32L053R8'
|
||||
|
||||
[build]
|
||||
target = "thumbv6m-none-eabi"
|
||||
# [build]
|
||||
# target = "thumbv6m-none-eabi"
|
||||
|
||||
[alias]
|
||||
arun = "run --target thumbv6m-none-eabi"
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
[build]
|
||||
target = "x86_64-unknown-linux-gnu"
|
||||
|
||||
[alias]
|
||||
abuild = "build --target thumbv6m-none-eabi"
|
||||
atest = "test --target x86_64-unknown-linux-gnu"
|
||||
abench = "bench --target x86_64-unknown-linux-gnu"
|
||||
acheck = "check --target x86_64-unknown-linux-gnu"
|
||||
aclippy = "clippy --target thumbv6m-none-eabi"
|
||||
cflash = "flash --chip STM32L053R8"
|
||||
|
||||
[env]
|
||||
DEFMT_LOG = "trace" # sets the log level to trace
|
|
@ -401,7 +401,7 @@ SHA2Result sha2_256_result(SHA2Context *context, SHA2Digest digest) {
|
|||
return shaSuccess;
|
||||
}
|
||||
|
||||
SHA2Result sha2_256_oneshot(const uint8_t *data, const size_t len,
|
||||
SHA2Result sha2_256_oneshot(const uint8_t data[], const size_t len,
|
||||
SHA2Digest digest) {
|
||||
SHA2Context context;
|
||||
SHA2Result res;
|
||||
|
|
|
@ -43,7 +43,7 @@ typedef struct SHA2Context {
|
|||
} SHA2Context;
|
||||
|
||||
/** data should always be null terminated */
|
||||
extern SHA2Result sha2_256_oneshot(const uint8_t *data, const size_t len,
|
||||
extern SHA2Result sha2_256_oneshot(const uint8_t data[], const size_t len,
|
||||
SHA2Digest digest);
|
||||
extern SHA2Result sha2_256_reset(SHA2Context *context);
|
||||
extern SHA2Result sha2_256_input(SHA2Context *context, const uint8_t data[],
|
||||
|
|
|
@ -14,10 +14,12 @@ void tearDown(void) {}
|
|||
#define SAMPLE(INPUT, HASH) \
|
||||
{(uint8_t[]){INPUT "\0"}, (uint8_t *)(uint32_t[])HASH}
|
||||
|
||||
#define TEST_VALUES_LEN 1
|
||||
#define TEST_VALUES_LEN 2
|
||||
uint8_t *test_values[TEST_VALUES_LEN][2] = {
|
||||
SAMPLE("AAAA", HASH(0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8,
|
||||
0xed584f16, 0x2f46e715, 0x114ee184, 0xf8de9201)),
|
||||
SAMPLE("BAAA", HASH(0x49e3cd45, 0x27c96cdc, 0x010160ff, 0x08520e0c,
|
||||
0xb63c6ef8, 0xc4e7d486, 0x08995343, 0x7f83a159)),
|
||||
};
|
||||
|
||||
void test_sha2_check(void) {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
use core::ffi::c_void;
|
||||
|
||||
use crate::{crc::Crc, ffi::ref_to_voidptr};
|
||||
use crate::{crc::Crc, ffi::ref_to_ptr};
|
||||
|
||||
pub type ChecksumCrc32 = u32; // uint32_t in C
|
||||
|
||||
|
@ -28,7 +26,7 @@ impl Crc for Crc32 {
|
|||
|
||||
#[inline]
|
||||
fn process(&mut self, data: &Self::Input) {
|
||||
unsafe { crc32_process(data, data.len() as u32, self as *mut Self) }
|
||||
unsafe { crc32_process(ref_to_ptr(data), data.len() as u32, self as *mut Self) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -38,7 +36,7 @@ impl Crc for Crc32 {
|
|||
|
||||
#[inline]
|
||||
fn checksum(data: &Self::Input) -> Self::Checksum {
|
||||
unsafe { crc32_checksum(data, data.len() as u32) }
|
||||
unsafe { crc32_checksum(ref_to_ptr(data), data.len() as u32) }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,8 +10,13 @@ pub fn ffi_is_loaded() -> bool {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn ref_to_voidptr<T: ?Sized>(r: &T) -> *const c_void {
|
||||
r as *const T as *const c_void
|
||||
pub(crate) fn ref_to_ptr<T: ?Sized, P>(r: &T) -> *const P {
|
||||
r as *const T as *const P
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn ref_to_ptr_mut<T: ?Sized, P>(r: &mut T) -> *mut P {
|
||||
r as *mut T as *mut P
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
mod sha1;
|
||||
pub use sha1::*;
|
||||
mod sha2;
|
||||
pub use sha2::*;
|
||||
|
|
123
crates/algorithms/src/hash/ffi/sha2.rs
Normal file
123
crates/algorithms/src/hash/ffi/sha2.rs
Normal file
|
@ -0,0 +1,123 @@
|
|||
use crate::ffi::{ref_to_ptr, ref_to_ptr_mut};
|
||||
|
||||
use super::super::sha2::*;
|
||||
|
||||
#[repr(C)]
|
||||
#[allow(non_camel_case_types)]
|
||||
#[allow(unused)]
|
||||
#[allow(clippy::enum_variant_names)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
pub enum SHA2Result {
|
||||
shaSuccess = 0,
|
||||
shaNull, /* Null pointer parameter */
|
||||
shaInputTooLong, /* input data too long */
|
||||
shaStateError, /* called Input after Result */
|
||||
shaBadArg, /* Bad argument was given to a function */
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
|
||||
pub struct SHA2Context {
|
||||
pub intermediate_hash: Digest,
|
||||
pub length_low: u32,
|
||||
pub length_high: u32,
|
||||
pub message_block_index: i16,
|
||||
pub message_block: [u8; SHA2_256_BLOCK_SIZE],
|
||||
pub computed: bool,
|
||||
pub corrupted: bool,
|
||||
}
|
||||
|
||||
impl SHA2Context {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
intermediate_hash: DIGEST_EMPTY,
|
||||
length_low: 0,
|
||||
length_high: 0,
|
||||
message_block_index: 0,
|
||||
message_block: [0; SHA2_256_BLOCK_SIZE],
|
||||
computed: false,
|
||||
corrupted: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SHA2Context {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
mod ffi {
|
||||
use super::*;
|
||||
unsafe extern "C" {
|
||||
pub fn sha2_256_oneshot(data: *const u8, len: usize, digest: *mut Digest) -> SHA2Result;
|
||||
pub fn sha2_256_reset(context: *mut SHA2Context) -> SHA2Result;
|
||||
pub fn sha2_256_input(context: *mut SHA2Context, data: *const u8, len: usize)
|
||||
-> SHA2Result;
|
||||
pub fn sha2_256_result(context: *mut SHA2Context, digest: *mut Digest) -> SHA2Result;
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn sha2_256_oneshot(data: &[u8]) -> Result<Digest, SHA2Result> {
|
||||
let mut digest: Digest = DIGEST_EMPTY;
|
||||
let res =
|
||||
unsafe { ffi::sha2_256_oneshot(ref_to_ptr(data), data.len(), ref_to_ptr_mut(&mut digest)) };
|
||||
to_res(digest, res)
|
||||
}
|
||||
|
||||
pub fn sha2_256_reset(context: &mut SHA2Context) -> Result<(), SHA2Result> {
|
||||
let res = unsafe { ffi::sha2_256_reset(ref_to_ptr_mut(context)) };
|
||||
to_res((), res)
|
||||
}
|
||||
|
||||
pub fn sha2_256_input(context: &mut SHA2Context, data: &[u8]) -> Result<(), SHA2Result> {
|
||||
let res = unsafe { ffi::sha2_256_input(ref_to_ptr_mut(context), ref_to_ptr(data), data.len()) };
|
||||
to_res((), res)
|
||||
}
|
||||
|
||||
pub fn sha2_256_result(context: &mut SHA2Context) -> Result<Digest, SHA2Result> {
|
||||
let mut digest: Digest = DIGEST_EMPTY;
|
||||
let res = unsafe { ffi::sha2_256_result(ref_to_ptr_mut(context), ref_to_ptr_mut(&mut digest)) };
|
||||
to_res(digest, res)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_res<T>(if_ok: T, res: SHA2Result) -> Result<T, SHA2Result> {
|
||||
if res == SHA2Result::shaSuccess {
|
||||
Ok(if_ok)
|
||||
} else {
|
||||
Err(res)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crate::digest;
|
||||
use crate::hash::Digest;
|
||||
use crate::hash::ffi::sha2_256_oneshot;
|
||||
|
||||
const TEST_VALUES: &[(&str, Digest)] = &[
|
||||
(
|
||||
"AAAA",
|
||||
digest!(
|
||||
0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8, 0xed584f16, 0x2f46e715, 0x114ee184,
|
||||
0xf8de9201
|
||||
),
|
||||
),
|
||||
(
|
||||
"BAAA",
|
||||
digest!(
|
||||
0x49e3cd45, 0x27c96cdc, 0x010160ff, 0x08520e0c, 0xb63c6ef8, 0xc4e7d486, 0x08995343,
|
||||
0x7f83a159
|
||||
),
|
||||
),
|
||||
];
|
||||
|
||||
#[test]
|
||||
fn test_check() {
|
||||
for (input, expected_output) in TEST_VALUES.iter().copied() {
|
||||
assert_eq!(sha2_256_oneshot(input.as_bytes()), Ok(expected_output))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
pub mod ffi;
|
||||
|
||||
mod sha1;
|
||||
pub use sha1::*;
|
||||
mod sha2;
|
||||
pub use sha2::*;
|
||||
|
|
15
crates/algorithms/src/hash/sha2.rs
Normal file
15
crates/algorithms/src/hash/sha2.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
pub const SHA2_256_HASH_BITS: usize = 256;
|
||||
pub const SHA2_256_HASH_BYTES: usize = SHA2_256_HASH_BITS / 8;
|
||||
pub const SHA2_256_HASH_PARTS: usize = SHA2_256_HASH_BYTES / 4 /* storing with u32 */;
|
||||
pub const SHA2_256_BLOCK_SIZE: usize = 2 * SHA2_256_HASH_BYTES;
|
||||
|
||||
pub type Digest = [u32; SHA2_256_HASH_PARTS];
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! digest {
|
||||
($($block:literal$(,)?)+) => {
|
||||
[$($block,)+ ]
|
||||
};
|
||||
}
|
||||
|
||||
pub(crate) const DIGEST_EMPTY: Digest = [0; SHA2_256_HASH_PARTS];
|
Loading…
Add table
Reference in a new issue