From b2de384fcf004d1889cfcd3c7b3920afc7068ea7 Mon Sep 17 00:00:00 2001 From: Paul Spooren Date: Mon, 11 Mar 2024 12:25:58 +0100 Subject: [PATCH] constant-time: add secure memcmp_le function The compare function should do a little-endian comparision, therefore copy the code from quinier/memsec and don't revert the loop, tada, le. Signed-off-by: Paul Spooren --- constant-time/src/compare.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/constant-time/src/compare.rs b/constant-time/src/compare.rs index d5e3605..301da6e 100644 --- a/constant-time/src/compare.rs +++ b/constant-time/src/compare.rs @@ -1,3 +1,18 @@ +use core::ptr; + +/// Little endian memcmp version of quinier/memsec +/// https://github.com/quininer/memsec/blob/bbc647967ff6d20d6dccf1c85f5d9037fcadd3b0/src/lib.rs#L30 +#[inline(never)] +pub unsafe fn memcmp_le(b1: *const u8, b2: *const u8, len: usize) -> i32 { + let mut res = 0; + for i in 0..len { + let diff = + i32::from(ptr::read_volatile(b1.add(i))) - i32::from(ptr::read_volatile(b2.add(i))); + res = (res & (((diff - 1) & !diff) >> 8)) | diff; + } + ((res - 1) >> 8) + (res >> 8) + 1 +} + /// compares two slices of memory content and returns an integer indicating the relationship between /// the slices /// @@ -20,5 +35,5 @@ #[inline] pub fn compare(a: &[u8], b: &[u8]) -> i32 { assert!(a.len() == b.len()); - unsafe { memsec::memcmp(a.as_ptr(), b.as_ptr(), a.len()) } + unsafe { memcmp_le(a.as_ptr(), b.as_ptr(), a.len()) } }