chore: Move rest of coloring.rs into secret-memory crate

Also removes the StoreSecret trait from cli.rs as it was
redundant.
This commit is contained in:
Karolin Varner
2023-11-30 12:46:13 +01:00
committed by Karolin Varner
parent 7bda010a9b
commit cf132bca11
12 changed files with 72 additions and 83 deletions

3
Cargo.lock generated
View File

@@ -1064,7 +1064,6 @@ dependencies = [
"clap 4.4.8", "clap 4.4.8",
"criterion", "criterion",
"env_logger", "env_logger",
"lazy_static",
"libsodium-sys-stable", "libsodium-sys-stable",
"log", "log",
"memoffset", "memoffset",
@@ -1122,6 +1121,8 @@ name = "rosenpass-secret-memory"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"lazy_static",
"libsodium-sys-stable",
"rosenpass-sodium", "rosenpass-sodium",
"rosenpass-to", "rosenpass-to",
"rosenpass-util", "rosenpass-util",

View File

@@ -11,6 +11,7 @@ cargo-fuzz = true
arbitrary = { workspace = true } arbitrary = { workspace = true }
libfuzzer-sys = { workspace = true } libfuzzer-sys = { workspace = true }
stacker = { workspace = true } stacker = { workspace = true }
rosenpass-secret-memory = { workspace = true }
rosenpass-sodium = { workspace = true } rosenpass-sodium = { workspace = true }
rosenpass-ciphers = { workspace = true } rosenpass-ciphers = { workspace = true }
rosenpass-to = { workspace = true } rosenpass-to = { workspace = true }

View File

@@ -3,8 +3,8 @@ extern crate rosenpass;
use libfuzzer_sys::fuzz_target; use libfuzzer_sys::fuzz_target;
use rosenpass::coloring::Secret;
use rosenpass::protocol::CryptoServer; use rosenpass::protocol::CryptoServer;
use rosenpass_secret_memory::Secret;
use rosenpass_sodium::init as sodium_init; use rosenpass_sodium::init as sodium_init;
fuzz_target!(|rx_buf: &[u8]| { fuzz_target!(|rx_buf: &[u8]| {

View File

@@ -25,7 +25,6 @@ static_assertions = { workspace = true }
memoffset = { workspace = true } memoffset = { workspace = true }
libsodium-sys-stable = { workspace = true } libsodium-sys-stable = { workspace = true }
oqs-sys = { workspace = true } oqs-sys = { workspace = true }
lazy_static = { workspace = true }
thiserror = { workspace = true } thiserror = { workspace = true }
paste = { workspace = true } paste = { workspace = true }
log = { workspace = true } log = { workspace = true }

View File

@@ -1,13 +1,12 @@
use anyhow::{bail, ensure}; use anyhow::{bail, ensure};
use clap::Parser; use clap::Parser;
use rosenpass_secret_memory::file::StoreSecret;
use rosenpass_util::file::{LoadValue, LoadValueB64}; use rosenpass_util::file::{LoadValue, LoadValueB64};
use std::path::{Path, PathBuf}; use std::path::PathBuf;
use crate::app_server; use crate::app_server;
use crate::app_server::AppServer; use crate::app_server::AppServer;
use crate::{ use crate::{
// app_server::{AppServer, LoadValue, LoadValueB64},
coloring::Secret,
pqkem::{StaticKEM, KEM}, pqkem::{StaticKEM, KEM},
protocol::{SPk, SSk, SymKey}, protocol::{SPk, SSk, SymKey},
}; };
@@ -248,14 +247,3 @@ impl Cli {
srv.event_loop() srv.event_loop()
} }
} }
trait StoreSecret {
fn store_secret<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()>;
}
impl<const N: usize> StoreSecret for Secret<N> {
fn store_secret<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
std::fs::write(path, self.secret())?;
Ok(())
}
}

View File

@@ -1,4 +1,3 @@
pub mod coloring;
#[rustfmt::skip] #[rustfmt::skip]
pub mod labeled_prf; pub mod labeled_prf;
pub mod app_server; pub mod app_server;

View File

@@ -1,5 +1,5 @@
//! Implementation of the tree-like structure used for the label derivation in [labeled_prf](crate::labeled_prf) //! Implementation of the tree-like structure used for the label derivation in [labeled_prf](crate::labeled_prf)
use crate::coloring::Secret; use rosenpass_secret_memory::Secret;
use anyhow::Result; use anyhow::Result;
use rosenpass_ciphers::{hash, KEY_LEN}; use rosenpass_ciphers::{hash, KEY_LEN};

View File

@@ -68,7 +68,6 @@
//! ``` //! ```
use crate::{ use crate::{
coloring::*,
labeled_prf as lprf, labeled_prf as lprf,
msgs::*, msgs::*,
pqkem::*, pqkem::*,
@@ -76,7 +75,7 @@ use crate::{
}; };
use anyhow::{bail, ensure, Context, Result}; use anyhow::{bail, ensure, Context, Result};
use rosenpass_ciphers::{aead, xaead, KEY_LEN}; use rosenpass_ciphers::{aead, xaead, KEY_LEN};
use rosenpass_secret_memory::Public; use rosenpass_secret_memory::{Public, Secret};
use rosenpass_util::{cat, mem::cpy_min, ord::max_usize, time::Timebase}; use rosenpass_util::{cat, mem::cpy_min, ord::max_usize, time::Timebase};
use std::collections::hash_map::{ use std::collections::hash_map::{
Entry::{Occupied, Vacant}, Entry::{Occupied, Vacant},

View File

@@ -14,3 +14,5 @@ anyhow = { workspace = true }
rosenpass-to = { workspace = true } rosenpass-to = { workspace = true }
rosenpass-sodium = { workspace = true } rosenpass-sodium = { workspace = true }
rosenpass-util = { workspace = true } rosenpass-util = { workspace = true }
libsodium-sys-stable = { workspace = true }
lazy_static = { workspace = true }

View File

@@ -0,0 +1,7 @@
use std::path::Path;
pub trait StoreSecret {
type Error;
fn store_secret<P: AsRef<Path>>(&self, path: P) -> Result<(), Self::Error>;
}

View File

@@ -1,4 +1,8 @@
pub mod debug;
pub mod file;
mod public; mod public;
pub use crate::public::Public; pub use crate::public::Public;
pub mod debug; mod secret;
pub use crate::secret::Secret;

View File

@@ -3,15 +3,17 @@ use lazy_static::lazy_static;
use libsodium_sys as libsodium; use libsodium_sys as libsodium;
use rosenpass_util::{ use rosenpass_util::{
b64::b64_reader, b64::b64_reader,
file::{fopen_r, LoadValue, LoadValueB64, ReadExactToEnd, StoreValue}, file::{fopen_r, LoadValue, LoadValueB64, ReadExactToEnd},
functional::mutating, functional::mutating,
}; };
use std::result::Result;
use std::{ use std::{
collections::HashMap, convert::TryInto, fmt, os::raw::c_void, path::Path, ptr::null_mut, collections::HashMap, convert::TryInto, fmt, os::raw::c_void, path::Path, ptr::null_mut,
sync::Mutex, sync::Mutex,
}; };
use crate::file::StoreSecret;
// This might become a problem in library usage; it's effectively a memory // This might become a problem in library usage; it's effectively a memory
// leak which probably isn't a problem right now because most memory will // leak which probably isn't a problem right now because most memory will
// be reused… // be reused…
@@ -28,7 +30,7 @@ lazy_static! {
/// Further information about the protection in place can be found in in the /// Further information about the protection in place can be found in in the
/// [libsodium documentation](https://libsodium.gitbook.io/doc/memory_management#guarded-heap-allocations) /// [libsodium documentation](https://libsodium.gitbook.io/doc/memory_management#guarded-heap-allocations)
#[derive(Debug)] // TODO check on Debug derive, is that clever #[derive(Debug)] // TODO check on Debug derive, is that clever
pub struct SecretMemoryPool { struct SecretMemoryPool {
pool: HashMap<usize, Vec<*mut c_void>>, pool: HashMap<usize, Vec<*mut c_void>>,
} }
@@ -44,6 +46,7 @@ impl SecretMemoryPool {
/// Return secrete back to the pool for future re-use /// Return secrete back to the pool for future re-use
/// ///
/// This consumes the [Secret], but its memory is re-used. /// This consumes the [Secret], but its memory is re-used.
#[allow(dead_code)]
pub fn release<const N: usize>(&mut self, mut s: Secret<N>) { pub fn release<const N: usize>(&mut self, mut s: Secret<N>) {
unsafe { unsafe {
self.release_by_ref(&mut s); self.release_by_ref(&mut s);
@@ -201,6 +204,50 @@ impl<const N: usize> fmt::Debug for Secret<N> {
} }
} }
impl<const N: usize> LoadValue for Secret<N> {
type Error = anyhow::Error;
fn load<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
let mut v = Self::random();
let p = path.as_ref();
fopen_r(p)?
.read_exact_to_end(v.secret_mut())
.with_context(|| format!("Could not load file {p:?}"))?;
Ok(v)
}
}
impl<const N: usize> LoadValueB64 for Secret<N> {
type Error = anyhow::Error;
fn load_b64<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
use std::io::Read;
let mut v = Self::random();
let p = path.as_ref();
// This might leave some fragments of the secret on the stack;
// in practice this is likely not a problem because the stack likely
// will be overwritten by something else soon but this is not exactly
// guaranteed. It would be possible to remedy this, but since the secret
// data will linger in the Linux page cache anyways with the current
// implementation, going to great length to erase the secret here is
// not worth it right now.
b64_reader(&mut fopen_r(p)?)
.read_exact(v.secret_mut())
.with_context(|| format!("Could not load base64 file {p:?}"))?;
Ok(v)
}
}
impl<const N: usize> StoreSecret for Secret<N> {
type Error = anyhow::Error;
fn store_secret<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
std::fs::write(path, self.secret())?;
Ok(())
}
}
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::*; use super::*;
@@ -274,61 +321,3 @@ mod test {
assert_eq!(new_secret.secret(), &[0; N]); assert_eq!(new_secret.secret(), &[0; N]);
} }
} }
trait StoreSecret {
type Error;
fn store_secret<P: AsRef<Path>>(&self, path: P) -> Result<(), Self::Error>;
}
impl<T: StoreValue> StoreSecret for T {
type Error = <T as StoreValue>::Error;
fn store_secret<P: AsRef<Path>>(&self, path: P) -> Result<(), Self::Error> {
self.store(path)
}
}
impl<const N: usize> LoadValue for Secret<N> {
type Error = anyhow::Error;
fn load<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
let mut v = Self::random();
let p = path.as_ref();
fopen_r(p)?
.read_exact_to_end(v.secret_mut())
.with_context(|| format!("Could not load file {p:?}"))?;
Ok(v)
}
}
impl<const N: usize> LoadValueB64 for Secret<N> {
type Error = anyhow::Error;
fn load_b64<P: AsRef<Path>>(path: P) -> anyhow::Result<Self> {
use std::io::Read;
let mut v = Self::random();
let p = path.as_ref();
// This might leave some fragments of the secret on the stack;
// in practice this is likely not a problem because the stack likely
// will be overwritten by something else soon but this is not exactly
// guaranteed. It would be possible to remedy this, but since the secret
// data will linger in the Linux page cache anyways with the current
// implementation, going to great length to erase the secret here is
// not worth it right now.
b64_reader(&mut fopen_r(p)?)
.read_exact(v.secret_mut())
.with_context(|| format!("Could not load base64 file {p:?}"))?;
Ok(v)
}
}
impl<const N: usize> StoreSecret for Secret<N> {
type Error = anyhow::Error;
fn store_secret<P: AsRef<Path>>(&self, path: P) -> anyhow::Result<()> {
std::fs::write(path, self.secret())?;
Ok(())
}
}