Add MD5 functionality from ESP ROM (#618)
* Add ROM MD5 definitions in linker and devices * Add initial MD5 support * Implement traits and add comments to MD5 module * Add MD5 example to ESP32-C3 * Test MD5 context on the quick brown fox * Implemenr From<Context> for Digest * Add MD5 to the rest of the examples * Add docs for MD5 * Remove #[repr(transparent)] from md5::Digest * Update CHANGELOG.md
This commit is contained in:
parent
b5fe37e6e7
commit
28fafa05e1
@ -28,6 +28,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Add initial support for `I2S` in ESP32-H2 (#597)
|
- Add initial support for `I2S` in ESP32-H2 (#597)
|
||||||
- Fix rom::crc docs
|
- Fix rom::crc docs
|
||||||
- Add octal PSRAM support for ESP32-S3 (#610)
|
- Add octal PSRAM support for ESP32-S3 (#610)
|
||||||
|
- Add MD5 functions from ESP ROM (#618)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
|||||||
@ -61,6 +61,7 @@ peripherals = [
|
|||||||
# ROM capabilities
|
# ROM capabilities
|
||||||
"rom_crc_le",
|
"rom_crc_le",
|
||||||
"rom_crc_be",
|
"rom_crc_be",
|
||||||
|
"rom_md5_bsd",
|
||||||
|
|
||||||
# Wakeup SOC based on ESP-IDF:
|
# Wakeup SOC based on ESP-IDF:
|
||||||
"pm_support_ext0_wakeup",
|
"pm_support_ext0_wakeup",
|
||||||
|
|||||||
@ -42,6 +42,7 @@ peripherals = [
|
|||||||
# ROM capabilities
|
# ROM capabilities
|
||||||
"rom_crc_le",
|
"rom_crc_le",
|
||||||
"rom_crc_be",
|
"rom_crc_be",
|
||||||
|
"rom_md5_mbedtls",
|
||||||
|
|
||||||
# Wakeup SOC based on ESP-IDF:
|
# Wakeup SOC based on ESP-IDF:
|
||||||
"pm_support_wifi_wakeup",
|
"pm_support_wifi_wakeup",
|
||||||
|
|||||||
@ -54,6 +54,7 @@ peripherals = [
|
|||||||
# ROM capabilities
|
# ROM capabilities
|
||||||
"rom_crc_le",
|
"rom_crc_le",
|
||||||
"rom_crc_be",
|
"rom_crc_be",
|
||||||
|
"rom_md5_bsd",
|
||||||
|
|
||||||
# Wakeup SOC based on ESP-IDF:
|
# Wakeup SOC based on ESP-IDF:
|
||||||
"pm_support_wifi_wakeup",
|
"pm_support_wifi_wakeup",
|
||||||
|
|||||||
@ -83,6 +83,7 @@ peripherals = [
|
|||||||
# ROM capabilities
|
# ROM capabilities
|
||||||
"rom_crc_le",
|
"rom_crc_le",
|
||||||
"rom_crc_be",
|
"rom_crc_be",
|
||||||
|
"rom_md5_bsd",
|
||||||
|
|
||||||
# Wakeup SOC based on ESP-IDF:
|
# Wakeup SOC based on ESP-IDF:
|
||||||
"pm_support_wifi_wakeup",
|
"pm_support_wifi_wakeup",
|
||||||
|
|||||||
@ -72,4 +72,5 @@ peripherals = [
|
|||||||
# ROM capabilities
|
# ROM capabilities
|
||||||
"rom_crc_le",
|
"rom_crc_le",
|
||||||
"rom_crc_be",
|
"rom_crc_be",
|
||||||
|
"rom_md5_bsd",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -57,6 +57,7 @@ peripherals = [
|
|||||||
|
|
||||||
# ROM capabilities
|
# ROM capabilities
|
||||||
"rom_crc_le",
|
"rom_crc_le",
|
||||||
|
"rom_md5_bsd",
|
||||||
|
|
||||||
# Wakeup SOC based on ESP-IDF:
|
# Wakeup SOC based on ESP-IDF:
|
||||||
"pm_support_ext0_wakeup",
|
"pm_support_ext0_wakeup",
|
||||||
|
|||||||
@ -70,6 +70,7 @@ peripherals = [
|
|||||||
# ROM capabilities
|
# ROM capabilities
|
||||||
"rom_crc_le",
|
"rom_crc_le",
|
||||||
"rom_crc_be",
|
"rom_crc_be",
|
||||||
|
"rom_md5_bsd",
|
||||||
|
|
||||||
# Wakeup SOC based on ESP-IDF:
|
# Wakeup SOC based on ESP-IDF:
|
||||||
"pm_support_ext0_wakeup",
|
"pm_support_ext0_wakeup",
|
||||||
|
|||||||
232
esp-hal-common/src/rom/md5.rs
Normal file
232
esp-hal-common/src/rom/md5.rs
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
//! MD5 Message-Digest Algorithm
|
||||||
|
//!
|
||||||
|
//! # Security Warning
|
||||||
|
//!
|
||||||
|
//! MD5 is a **cryptographically broken** message digest. It should **not**
|
||||||
|
//! be used for data security, for example, to check if data has been
|
||||||
|
//! intentionally tampered with.
|
||||||
|
//!
|
||||||
|
//! However, it is still very useful for purposes of data **integrity**, for
|
||||||
|
//! example, to check if data has been **accidentally** tampered with, such as
|
||||||
|
//! detecting data corrupted during transmission in a stream or stored in
|
||||||
|
//! flash. This is especially important on microcontrollers where the
|
||||||
|
//! computational efficiency of MD5 is desired.
|
||||||
|
//!
|
||||||
|
//! # Compatibility
|
||||||
|
//!
|
||||||
|
//! The public API exposed by this module tries to *mimic* the public API
|
||||||
|
//! offered by the [MD5][1] crate in an effort to act as a drop-in replacement.
|
||||||
|
//! The actual implementation, however, links to whatever is available in the
|
||||||
|
//! ROM of the particular ESP32 target. Each chip target may offer a different
|
||||||
|
//! underlying MD5 implementation with varying functionality.
|
||||||
|
//!
|
||||||
|
//! This module offers a least-common-denominator API to stay consistent with
|
||||||
|
//! all of them. Usage of this module may help make program binaries smaller
|
||||||
|
//! than it would be if you included an MD5 implementation in your project.
|
||||||
|
//!
|
||||||
|
//! # Example
|
||||||
|
//!
|
||||||
|
//! To compute a full digest from a single buffer, use the following:
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! let d: md5::Digest = md5::compute(&data);
|
||||||
|
//! writeln!(uart0, "{}", d);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! To compute a digest over multiple buffers:
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! let mut ctx = md5::Context::new();
|
||||||
|
//! ctx.consume(&data0);
|
||||||
|
//! ctx.consume(&data1);
|
||||||
|
//! let d: md5::Digest = ctx.compute();
|
||||||
|
//! writeln!(uart0, "{}", d);
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
//! [1]: <https://crates.io/crates/md5>
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
use core::ffi::{c_int, c_uchar, c_void};
|
||||||
|
use core::{
|
||||||
|
convert::From,
|
||||||
|
fmt,
|
||||||
|
mem::MaybeUninit,
|
||||||
|
ops::{Deref, DerefMut},
|
||||||
|
};
|
||||||
|
|
||||||
|
// If there is not exactly one of the MD5 variations defined in the device
|
||||||
|
// toml file then `InternalContext` will be either undefined or multiple
|
||||||
|
// defined and this module will fail to compile letting you know to fix it
|
||||||
|
|
||||||
|
#[cfg(doc)]
|
||||||
|
struct InternalContext;
|
||||||
|
|
||||||
|
#[cfg(rom_md5_bsd)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct InternalContext {
|
||||||
|
buf: [u32; 4],
|
||||||
|
bits: [u32; 2],
|
||||||
|
_in: [u8; 64],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(rom_md5_bsd)]
|
||||||
|
extern "C" {
|
||||||
|
fn esp_rom_md5_init(context: *mut InternalContext);
|
||||||
|
fn esp_rom_md5_update(context: *mut InternalContext, buf: *const c_void, len: u32);
|
||||||
|
fn esp_rom_md5_final(digest: *mut u8, context: *mut InternalContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(rom_md5_mbedtls)]
|
||||||
|
#[derive(Clone)]
|
||||||
|
#[repr(C)]
|
||||||
|
struct InternalContext {
|
||||||
|
total: [u32; 2],
|
||||||
|
state: [u32; 4],
|
||||||
|
buffer: [c_uchar; 64],
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(rom_md5_mbedtls)]
|
||||||
|
extern "C" {
|
||||||
|
fn esp_rom_mbedtls_md5_starts_ret(context: *mut InternalContext) -> c_int;
|
||||||
|
fn esp_rom_mbedtls_md5_update_ret(
|
||||||
|
context: *mut InternalContext,
|
||||||
|
buf: *const c_void,
|
||||||
|
len: u32,
|
||||||
|
) -> c_int;
|
||||||
|
fn esp_rom_mbedtls_md5_finish_ret(context: *mut InternalContext, digest: *mut u8) -> c_int;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// MD5 context for an ongoing computation
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct Context(InternalContext);
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
/// Create a new MD5 context
|
||||||
|
#[inline]
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let mut ctx = MaybeUninit::<InternalContext>::uninit();
|
||||||
|
unsafe {
|
||||||
|
#[cfg(rom_md5_bsd)]
|
||||||
|
esp_rom_md5_init(ctx.as_mut_ptr());
|
||||||
|
|
||||||
|
#[cfg(rom_md5_mbedtls)]
|
||||||
|
let _ = esp_rom_mbedtls_md5_starts_ret(ctx.as_mut_ptr());
|
||||||
|
|
||||||
|
Self(ctx.assume_init())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Feed data to the hasher
|
||||||
|
#[inline]
|
||||||
|
pub fn consume<T: AsRef<[u8]>>(&mut self, data: T) {
|
||||||
|
let data = data.as_ref();
|
||||||
|
unsafe {
|
||||||
|
#[cfg(rom_md5_bsd)]
|
||||||
|
esp_rom_md5_update(
|
||||||
|
&mut self.0 as *mut _,
|
||||||
|
data.as_ptr() as *const c_void,
|
||||||
|
data.len() as u32,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[cfg(rom_md5_mbedtls)]
|
||||||
|
let _ = esp_rom_mbedtls_md5_update_ret(
|
||||||
|
&mut self.0 as *mut _,
|
||||||
|
data.as_ptr() as *const c_void,
|
||||||
|
data.len() as u32,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finalize and return a digest
|
||||||
|
#[inline]
|
||||||
|
pub fn compute(mut self) -> Digest {
|
||||||
|
let mut digest = MaybeUninit::<[u8; 16]>::uninit();
|
||||||
|
unsafe {
|
||||||
|
#[cfg(rom_md5_bsd)]
|
||||||
|
esp_rom_md5_final(digest.as_mut_ptr() as *mut _, &mut self.0 as *mut _);
|
||||||
|
|
||||||
|
#[cfg(rom_md5_mbedtls)]
|
||||||
|
let _ = esp_rom_mbedtls_md5_finish_ret(
|
||||||
|
&mut self.0 as *mut _,
|
||||||
|
digest.as_mut_ptr() as *mut _,
|
||||||
|
);
|
||||||
|
|
||||||
|
Digest(digest.assume_init())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compute a full digest from a single buffer
|
||||||
|
#[inline]
|
||||||
|
pub fn compute<T: AsRef<[u8]>>(data: T) -> Digest {
|
||||||
|
let mut ctx = Context::new();
|
||||||
|
ctx.consume(data);
|
||||||
|
ctx.compute()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 16-byte message digest
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||||
|
pub struct Digest(pub [u8; 16]);
|
||||||
|
|
||||||
|
impl fmt::LowerHex for Digest {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
for &byte in &self.0 {
|
||||||
|
write!(f, "{:02x}", byte)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::UpperHex for Digest {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
for &byte in &self.0 {
|
||||||
|
write!(f, "{:02X}", byte)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Digest {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
<Digest as fmt::LowerHex>::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for Digest {
|
||||||
|
#[inline]
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
<Digest as fmt::LowerHex>::fmt(self, f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Digest> for [u8; 16] {
|
||||||
|
#[inline]
|
||||||
|
fn from(digest: Digest) -> Self {
|
||||||
|
digest.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<Context> for Digest {
|
||||||
|
#[inline]
|
||||||
|
fn from(context: Context) -> Digest {
|
||||||
|
context.compute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for Digest {
|
||||||
|
type Target = [u8; 16];
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DerefMut for Digest {
|
||||||
|
#[inline]
|
||||||
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
|
&mut self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -4,6 +4,7 @@
|
|||||||
//! read-only memory.
|
//! read-only memory.
|
||||||
|
|
||||||
pub mod crc;
|
pub mod crc;
|
||||||
|
pub mod md5;
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use esp32_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rom::crc,
|
rom::{crc, md5},
|
||||||
timer::TimerGroup,
|
timer::TimerGroup,
|
||||||
Rtc,
|
Rtc,
|
||||||
Uart,
|
Uart,
|
||||||
@ -40,6 +40,7 @@ fn main() -> ! {
|
|||||||
timer0.start(1u64.secs());
|
timer0.start(1u64.secs());
|
||||||
|
|
||||||
let data = "123456789";
|
let data = "123456789";
|
||||||
|
let sentence = "The quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
@ -66,10 +67,38 @@ fn main() -> ! {
|
|||||||
assert_eq!(crc_rohc, 0xd0);
|
assert_eq!(crc_rohc, 0xd0);
|
||||||
assert_eq!(crc_smbus, 0xf4);
|
assert_eq!(crc_smbus, 0xf4);
|
||||||
|
|
||||||
|
// Hash the sentence one word at a time to *really* test the context
|
||||||
|
// Use Peekable while iter_intersperse is unstable
|
||||||
|
let mut md5_ctx = md5::Context::new();
|
||||||
|
let mut it = sentence.split_whitespace().peekable();
|
||||||
|
while let Some(word) = it.next() {
|
||||||
|
md5_ctx.consume(word);
|
||||||
|
if it.peek().is_some() {
|
||||||
|
md5_ctx.consume(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let md5_digest = md5_ctx.compute();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
md5_digest,
|
||||||
|
md5::Digest([
|
||||||
|
0x30, 0xde, 0xd8, 0x07, 0xd6, 0x5e, 0xe0, 0x37, 0x0f, 0xc6, 0xd7, 0x3d, 0x6a, 0xb5,
|
||||||
|
0x5a, 0x95
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x}",
|
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x} {}",
|
||||||
crc_hdlc, crc_bzip2, crc_mpeg2, crc_cksum, crc_kermit, crc_genibus, crc_rohc, crc_smbus
|
crc_hdlc,
|
||||||
|
crc_bzip2,
|
||||||
|
crc_mpeg2,
|
||||||
|
crc_cksum,
|
||||||
|
crc_kermit,
|
||||||
|
crc_genibus,
|
||||||
|
crc_rohc,
|
||||||
|
crc_smbus,
|
||||||
|
md5_digest
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -23,3 +23,7 @@ PROVIDE (esp_rom_crc8_be = 0x4005d114);
|
|||||||
PROVIDE (esp_rom_crc32_le = 0x4005cfec);
|
PROVIDE (esp_rom_crc32_le = 0x4005cfec);
|
||||||
PROVIDE (esp_rom_crc16_le = 0x4005d05c);
|
PROVIDE (esp_rom_crc16_le = 0x4005d05c);
|
||||||
PROVIDE (esp_rom_crc8_le = 0x4005d0e0);
|
PROVIDE (esp_rom_crc8_le = 0x4005d0e0);
|
||||||
|
|
||||||
|
PROVIDE (esp_rom_md5_init = 0x4005da7c);
|
||||||
|
PROVIDE (esp_rom_md5_update = 0x4005da9c);
|
||||||
|
PROVIDE (esp_rom_md5_final = 0x4005db1c);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use esp32c2_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rom::crc,
|
rom::{crc, md5},
|
||||||
timer::TimerGroup,
|
timer::TimerGroup,
|
||||||
Rtc,
|
Rtc,
|
||||||
Uart,
|
Uart,
|
||||||
@ -41,6 +41,7 @@ fn main() -> ! {
|
|||||||
timer0.start(1u64.secs());
|
timer0.start(1u64.secs());
|
||||||
|
|
||||||
let data = "123456789";
|
let data = "123456789";
|
||||||
|
let sentence = "The quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
@ -67,10 +68,38 @@ fn main() -> ! {
|
|||||||
assert_eq!(crc_rohc, 0xd0);
|
assert_eq!(crc_rohc, 0xd0);
|
||||||
assert_eq!(crc_smbus, 0xf4);
|
assert_eq!(crc_smbus, 0xf4);
|
||||||
|
|
||||||
|
// Hash the sentence one word at a time to *really* test the context
|
||||||
|
// Use Peekable while iter_intersperse is unstable
|
||||||
|
let mut md5_ctx = md5::Context::new();
|
||||||
|
let mut it = sentence.split_whitespace().peekable();
|
||||||
|
while let Some(word) = it.next() {
|
||||||
|
md5_ctx.consume(word);
|
||||||
|
if it.peek().is_some() {
|
||||||
|
md5_ctx.consume(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let md5_digest = md5_ctx.compute();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
md5_digest,
|
||||||
|
md5::Digest([
|
||||||
|
0x30, 0xde, 0xd8, 0x07, 0xd6, 0x5e, 0xe0, 0x37, 0x0f, 0xc6, 0xd7, 0x3d, 0x6a, 0xb5,
|
||||||
|
0x5a, 0x95
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x}",
|
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x} {}",
|
||||||
crc_hdlc, crc_bzip2, crc_mpeg2, crc_cksum, crc_kermit, crc_genibus, crc_rohc, crc_smbus
|
crc_hdlc,
|
||||||
|
crc_bzip2,
|
||||||
|
crc_mpeg2,
|
||||||
|
crc_cksum,
|
||||||
|
crc_kermit,
|
||||||
|
crc_genibus,
|
||||||
|
crc_rohc,
|
||||||
|
crc_smbus,
|
||||||
|
md5_digest
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -12,3 +12,7 @@ PROVIDE(esp_rom_crc8_be = 0x40000810);
|
|||||||
PROVIDE(esp_rom_crc32_le = 0x400007fc);
|
PROVIDE(esp_rom_crc32_le = 0x400007fc);
|
||||||
PROVIDE(esp_rom_crc16_le = 0x40000800);
|
PROVIDE(esp_rom_crc16_le = 0x40000800);
|
||||||
PROVIDE(esp_rom_crc8_le = 0x40000804);
|
PROVIDE(esp_rom_crc8_le = 0x40000804);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_mbedtls_md5_starts_ret = 0x40002be4);
|
||||||
|
PROVIDE(esp_rom_mbedtls_md5_update_ret = 0x40002be8);
|
||||||
|
PROVIDE(esp_rom_mbedtls_md5_finish_ret = 0x40002bec);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use esp32c3_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rom::crc,
|
rom::{crc, md5},
|
||||||
timer::TimerGroup,
|
timer::TimerGroup,
|
||||||
Rtc,
|
Rtc,
|
||||||
Uart,
|
Uart,
|
||||||
@ -48,6 +48,7 @@ fn main() -> ! {
|
|||||||
timer0.start(1u64.secs());
|
timer0.start(1u64.secs());
|
||||||
|
|
||||||
let data = "123456789";
|
let data = "123456789";
|
||||||
|
let sentence = "The quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
uart0,
|
uart0,
|
||||||
@ -74,10 +75,38 @@ fn main() -> ! {
|
|||||||
assert_eq!(crc_rohc, 0xd0);
|
assert_eq!(crc_rohc, 0xd0);
|
||||||
assert_eq!(crc_smbus, 0xf4);
|
assert_eq!(crc_smbus, 0xf4);
|
||||||
|
|
||||||
|
// Hash the sentence one word at a time to *really* test the context
|
||||||
|
// Use Peekable while iter_intersperse is unstable
|
||||||
|
let mut md5_ctx = md5::Context::new();
|
||||||
|
let mut it = sentence.split_whitespace().peekable();
|
||||||
|
while let Some(word) = it.next() {
|
||||||
|
md5_ctx.consume(word);
|
||||||
|
if it.peek().is_some() {
|
||||||
|
md5_ctx.consume(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let md5_digest = md5_ctx.compute();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
md5_digest,
|
||||||
|
md5::Digest([
|
||||||
|
0x30, 0xde, 0xd8, 0x07, 0xd6, 0x5e, 0xe0, 0x37, 0x0f, 0xc6, 0xd7, 0x3d, 0x6a, 0xb5,
|
||||||
|
0x5a, 0x95
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
uart0,
|
uart0,
|
||||||
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x}",
|
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x} {}",
|
||||||
crc_hdlc, crc_bzip2, crc_mpeg2, crc_cksum, crc_kermit, crc_genibus, crc_rohc, crc_smbus
|
crc_hdlc,
|
||||||
|
crc_bzip2,
|
||||||
|
crc_mpeg2,
|
||||||
|
crc_cksum,
|
||||||
|
crc_kermit,
|
||||||
|
crc_genibus,
|
||||||
|
crc_rohc,
|
||||||
|
crc_smbus,
|
||||||
|
md5_digest
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -19,3 +19,7 @@ PROVIDE(esp_rom_crc8_be = 0x4000063c);
|
|||||||
PROVIDE(esp_rom_crc32_le = 0x40000628);
|
PROVIDE(esp_rom_crc32_le = 0x40000628);
|
||||||
PROVIDE(esp_rom_crc16_le = 0x40000630);
|
PROVIDE(esp_rom_crc16_le = 0x40000630);
|
||||||
PROVIDE(esp_rom_crc8_le = 0x40000638);
|
PROVIDE(esp_rom_crc8_le = 0x40000638);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_md5_init = 0x40000614);
|
||||||
|
PROVIDE(esp_rom_md5_update = 0x40000618);
|
||||||
|
PROVIDE(esp_rom_md5_final = 0x4000061c);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use esp32c6_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rom::crc,
|
rom::{crc, md5},
|
||||||
timer::TimerGroup,
|
timer::TimerGroup,
|
||||||
Rtc,
|
Rtc,
|
||||||
Uart,
|
Uart,
|
||||||
@ -48,6 +48,7 @@ fn main() -> ! {
|
|||||||
timer0.start(1u64.secs());
|
timer0.start(1u64.secs());
|
||||||
|
|
||||||
let data = "123456789";
|
let data = "123456789";
|
||||||
|
let sentence = "The quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
uart0,
|
uart0,
|
||||||
@ -74,10 +75,38 @@ fn main() -> ! {
|
|||||||
assert_eq!(crc_rohc, 0xd0);
|
assert_eq!(crc_rohc, 0xd0);
|
||||||
assert_eq!(crc_smbus, 0xf4);
|
assert_eq!(crc_smbus, 0xf4);
|
||||||
|
|
||||||
|
// Hash the sentence one word at a time to *really* test the context
|
||||||
|
// Use Peekable while iter_intersperse is unstable
|
||||||
|
let mut md5_ctx = md5::Context::new();
|
||||||
|
let mut it = sentence.split_whitespace().peekable();
|
||||||
|
while let Some(word) = it.next() {
|
||||||
|
md5_ctx.consume(word);
|
||||||
|
if it.peek().is_some() {
|
||||||
|
md5_ctx.consume(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let md5_digest = md5_ctx.compute();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
md5_digest,
|
||||||
|
md5::Digest([
|
||||||
|
0x30, 0xde, 0xd8, 0x07, 0xd6, 0x5e, 0xe0, 0x37, 0x0f, 0xc6, 0xd7, 0x3d, 0x6a, 0xb5,
|
||||||
|
0x5a, 0x95
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
uart0,
|
uart0,
|
||||||
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x}",
|
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x} {}",
|
||||||
crc_hdlc, crc_bzip2, crc_mpeg2, crc_cksum, crc_kermit, crc_genibus, crc_rohc, crc_smbus
|
crc_hdlc,
|
||||||
|
crc_bzip2,
|
||||||
|
crc_mpeg2,
|
||||||
|
crc_cksum,
|
||||||
|
crc_kermit,
|
||||||
|
crc_genibus,
|
||||||
|
crc_rohc,
|
||||||
|
crc_smbus,
|
||||||
|
md5_digest
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -19,3 +19,7 @@ PROVIDE(esp_rom_crc8_be = 0x4000076c);
|
|||||||
PROVIDE(esp_rom_crc32_le = 0x40000758);
|
PROVIDE(esp_rom_crc32_le = 0x40000758);
|
||||||
PROVIDE(esp_rom_crc16_le = 0x4000075c);
|
PROVIDE(esp_rom_crc16_le = 0x4000075c);
|
||||||
PROVIDE(esp_rom_crc8_le = 0x40000760);
|
PROVIDE(esp_rom_crc8_le = 0x40000760);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_md5_init = 0x4000074c);
|
||||||
|
PROVIDE(esp_rom_md5_update = 0x40000750);
|
||||||
|
PROVIDE(esp_rom_md5_final = 0x40000754);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use esp32h2_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rom::crc,
|
rom::{crc, md5},
|
||||||
timer::TimerGroup,
|
timer::TimerGroup,
|
||||||
Rtc,
|
Rtc,
|
||||||
Uart,
|
Uart,
|
||||||
@ -49,6 +49,7 @@ fn main() -> ! {
|
|||||||
timer0.start(1u64.secs());
|
timer0.start(1u64.secs());
|
||||||
|
|
||||||
let data = "123456789";
|
let data = "123456789";
|
||||||
|
let sentence = "The quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
uart0,
|
uart0,
|
||||||
@ -75,10 +76,38 @@ fn main() -> ! {
|
|||||||
assert_eq!(crc_rohc, 0xd0);
|
assert_eq!(crc_rohc, 0xd0);
|
||||||
assert_eq!(crc_smbus, 0xf4);
|
assert_eq!(crc_smbus, 0xf4);
|
||||||
|
|
||||||
|
// Hash the sentence one word at a time to *really* test the context
|
||||||
|
// Use Peekable while iter_intersperse is unstable
|
||||||
|
let mut md5_ctx = md5::Context::new();
|
||||||
|
let mut it = sentence.split_whitespace().peekable();
|
||||||
|
while let Some(word) = it.next() {
|
||||||
|
md5_ctx.consume(word);
|
||||||
|
if it.peek().is_some() {
|
||||||
|
md5_ctx.consume(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let md5_digest = md5_ctx.compute();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
md5_digest,
|
||||||
|
md5::Digest([
|
||||||
|
0x30, 0xde, 0xd8, 0x07, 0xd6, 0x5e, 0xe0, 0x37, 0x0f, 0xc6, 0xd7, 0x3d, 0x6a, 0xb5,
|
||||||
|
0x5a, 0x95
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
uart0,
|
uart0,
|
||||||
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x}",
|
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x} {}",
|
||||||
crc_hdlc, crc_bzip2, crc_mpeg2, crc_cksum, crc_kermit, crc_genibus, crc_rohc, crc_smbus
|
crc_hdlc,
|
||||||
|
crc_bzip2,
|
||||||
|
crc_mpeg2,
|
||||||
|
crc_cksum,
|
||||||
|
crc_kermit,
|
||||||
|
crc_genibus,
|
||||||
|
crc_rohc,
|
||||||
|
crc_smbus,
|
||||||
|
md5_digest
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -19,3 +19,7 @@ PROVIDE(esp_rom_crc8_be = 0x40000738);
|
|||||||
PROVIDE(esp_rom_crc32_le = 0x40000724);
|
PROVIDE(esp_rom_crc32_le = 0x40000724);
|
||||||
PROVIDE(esp_rom_crc16_le = 0x40000728);
|
PROVIDE(esp_rom_crc16_le = 0x40000728);
|
||||||
PROVIDE(esp_rom_crc8_le = 0x4000072c);
|
PROVIDE(esp_rom_crc8_le = 0x4000072c);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_md5_init = 0x40000718);
|
||||||
|
PROVIDE(esp_rom_md5_update = 0x4000071c);
|
||||||
|
PROVIDE(esp_rom_md5_final = 0x40000720);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use esp32s2_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rom::crc,
|
rom::{crc, md5},
|
||||||
timer::TimerGroup,
|
timer::TimerGroup,
|
||||||
Rtc,
|
Rtc,
|
||||||
Uart,
|
Uart,
|
||||||
@ -40,6 +40,7 @@ fn main() -> ! {
|
|||||||
timer0.start(1u64.secs());
|
timer0.start(1u64.secs());
|
||||||
|
|
||||||
let data = "123456789";
|
let data = "123456789";
|
||||||
|
let sentence = "The quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
@ -66,10 +67,38 @@ fn main() -> ! {
|
|||||||
assert_eq!(crc_rohc, 0xd0);
|
assert_eq!(crc_rohc, 0xd0);
|
||||||
assert_eq!(crc_smbus, 0xf4);
|
assert_eq!(crc_smbus, 0xf4);
|
||||||
|
|
||||||
|
// Hash the sentence one word at a time to *really* test the context
|
||||||
|
// Use Peekable while iter_intersperse is unstable
|
||||||
|
let mut md5_ctx = md5::Context::new();
|
||||||
|
let mut it = sentence.split_whitespace().peekable();
|
||||||
|
while let Some(word) = it.next() {
|
||||||
|
md5_ctx.consume(word);
|
||||||
|
if it.peek().is_some() {
|
||||||
|
md5_ctx.consume(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let md5_digest = md5_ctx.compute();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
md5_digest,
|
||||||
|
md5::Digest([
|
||||||
|
0x30, 0xde, 0xd8, 0x07, 0xd6, 0x5e, 0xe0, 0x37, 0x0f, 0xc6, 0xd7, 0x3d, 0x6a, 0xb5,
|
||||||
|
0x5a, 0x95
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x}",
|
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x} {}",
|
||||||
crc_hdlc, crc_bzip2, crc_mpeg2, crc_cksum, crc_kermit, crc_genibus, crc_rohc, crc_smbus
|
crc_hdlc,
|
||||||
|
crc_bzip2,
|
||||||
|
crc_mpeg2,
|
||||||
|
crc_cksum,
|
||||||
|
crc_kermit,
|
||||||
|
crc_genibus,
|
||||||
|
crc_rohc,
|
||||||
|
crc_smbus,
|
||||||
|
md5_digest
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -23,3 +23,7 @@ PROVIDE ( esp_rom_spi_cmd_config = 0x40017c58 );
|
|||||||
PROVIDE(esp_rom_crc32_le = 0x400119dc);
|
PROVIDE(esp_rom_crc32_le = 0x400119dc);
|
||||||
PROVIDE(esp_rom_crc16_le = 0x40011a10);
|
PROVIDE(esp_rom_crc16_le = 0x40011a10);
|
||||||
PROVIDE(esp_rom_crc8_le = 0x40011a4c);
|
PROVIDE(esp_rom_crc8_le = 0x40011a4c);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_md5_final = 0x4000530c);
|
||||||
|
PROVIDE(esp_rom_md5_init = 0x4000526c);
|
||||||
|
PROVIDE(esp_rom_md5_update = 0x4000528c);
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use esp32s3_hal::{
|
|||||||
clock::ClockControl,
|
clock::ClockControl,
|
||||||
peripherals::Peripherals,
|
peripherals::Peripherals,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
rom::crc,
|
rom::{crc, md5},
|
||||||
timer::TimerGroup,
|
timer::TimerGroup,
|
||||||
Rtc,
|
Rtc,
|
||||||
Uart,
|
Uart,
|
||||||
@ -40,6 +40,7 @@ fn main() -> ! {
|
|||||||
timer0.start(1u64.secs());
|
timer0.start(1u64.secs());
|
||||||
|
|
||||||
let data = "123456789";
|
let data = "123456789";
|
||||||
|
let sentence = "The quick brown fox jumps over a lazy dog";
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
@ -66,10 +67,38 @@ fn main() -> ! {
|
|||||||
assert_eq!(crc_rohc, 0xd0);
|
assert_eq!(crc_rohc, 0xd0);
|
||||||
assert_eq!(crc_smbus, 0xf4);
|
assert_eq!(crc_smbus, 0xf4);
|
||||||
|
|
||||||
|
// Hash the sentence one word at a time to *really* test the context
|
||||||
|
// Use Peekable while iter_intersperse is unstable
|
||||||
|
let mut md5_ctx = md5::Context::new();
|
||||||
|
let mut it = sentence.split_whitespace().peekable();
|
||||||
|
while let Some(word) = it.next() {
|
||||||
|
md5_ctx.consume(word);
|
||||||
|
if it.peek().is_some() {
|
||||||
|
md5_ctx.consume(" ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let md5_digest = md5_ctx.compute();
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
md5_digest,
|
||||||
|
md5::Digest([
|
||||||
|
0x30, 0xde, 0xd8, 0x07, 0xd6, 0x5e, 0xe0, 0x37, 0x0f, 0xc6, 0xd7, 0x3d, 0x6a, 0xb5,
|
||||||
|
0x5a, 0x95
|
||||||
|
])
|
||||||
|
);
|
||||||
|
|
||||||
writeln!(
|
writeln!(
|
||||||
serial0,
|
serial0,
|
||||||
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x}",
|
"{:08x} {:08x} {:08x} {:08x} {:04x} {:04x} {:02x} {:02x} {}",
|
||||||
crc_hdlc, crc_bzip2, crc_mpeg2, crc_cksum, crc_kermit, crc_genibus, crc_rohc, crc_smbus
|
crc_hdlc,
|
||||||
|
crc_bzip2,
|
||||||
|
crc_mpeg2,
|
||||||
|
crc_cksum,
|
||||||
|
crc_kermit,
|
||||||
|
crc_genibus,
|
||||||
|
crc_rohc,
|
||||||
|
crc_smbus,
|
||||||
|
md5_digest
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,10 @@ PROVIDE(esp_rom_crc32_le = 0x40001c98);
|
|||||||
PROVIDE(esp_rom_crc16_le = 0x40001cb0);
|
PROVIDE(esp_rom_crc16_le = 0x40001cb0);
|
||||||
PROVIDE(esp_rom_crc8_le = 0x40001cc8);
|
PROVIDE(esp_rom_crc8_le = 0x40001cc8);
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_md5_init = 0x40001c5c);
|
||||||
|
PROVIDE(esp_rom_md5_update = 0x40001c68);
|
||||||
|
PROVIDE(esp_rom_md5_final = 0x40001c74);
|
||||||
|
|
||||||
PROVIDE (esp_rom_opiflash_exec_cmd = 0x400008b8);
|
PROVIDE (esp_rom_opiflash_exec_cmd = 0x400008b8);
|
||||||
PROVIDE( esp_rom_spi_set_dtr_swap_mode = 0x4000093c );
|
PROVIDE( esp_rom_spi_set_dtr_swap_mode = 0x4000093c );
|
||||||
PROVIDE( esp_rom_opiflash_pin_config = 0x40000894 );
|
PROVIDE( esp_rom_opiflash_pin_config = 0x40000894 );
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user