Compare commits
31 Commits
dcc698c9f9
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b60e04513 | |||
| b72ea11712 | |||
| ebb738445b | |||
| 0f16f071b4 | |||
| 0bb5c528ee | |||
| c61fb504c6 | |||
| a97adf188b | |||
| 2b23baa3af | |||
| 68ff86b8c6 | |||
| d770fd2641 | |||
| 5c05bd7921 | |||
| 57dae7f181 | |||
| 14f782b46a | |||
| 5c4067608c | |||
| cbf0454517 | |||
| d36eb9afcf | |||
| 05eb75d932 | |||
| 3922222898 | |||
| 46c9a6e499 | |||
| 31126ad5eb | |||
| 312007ea7f | |||
| 2ed3949ee1 | |||
| 54565cb769 | |||
| 4857476043 | |||
| bd7d80765c | |||
| 6ec9735709 | |||
| bbdecfc8cb | |||
| 26a09b5ec2 | |||
| bd19c3639a | |||
| 0edc34a236 | |||
| 82d0f7a3f5 |
12
Cargo.lock
generated
12
Cargo.lock
generated
@@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "agent_lib"
|
||||
@@ -13,20 +13,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.82"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519"
|
||||
checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.153"
|
||||
version = "0.2.159"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
|
||||
checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
|
||||
|
||||
[[package]]
|
||||
name = "shared_memory_heap"
|
||||
version = "0.1.0"
|
||||
source = "git+https://gitea.rixxc.de/rixxc/shared_memory_heap.git#5cd37dfc93aa9bc44df47571396dff70d773fcb2"
|
||||
source = "git+https://gitea.rixxc.de/rixxc/shared_memory_heap.git#ef9bcc94fb04d7191514a249c78d608d2f7cb9a6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
26
src/agent.rs
26
src/agent.rs
@@ -1,7 +1,8 @@
|
||||
use anyhow::{bail, Result};
|
||||
use libc::{
|
||||
c_char, c_void, execve, fork, ftruncate, memfd_create, mmap, perror, syscall, SYS_futex,
|
||||
FUTEX_WAIT, FUTEX_WAKE, MAP_FAILED, MAP_SHARED, PROT_READ, PROT_WRITE,
|
||||
c_char, c_void, close, execve, fcntl, fork, ftruncate, memfd_create, mmap, perror, syscall,
|
||||
SYS_futex, FUTEX_WAIT, FUTEX_WAKE, F_ADD_SEALS, F_SEAL_FUTURE_WRITE, MAP_FAILED, MAP_SHARED,
|
||||
MFD_ALLOW_SEALING, PROT_READ, PROT_WRITE,
|
||||
};
|
||||
use shared_memory_heap::get_shared_mem_fd;
|
||||
use std::{ffi::CString, path::Path, ptr, usize};
|
||||
@@ -13,7 +14,7 @@ pub struct Agent {
|
||||
unsafe impl Send for Agent {}
|
||||
|
||||
impl Agent {
|
||||
pub(crate) unsafe fn new(path: &Path) -> Result<Self> {
|
||||
pub(crate) unsafe fn new(agent_path: &Path, keyfile_path: &Path) -> Result<Self> {
|
||||
let data_fd = get_shared_mem_fd();
|
||||
let sync_fd = memfd_create("sync\x00".as_ptr() as *const c_char, 0);
|
||||
|
||||
@@ -46,15 +47,22 @@ impl Agent {
|
||||
if child == 0 {
|
||||
// child
|
||||
|
||||
close(0);
|
||||
close(1);
|
||||
close(2);
|
||||
|
||||
let path = CString::new(agent_path.as_os_str().as_encoded_bytes()).unwrap();
|
||||
let data_fd = CString::new(data_fd.to_string()).unwrap();
|
||||
let sync_fd = CString::new(sync_fd.to_string()).unwrap();
|
||||
let args = [data_fd.as_ptr(), sync_fd.as_ptr(), ptr::null()];
|
||||
|
||||
execve(
|
||||
path.as_os_str().as_encoded_bytes().as_ptr() as *const c_char,
|
||||
args.as_ptr(),
|
||||
let keyfile = CString::new(keyfile_path.as_os_str().as_encoded_bytes()).unwrap();
|
||||
let args = [
|
||||
data_fd.as_ptr(),
|
||||
sync_fd.as_ptr(),
|
||||
keyfile.as_ptr(),
|
||||
ptr::null(),
|
||||
);
|
||||
];
|
||||
|
||||
execve(path.as_ptr() as *const c_char, args.as_ptr(), ptr::null());
|
||||
|
||||
perror("execve:\x00".as_ptr() as *const c_char);
|
||||
|
||||
|
||||
128
src/ed25519.rs
Normal file
128
src/ed25519.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
pub use shared_memory_heap::sharedptr::SharedPtr;
|
||||
|
||||
use crate::agent::Agent;
|
||||
use std::{
|
||||
ops::Deref,
|
||||
path::Path,
|
||||
sync::{LazyLock, Mutex},
|
||||
};
|
||||
|
||||
static ED25519AGENT: LazyLock<Vec<Mutex<Agent>>> = LazyLock::new(|| {
|
||||
let agent_path = std::env::var("ED25519_AGENT_PATH")
|
||||
.expect("ED25519_AGENT_PATH environment variable missing");
|
||||
let keyfile_path =
|
||||
std::env::var("ED25519_KEYFILE").expect("Ed25519_KEYFILE environment variable missing");
|
||||
let num_agents: usize = std::env::var("NUM_AGENTS")
|
||||
.expect("NUM_AGENTS environment variable missing")
|
||||
.parse()
|
||||
.expect("NUM_AGENTS should be an integer");
|
||||
let mut agents = Vec::with_capacity(num_agents);
|
||||
for _ in 0..num_agents {
|
||||
let agent = unsafe {
|
||||
Agent::new(Path::new(&agent_path), Path::new(&keyfile_path))
|
||||
.expect("Agent failed to start")
|
||||
};
|
||||
agents.push(Mutex::new(agent));
|
||||
}
|
||||
agents
|
||||
});
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Ed25519PrivKey(SharedPtr);
|
||||
#[derive(Debug)]
|
||||
pub struct Ed25519PubKey(SharedPtr);
|
||||
#[derive(Debug)]
|
||||
pub struct Ed25519Signature(SharedPtr);
|
||||
|
||||
impl From<&[u8; 32]> for Ed25519PubKey {
|
||||
fn from(value: &[u8; 32]) -> Self {
|
||||
let mut pk = SharedPtr::new(32).unwrap();
|
||||
pk.copy_from_slice(value);
|
||||
Ed25519PubKey(pk)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[u8; 8]> for Ed25519PrivKey {
|
||||
fn from(value: &[u8; 8]) -> Self {
|
||||
let mut sk = SharedPtr::new(8).unwrap();
|
||||
sk.copy_from_slice(value);
|
||||
Ed25519PrivKey(sk)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Ed25519PrivKey {
|
||||
type Target = [u8; 8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Ed25519PubKey {
|
||||
type Target = [u8; 32];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Ed25519Signature {
|
||||
type Target = [u8; 64];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ed25519_keygen() -> (Ed25519PrivKey, Ed25519PubKey) {
|
||||
let sk = Ed25519PrivKey(SharedPtr::new(8).unwrap());
|
||||
let pk = Ed25519PubKey(SharedPtr::new(32).unwrap());
|
||||
|
||||
let mut agent = None;
|
||||
while agent.is_none() {
|
||||
agent = ED25519AGENT
|
||||
.iter()
|
||||
.map(|agent| agent.try_lock())
|
||||
.filter(|agent| agent.is_ok())
|
||||
.next();
|
||||
}
|
||||
let mut agent = agent.unwrap().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(0, &[sk.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
(sk, pk)
|
||||
}
|
||||
|
||||
pub fn ed25519_sign(sk: &Ed25519PrivKey, msg: &SharedPtr) -> Ed25519Signature {
|
||||
let sig = Ed25519Signature(SharedPtr::new(64).unwrap());
|
||||
|
||||
let mut agent = None;
|
||||
while agent.is_none() {
|
||||
agent = ED25519AGENT
|
||||
.iter()
|
||||
.map(|agent| agent.try_lock())
|
||||
.filter(|agent| agent.is_ok())
|
||||
.next();
|
||||
}
|
||||
let mut agent = agent.unwrap().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(
|
||||
1,
|
||||
&[
|
||||
sk.0.get_offset(),
|
||||
msg.get_offset(),
|
||||
msg.get_size(),
|
||||
sig.0.get_offset(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
sig
|
||||
}
|
||||
51
src/lib.rs
51
src/lib.rs
@@ -1,49 +1,6 @@
|
||||
#![feature(lazy_cell)]
|
||||
|
||||
mod agent;
|
||||
|
||||
pub use shared_memory_heap::sharedptr::SharedPtr;
|
||||
|
||||
use agent::Agent;
|
||||
use std::{
|
||||
path::Path,
|
||||
sync::{LazyLock, Mutex},
|
||||
};
|
||||
|
||||
static AGENT: LazyLock<Mutex<Agent>> = LazyLock::new(|| {
|
||||
let agent_path = std::env::var("AGENT_PATH").expect("AGENT_PATH environment variable missing");
|
||||
let agent = unsafe { Agent::new(Path::new(&agent_path)).expect("Agent failed to start") };
|
||||
Mutex::new(agent)
|
||||
});
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct X25519PrivKey<'a>(SharedPtr<'a, 8>);
|
||||
#[derive(Debug)]
|
||||
pub struct X25519PubKey<'a>(SharedPtr<'a, 32>);
|
||||
#[derive(Debug)]
|
||||
pub struct X25519SharedKey<'a>(SharedPtr<'a, 32>);
|
||||
|
||||
pub fn x25519_keygen<'a>() -> (X25519PrivKey<'a>, X25519PubKey<'a>) {
|
||||
let sk = X25519PrivKey(SharedPtr::<8>::new().unwrap());
|
||||
let pk = X25519PubKey(SharedPtr::<32>::new().unwrap());
|
||||
|
||||
let mut agent = AGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(0, &[sk.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
(sk, pk)
|
||||
}
|
||||
|
||||
pub fn x25519<'a>(sk: &X25519PrivKey, pk: &X25519PubKey) -> X25519SharedKey<'a> {
|
||||
let out = X25519SharedKey(SharedPtr::<32>::new().unwrap());
|
||||
|
||||
let mut agent = AGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(1, &[out.0.get_offset(), sk.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
mod agent;
|
||||
pub mod ed25519;
|
||||
pub mod mlkem;
|
||||
pub mod x25519;
|
||||
|
||||
114
src/mlkem.rs
Normal file
114
src/mlkem.rs
Normal file
@@ -0,0 +1,114 @@
|
||||
pub use shared_memory_heap::sharedptr::SharedPtr;
|
||||
|
||||
use crate::agent::Agent;
|
||||
use std::{
|
||||
ops::Deref, path::Path, sync::{LazyLock, Mutex}
|
||||
};
|
||||
|
||||
static MLKEMAGENT: LazyLock<Mutex<Agent>> = LazyLock::new(|| {
|
||||
let agent_path = std::env::var("MLKEM_AGENT_PATH").expect("MLKEM_AGENT_PATH environment variable missing");
|
||||
let keyfile_path = std::env::var("MLKEM_KEYFILE").expect("MLKEM_KEYFILE environment variable missing");
|
||||
let agent = unsafe { Agent::new(Path::new(&agent_path), Path::new(&keyfile_path)).expect("Agent failed to start") };
|
||||
Mutex::new(agent)
|
||||
});
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MLKEMPrivKey(SharedPtr);
|
||||
#[derive(Debug)]
|
||||
pub struct MLKEMPubKey(SharedPtr);
|
||||
#[derive(Debug)]
|
||||
pub struct MLKEMCiphertext(SharedPtr);
|
||||
#[derive(Debug)]
|
||||
pub struct MLKEMSharedKey(SharedPtr);
|
||||
|
||||
impl From<&[u8; 1184]> for MLKEMPubKey {
|
||||
fn from(value: &[u8; 1184]) -> Self {
|
||||
let mut pk = SharedPtr::new(1184).unwrap();
|
||||
pk.copy_from_slice(value);
|
||||
MLKEMPubKey(pk)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[u8; 8]> for MLKEMPrivKey {
|
||||
fn from(value: &[u8; 8]) -> Self {
|
||||
let mut sk = SharedPtr::new(8).unwrap();
|
||||
sk.copy_from_slice(value);
|
||||
MLKEMPrivKey(sk)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for MLKEMPrivKey {
|
||||
type Target = [u8; 8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for MLKEMPubKey {
|
||||
type Target = [u8; 1184];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for MLKEMCiphertext {
|
||||
type Target = [u8; 1088];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for MLKEMSharedKey {
|
||||
type Target = [u8; 32];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn mlkem_keygen() -> (MLKEMPrivKey, MLKEMPubKey) {
|
||||
let sk = MLKEMPrivKey(SharedPtr::new(8).unwrap());
|
||||
let pk = MLKEMPubKey(SharedPtr::new(1184).unwrap());
|
||||
|
||||
let mut agent = MLKEMAGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(0, &[sk.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
(sk, pk)
|
||||
}
|
||||
|
||||
pub fn mlkem_encap(pk: &MLKEMPubKey) -> (MLKEMCiphertext, MLKEMSharedKey) {
|
||||
let ct = MLKEMCiphertext(SharedPtr::new(1088).unwrap());
|
||||
let ss = MLKEMSharedKey(SharedPtr::new(32).unwrap());
|
||||
|
||||
let mut agent = MLKEMAGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(1, &[ct.0.get_offset(), ss.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
(ct, ss)
|
||||
}
|
||||
|
||||
pub fn mlkem_decap(ct: &MLKEMCiphertext, sk: &MLKEMPrivKey) -> MLKEMSharedKey {
|
||||
let ss = MLKEMSharedKey(SharedPtr::new(32).unwrap());
|
||||
|
||||
let mut agent = MLKEMAGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(2, &[ss.0.get_offset(), ct.0.get_offset(), sk.0.get_offset()]);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
ss
|
||||
}
|
||||
103
src/x25519.rs
Normal file
103
src/x25519.rs
Normal file
@@ -0,0 +1,103 @@
|
||||
pub use shared_memory_heap::sharedptr::SharedPtr;
|
||||
|
||||
use crate::agent::Agent;
|
||||
use std::{
|
||||
ops::Deref, path::Path, sync::{LazyLock, Mutex}
|
||||
};
|
||||
|
||||
static X25519AGENT: LazyLock<Mutex<Agent>> = LazyLock::new(|| {
|
||||
let agent_path = std::env::var("X25519_AGENT_PATH").expect("X25519_AGENT_PATH environment variable missing");
|
||||
let keyfile_path = std::env::var("X25519_KEYFILE").expect("X25519_KEYFILE environment variable missing");
|
||||
let agent = unsafe { Agent::new(Path::new(&agent_path), Path::new(&keyfile_path)).expect("Agent failed to start") };
|
||||
Mutex::new(agent)
|
||||
});
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct X25519PrivKey(SharedPtr);
|
||||
#[derive(Debug)]
|
||||
pub struct X25519PubKey(SharedPtr);
|
||||
#[derive(Debug)]
|
||||
pub struct X25519SharedKey(SharedPtr);
|
||||
|
||||
impl From<&[u8; 32]> for X25519PubKey {
|
||||
fn from(value: &[u8; 32]) -> Self {
|
||||
let mut pk = SharedPtr::new(32).unwrap();
|
||||
pk.copy_from_slice(value);
|
||||
X25519PubKey(pk)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&[u8; 8]> for X25519PrivKey {
|
||||
fn from(value: &[u8; 8]) -> Self {
|
||||
let mut sk = SharedPtr::new(8).unwrap();
|
||||
sk.copy_from_slice(value);
|
||||
X25519PrivKey(sk)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for X25519PrivKey {
|
||||
type Target = [u8; 8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for X25519PubKey {
|
||||
type Target = [u8; 32];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for X25519SharedKey {
|
||||
type Target = [u8; 32];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.deref().try_into().expect("this should never fail")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn x25519_keygen() -> (X25519PrivKey, X25519PubKey) {
|
||||
let sk = X25519PrivKey(SharedPtr::new(8).unwrap());
|
||||
let pk = X25519PubKey(SharedPtr::new(32).unwrap());
|
||||
|
||||
let mut agent = X25519AGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(0, &[sk.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
(sk, pk)
|
||||
}
|
||||
|
||||
pub fn x22519_pubkey(sk: &X25519PrivKey) -> X25519PubKey {
|
||||
let pk = X25519PubKey(SharedPtr::new(32).unwrap());
|
||||
|
||||
let mut agent = X25519AGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(1, &[sk.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
pk
|
||||
}
|
||||
|
||||
pub fn x25519(sk: &X25519PrivKey, pk: &X25519PubKey) -> X25519SharedKey {
|
||||
let out = X25519SharedKey(SharedPtr::new(32).unwrap());
|
||||
|
||||
let mut agent = X25519AGENT.lock().unwrap();
|
||||
|
||||
unsafe {
|
||||
agent.perform_ipc_call(2, &[out.0.get_offset(), sk.0.get_offset(), pk.0.get_offset()]);
|
||||
}
|
||||
|
||||
drop(agent);
|
||||
|
||||
out
|
||||
}
|
||||
Reference in New Issue
Block a user