Files
agent_lib/src/ed25519.rs

129 lines
3.2 KiB
Rust

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
}