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]
|
[target.thumbv6m-none-eabi]
|
||||||
runner = 'probe-rs run --chip STM32L053R8'
|
runner = 'probe-rs run --chip STM32L053R8'
|
||||||
|
|
||||||
[build]
|
# [build]
|
||||||
target = "thumbv6m-none-eabi"
|
# target = "thumbv6m-none-eabi"
|
||||||
|
|
||||||
[alias]
|
[alias]
|
||||||
arun = "run --target thumbv6m-none-eabi"
|
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;
|
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) {
|
SHA2Digest digest) {
|
||||||
SHA2Context context;
|
SHA2Context context;
|
||||||
SHA2Result res;
|
SHA2Result res;
|
||||||
|
|
|
@ -43,7 +43,7 @@ typedef struct SHA2Context {
|
||||||
} SHA2Context;
|
} SHA2Context;
|
||||||
|
|
||||||
/** data should always be null terminated */
|
/** 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);
|
SHA2Digest digest);
|
||||||
extern SHA2Result sha2_256_reset(SHA2Context *context);
|
extern SHA2Result sha2_256_reset(SHA2Context *context);
|
||||||
extern SHA2Result sha2_256_input(SHA2Context *context, const uint8_t data[],
|
extern SHA2Result sha2_256_input(SHA2Context *context, const uint8_t data[],
|
||||||
|
|
|
@ -14,10 +14,12 @@ void tearDown(void) {}
|
||||||
#define SAMPLE(INPUT, HASH) \
|
#define SAMPLE(INPUT, HASH) \
|
||||||
{(uint8_t[]){INPUT "\0"}, (uint8_t *)(uint32_t[])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] = {
|
uint8_t *test_values[TEST_VALUES_LEN][2] = {
|
||||||
SAMPLE("AAAA", HASH(0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8,
|
SAMPLE("AAAA", HASH(0x63c1dd95, 0x1ffedf6f, 0x7fd968ad, 0x4efa39b8,
|
||||||
0xed584f16, 0x2f46e715, 0x114ee184, 0xf8de9201)),
|
0xed584f16, 0x2f46e715, 0x114ee184, 0xf8de9201)),
|
||||||
|
SAMPLE("BAAA", HASH(0x49e3cd45, 0x27c96cdc, 0x010160ff, 0x08520e0c,
|
||||||
|
0xb63c6ef8, 0xc4e7d486, 0x08995343, 0x7f83a159)),
|
||||||
};
|
};
|
||||||
|
|
||||||
void test_sha2_check(void) {
|
void test_sha2_check(void) {
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
use core::ffi::c_void;
|
use crate::{crc::Crc, ffi::ref_to_ptr};
|
||||||
|
|
||||||
use crate::{crc::Crc, ffi::ref_to_voidptr};
|
|
||||||
|
|
||||||
pub type ChecksumCrc32 = u32; // uint32_t in C
|
pub type ChecksumCrc32 = u32; // uint32_t in C
|
||||||
|
|
||||||
|
@ -28,7 +26,7 @@ impl Crc for Crc32 {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn process(&mut self, data: &Self::Input) {
|
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]
|
#[inline]
|
||||||
|
@ -38,7 +36,7 @@ impl Crc for Crc32 {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn checksum(data: &Self::Input) -> Self::Checksum {
|
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]
|
#[inline]
|
||||||
pub(crate) fn ref_to_voidptr<T: ?Sized>(r: &T) -> *const c_void {
|
pub(crate) fn ref_to_ptr<T: ?Sized, P>(r: &T) -> *const P {
|
||||||
r as *const T as *const c_void
|
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)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
mod sha1;
|
mod sha2;
|
||||||
pub use sha1::*;
|
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;
|
pub mod ffi;
|
||||||
|
|
||||||
mod sha1;
|
mod sha2;
|
||||||
pub use sha1::*;
|
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