use super::common::{PcStatus, guard, slice, wipe_array};
use crate::ec::x448::X448PrivateKey;
use crate::ec::x25519::X25519PrivateKey;
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pc_x25519(scalar: *const u8, peer: *const u8, out: *mut u8) -> PcStatus {
guard(|| {
let (Some(s), Some(p)) = (unsafe { slice(scalar, 32) }, unsafe { slice(peer, 32) }) else {
return PcStatus::NullPointer;
};
if out.is_null() {
return PcStatus::NullPointer;
}
let scalar: [u8; 32] = s.try_into().unwrap();
let peer: [u8; 32] = p.try_into().unwrap();
let sk = X25519PrivateKey::from_bytes(scalar);
match sk.diffie_hellman(&peer) {
Ok(mut secret) => {
unsafe { core::ptr::copy_nonoverlapping(secret.as_ptr(), out, 32) };
wipe_array(&mut secret);
PcStatus::Ok
}
Err(_) => PcStatus::Verification,
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pc_x25519_public(scalar: *const u8, out: *mut u8) -> PcStatus {
guard(|| {
let Some(s) = (unsafe { slice(scalar, 32) }) else {
return PcStatus::NullPointer;
};
if out.is_null() {
return PcStatus::NullPointer;
}
let scalar: [u8; 32] = s.try_into().unwrap();
let sk = X25519PrivateKey::from_bytes(scalar);
let pk = sk.public_key();
unsafe { core::ptr::copy_nonoverlapping(pk.as_ptr(), out, 32) };
PcStatus::Ok
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pc_x448(scalar: *const u8, peer: *const u8, out: *mut u8) -> PcStatus {
guard(|| {
let (Some(s), Some(p)) = (unsafe { slice(scalar, 56) }, unsafe { slice(peer, 56) }) else {
return PcStatus::NullPointer;
};
if out.is_null() {
return PcStatus::NullPointer;
}
let scalar: [u8; 56] = s.try_into().unwrap();
let peer: [u8; 56] = p.try_into().unwrap();
let sk = X448PrivateKey::from_bytes(scalar);
match sk.diffie_hellman(&peer) {
Ok(mut secret) => {
unsafe { core::ptr::copy_nonoverlapping(secret.as_ptr(), out, 56) };
wipe_array(&mut secret);
PcStatus::Ok
}
Err(_) => PcStatus::Verification,
}
})
}
#[unsafe(no_mangle)]
pub unsafe extern "C" fn pc_x448_public(scalar: *const u8, out: *mut u8) -> PcStatus {
guard(|| {
let Some(s) = (unsafe { slice(scalar, 56) }) else {
return PcStatus::NullPointer;
};
if out.is_null() {
return PcStatus::NullPointer;
}
let scalar: [u8; 56] = s.try_into().unwrap();
let sk = X448PrivateKey::from_bytes(scalar);
let pk = sk.public_key();
unsafe { core::ptr::copy_nonoverlapping(pk.as_ptr(), out, 56) };
PcStatus::Ok
})
}