mirror of
https://github.com/rosenpass/rosenpass.git
synced 2026-02-28 06:23:08 -08:00
chore: Move xor_into, copying and base64 utils into own crates
This commit is contained in:
committed by
Karolin Varner
parent
c9cef05b29
commit
a220c11e67
14
Cargo.lock
generated
14
Cargo.lock
generated
@@ -1014,7 +1014,6 @@ name = "rosenpass"
|
|||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"base64",
|
|
||||||
"clap 4.4.8",
|
"clap 4.4.8",
|
||||||
"criterion",
|
"criterion",
|
||||||
"env_logger",
|
"env_logger",
|
||||||
@@ -1025,6 +1024,8 @@ dependencies = [
|
|||||||
"mio",
|
"mio",
|
||||||
"oqs-sys",
|
"oqs-sys",
|
||||||
"paste",
|
"paste",
|
||||||
|
"rosenpass-constant-time",
|
||||||
|
"rosenpass-util",
|
||||||
"serde",
|
"serde",
|
||||||
"stacker",
|
"stacker",
|
||||||
"static_assertions",
|
"static_assertions",
|
||||||
@@ -1033,6 +1034,17 @@ dependencies = [
|
|||||||
"toml",
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rosenpass-constant-time"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rosenpass-util"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"base64",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc-demangle"
|
name = "rustc-demangle"
|
||||||
version = "0.1.23"
|
version = "0.1.23"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ resolver = "2"
|
|||||||
|
|
||||||
members = [
|
members = [
|
||||||
"rosenpass",
|
"rosenpass",
|
||||||
|
"rosenpass-util",
|
||||||
|
"rosenpass-constant-time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.metadata.release]
|
[workspace.metadata.release]
|
||||||
|
|||||||
14
rosenpass-constant-time/Cargo.toml
Normal file
14
rosenpass-constant-time/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
[package]
|
||||||
|
name = "rosenpass-constant-time"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
description = "Rosenpass internal utilities for constant time crypto implementations"
|
||||||
|
homepage = "https://rosenpass.eu/"
|
||||||
|
repository = "https://github.com/rosenpass/rosenpass"
|
||||||
|
readme = "readme.md"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
5
rosenpass-constant-time/readme.md
Normal file
5
rosenpass-constant-time/readme.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Rosenpass constant time library
|
||||||
|
|
||||||
|
Rosenpass internal library providing basic constant-time operations.
|
||||||
|
|
||||||
|
This is an internal library; not guarantee is made about its API at this point in time.
|
||||||
18
rosenpass-constant-time/src/lib.rs
Normal file
18
rosenpass-constant-time/src/lib.rs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
/// Xors a and b element-wise and writes the result into a.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// use rosenpass_constant_time::xor_into;
|
||||||
|
/// let mut a = String::from("hello").into_bytes();
|
||||||
|
/// let b = b"world";
|
||||||
|
/// xor_into(&mut a, b);
|
||||||
|
/// assert_eq!(&a, b"\x1f\n\x1e\x00\x0b");
|
||||||
|
/// ```
|
||||||
|
#[inline]
|
||||||
|
pub fn xor_into(a: &mut [u8], b: &[u8]) {
|
||||||
|
assert!(a.len() == b.len());
|
||||||
|
for (av, bv) in a.iter_mut().zip(b.iter()) {
|
||||||
|
*av ^= *bv;
|
||||||
|
}
|
||||||
|
}
|
||||||
15
rosenpass-util/Cargo.toml
Normal file
15
rosenpass-util/Cargo.toml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[package]
|
||||||
|
name = "rosenpass-util"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Karolin Varner <karo@cupdev.net>", "wucke13 <wucke13@gmail.com>"]
|
||||||
|
edition = "2021"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
description = "Rosenpass internal utilities"
|
||||||
|
homepage = "https://rosenpass.eu/"
|
||||||
|
repository = "https://github.com/rosenpass/rosenpass"
|
||||||
|
readme = "readme.md"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
base64 = "0.21.1"
|
||||||
20
rosenpass-util/src/b64.rs
Normal file
20
rosenpass-util/src/b64.rs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
use base64::{
|
||||||
|
display::Base64Display as B64Display, read::DecoderReader as B64Reader,
|
||||||
|
write::EncoderWriter as B64Writer,
|
||||||
|
};
|
||||||
|
use std::io::{Read, Write};
|
||||||
|
|
||||||
|
use base64::engine::general_purpose::GeneralPurpose as Base64Engine;
|
||||||
|
const B64ENGINE: Base64Engine = base64::engine::general_purpose::STANDARD;
|
||||||
|
|
||||||
|
pub fn fmt_b64<'a>(payload: &'a [u8]) -> B64Display<'a, 'static, Base64Engine> {
|
||||||
|
B64Display::<'a, 'static>::new(payload, &B64ENGINE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn b64_writer<W: Write>(w: W) -> B64Writer<'static, Base64Engine, W> {
|
||||||
|
B64Writer::new(w, &B64ENGINE)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn b64_reader<R: Read>(r: R) -> B64Reader<'static, Base64Engine, R> {
|
||||||
|
B64Reader::new(r, &B64ENGINE)
|
||||||
|
}
|
||||||
3
rosenpass-util/src/lib.rs
Normal file
3
rosenpass-util/src/lib.rs
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
pub mod b64;
|
||||||
|
pub mod mem;
|
||||||
|
pub mod result;
|
||||||
33
rosenpass-util/src/mem.rs
Normal file
33
rosenpass-util/src/mem.rs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
use std::borrow::{Borrow, BorrowMut};
|
||||||
|
use std::cmp::min;
|
||||||
|
|
||||||
|
/// Concatenate two byte arrays
|
||||||
|
// TODO: Zeroize result?
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! cat {
|
||||||
|
($len:expr; $($toks:expr),+) => {{
|
||||||
|
let mut buf = [0u8; $len];
|
||||||
|
let mut off = 0;
|
||||||
|
$({
|
||||||
|
let tok = $toks;
|
||||||
|
let tr = ::std::borrow::Borrow::<[u8]>::borrow(tok);
|
||||||
|
(&mut buf[off..(off + tr.len())]).copy_from_slice(tr);
|
||||||
|
off += tr.len();
|
||||||
|
})+
|
||||||
|
assert!(off == buf.len(), "Size mismatch in cat!()");
|
||||||
|
buf
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: consistent inout ordering
|
||||||
|
pub fn cpy<T: BorrowMut<[u8]> + ?Sized, F: Borrow<[u8]> + ?Sized>(src: &F, dst: &mut T) {
|
||||||
|
dst.borrow_mut().copy_from_slice(src.borrow());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Copy from `src` to `dst`. If `src` and `dst` are not of equal length, copy as many bytes as possible.
|
||||||
|
pub fn cpy_min<T: BorrowMut<[u8]> + ?Sized, F: Borrow<[u8]> + ?Sized>(src: &F, dst: &mut T) {
|
||||||
|
let src = src.borrow();
|
||||||
|
let dst = dst.borrow_mut();
|
||||||
|
let len = min(src.len(), dst.len());
|
||||||
|
dst[..len].copy_from_slice(&src[..len]);
|
||||||
|
}
|
||||||
7
rosenpass-util/src/result.rs
Normal file
7
rosenpass-util/src/result.rs
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/// Try block basically…returns a result and allows the use of the question mark operator inside
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! attempt {
|
||||||
|
($block:expr) => {
|
||||||
|
(|| -> ::anyhow::Result<_> { $block })()
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -14,8 +14,9 @@ name = "handshake"
|
|||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
rosenpass-util = { path = "../rosenpass-util" }
|
||||||
|
rosenpass-constant-time = { path = "../rosenpass-constant-time" }
|
||||||
anyhow = { version = "1.0.71", features = ["backtrace"] }
|
anyhow = { version = "1.0.71", features = ["backtrace"] }
|
||||||
base64 = "0.21.1"
|
|
||||||
static_assertions = "1.1.0"
|
static_assertions = "1.1.0"
|
||||||
memoffset = "0.9.0"
|
memoffset = "0.9.0"
|
||||||
libsodium-sys-stable = { version = "1.19.28", features = ["use-pkg-config"] }
|
libsodium-sys-stable = { version = "1.19.28", features = ["use-pkg-config"] }
|
||||||
|
|||||||
@@ -26,8 +26,9 @@ use crate::util::fopen_w;
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::Verbosity,
|
config::Verbosity,
|
||||||
protocol::{CryptoServer, MsgBuf, PeerPtr, SPk, SSk, SymKey, Timing},
|
protocol::{CryptoServer, MsgBuf, PeerPtr, SPk, SSk, SymKey, Timing},
|
||||||
util::{b64_writer, fmt_b64},
|
|
||||||
};
|
};
|
||||||
|
use rosenpass_util::attempt;
|
||||||
|
use rosenpass_util::b64::{b64_writer, fmt_b64};
|
||||||
|
|
||||||
const IPV4_ANY_ADDR: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0);
|
const IPV4_ANY_ADDR: Ipv4Addr = Ipv4Addr::new(0, 0, 0, 0);
|
||||||
const IPV6_ANY_ADDR: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
|
const IPV6_ANY_ADDR: Ipv6Addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0);
|
||||||
|
|||||||
@@ -8,10 +8,11 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
sodium::{rng, zeroize},
|
sodium::{rng, zeroize},
|
||||||
util::{cpy, mutating},
|
util::mutating,
|
||||||
};
|
};
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use libsodium_sys as libsodium;
|
use libsodium_sys as libsodium;
|
||||||
|
use rosenpass_util::mem::cpy;
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
convert::TryInto,
|
convert::TryInto,
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ use crate::{
|
|||||||
util::*,
|
util::*,
|
||||||
};
|
};
|
||||||
use anyhow::{bail, ensure, Context, Result};
|
use anyhow::{bail, ensure, Context, Result};
|
||||||
|
use rosenpass_util::{cat, mem::cpy_min};
|
||||||
use std::collections::hash_map::{
|
use std::collections::hash_map::{
|
||||||
Entry::{Occupied, Vacant},
|
Entry::{Occupied, Vacant},
|
||||||
HashMap,
|
HashMap,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
//! Bindings and helpers for accessing libsodium functions
|
//! Bindings and helpers for accessing libsodium functions
|
||||||
|
|
||||||
use crate::util::*;
|
|
||||||
use anyhow::{ensure, Result};
|
use anyhow::{ensure, Result};
|
||||||
use libsodium_sys as libsodium;
|
use libsodium_sys as libsodium;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
use rosenpass_constant_time::xor_into;
|
||||||
|
use rosenpass_util::attempt;
|
||||||
use static_assertions::const_assert_eq;
|
use static_assertions::const_assert_eq;
|
||||||
use std::os::raw::{c_ulonglong, c_void};
|
use std::os::raw::{c_ulonglong, c_void};
|
||||||
use std::ptr::{null as nullptr, null_mut as nullptr_mut};
|
use std::ptr::{null as nullptr, null_mut as nullptr_mut};
|
||||||
|
|||||||
@@ -1,92 +1,14 @@
|
|||||||
//! Helper functions and macros
|
//! Helper functions and macros
|
||||||
use anyhow::{ensure, Context, Result};
|
use anyhow::{ensure, Context, Result};
|
||||||
use base64::{
|
|
||||||
display::Base64Display as B64Display, read::DecoderReader as B64Reader,
|
|
||||||
write::EncoderWriter as B64Writer,
|
|
||||||
};
|
|
||||||
use std::{
|
use std::{
|
||||||
borrow::{Borrow, BorrowMut},
|
|
||||||
cmp::min,
|
|
||||||
fs::{File, OpenOptions},
|
fs::{File, OpenOptions},
|
||||||
io::{Read, Write},
|
io::Read,
|
||||||
path::Path,
|
path::Path,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::coloring::{Public, Secret};
|
use crate::coloring::{Public, Secret};
|
||||||
|
use rosenpass_util::b64::b64_reader;
|
||||||
/// Xors a and b element-wise and writes the result into a.
|
|
||||||
///
|
|
||||||
/// # Examples
|
|
||||||
///
|
|
||||||
/// ```
|
|
||||||
/// use rosenpass::util::xor_into;
|
|
||||||
/// let mut a = String::from("hello").into_bytes();
|
|
||||||
/// let b = b"world";
|
|
||||||
/// xor_into(&mut a, b);
|
|
||||||
/// assert_eq!(&a, b"\x1f\n\x1e\x00\x0b");
|
|
||||||
/// ```
|
|
||||||
#[inline]
|
|
||||||
pub fn xor_into(a: &mut [u8], b: &[u8]) {
|
|
||||||
assert!(a.len() == b.len());
|
|
||||||
for (av, bv) in a.iter_mut().zip(b.iter()) {
|
|
||||||
*av ^= *bv;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Concatenate two byte arrays
|
|
||||||
// TODO: Zeroize result?
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! cat {
|
|
||||||
($len:expr; $($toks:expr),+) => {{
|
|
||||||
let mut buf = [0u8; $len];
|
|
||||||
let mut off = 0;
|
|
||||||
$({
|
|
||||||
let tok = $toks;
|
|
||||||
let tr = ::std::borrow::Borrow::<[u8]>::borrow(tok);
|
|
||||||
(&mut buf[off..(off + tr.len())]).copy_from_slice(tr);
|
|
||||||
off += tr.len();
|
|
||||||
})+
|
|
||||||
assert!(off == buf.len(), "Size mismatch in cat!()");
|
|
||||||
buf
|
|
||||||
}}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: consistent inout ordering
|
|
||||||
pub fn cpy<T: BorrowMut<[u8]> + ?Sized, F: Borrow<[u8]> + ?Sized>(src: &F, dst: &mut T) {
|
|
||||||
dst.borrow_mut().copy_from_slice(src.borrow());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Copy from `src` to `dst`. If `src` and `dst` are not of equal length, copy as many bytes as possible.
|
|
||||||
pub fn cpy_min<T: BorrowMut<[u8]> + ?Sized, F: Borrow<[u8]> + ?Sized>(src: &F, dst: &mut T) {
|
|
||||||
let src = src.borrow();
|
|
||||||
let dst = dst.borrow_mut();
|
|
||||||
let len = min(src.len(), dst.len());
|
|
||||||
dst[..len].copy_from_slice(&src[..len]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Try block basically…returns a result and allows the use of the question mark operator inside
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! attempt {
|
|
||||||
($block:expr) => {
|
|
||||||
(|| -> ::anyhow::Result<_> { $block })()
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
use base64::engine::general_purpose::GeneralPurpose as Base64Engine;
|
|
||||||
const B64ENGINE: Base64Engine = base64::engine::general_purpose::STANDARD;
|
|
||||||
|
|
||||||
pub fn fmt_b64<'a>(payload: &'a [u8]) -> B64Display<'a, 'static, Base64Engine> {
|
|
||||||
B64Display::<'a, 'static>::new(payload, &B64ENGINE)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn b64_writer<W: Write>(w: W) -> B64Writer<'static, Base64Engine, W> {
|
|
||||||
B64Writer::new(w, &B64ENGINE)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn b64_reader<R: Read>(r: R) -> B64Reader<'static, Base64Engine, R> {
|
|
||||||
B64Reader::new(r, &B64ENGINE)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO remove this once std::cmp::max becomes const
|
// TODO remove this once std::cmp::max becomes const
|
||||||
pub const fn max_usize(a: usize, b: usize) -> usize {
|
pub const fn max_usize(a: usize, b: usize) -> usize {
|
||||||
|
|||||||
Reference in New Issue
Block a user