use crate::{
decrypt0_into, decrypt_into, encrypt0_detached_into, encrypt0_into, encrypt0_to_vec,
encrypt_detached_into, encrypt_into, encrypt_to_vec, mac0_into, mac0_to_vec, mac_into,
mac_to_vec, sign1_into, sign1_to_vec, sign_into, sign_to_vec, verify1, verify_mac, verify_mac0,
verify_sign, Algorithm, CoseKey, DecryptOutput, Encrypt0DetachedOutput, Error, MacVerifyOutput,
PayloadMode, Recipient, Result, Signature, VerifyOutput,
};
use alloc::{vec, vec::Vec};
use core::ptr::NonNull;
const DEFAULT_SCRATCH: usize = 4096;
pub struct Sign1Builder<'a> {
key: Option<&'a CoseKey>,
algorithm: Option<Algorithm>,
kid: Option<&'a [u8]>,
payload: Option<PayloadMode<'a>>,
external_aad: &'a [u8],
scratch: Vec<u8>,
rng: Option<NonNull<crate::raw::WC_RNG>>,
}
impl<'a> Sign1Builder<'a> {
pub fn new() -> Self {
Self {
key: None,
algorithm: None,
kid: None,
payload: None,
external_aad: &[],
scratch: vec![0; DEFAULT_SCRATCH],
rng: None,
}
}
pub fn key(mut self, key: &'a CoseKey) -> Self {
self.key = Some(key);
self
}
pub fn algorithm(mut self, algorithm: Algorithm) -> Self {
self.algorithm = Some(algorithm);
self
}
pub fn kid(mut self, kid: &'a [u8]) -> Self {
self.kid = Some(kid);
self
}
pub fn payload(mut self, payload: PayloadMode<'a>) -> Self {
self.payload = Some(payload);
self
}
pub fn external_aad(mut self, external_aad: &'a [u8]) -> Self {
self.external_aad = external_aad;
self
}
pub fn scratch_len(mut self, len: usize) -> Self {
self.scratch.resize(len, 0);
self
}
pub fn rng(mut self, rng: NonNull<crate::raw::WC_RNG>) -> Self {
self.rng = Some(rng);
self
}
pub fn sign_into<'out>(&mut self, out: &'out mut [u8]) -> Result<&'out [u8]> {
sign1_into(
self.key.ok_or(Error::InvalidArgument)?,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.kid,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
out,
self.rng,
)
}
pub fn sign_to_vec(&mut self) -> Result<Vec<u8>> {
sign1_to_vec(
self.key.ok_or(Error::InvalidArgument)?,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.kid,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
self.rng,
)
}
pub fn verify<'inbuf>(
&mut self,
input: &'inbuf [u8],
detached_payload: Option<&[u8]>,
) -> Result<VerifyOutput<'inbuf>> {
verify1(
self.key.ok_or(Error::InvalidArgument)?,
input,
detached_payload,
self.external_aad,
&mut self.scratch,
)
}
}
impl Default for Sign1Builder<'_> {
fn default() -> Self {
Self::new()
}
}
pub struct Encrypt0Builder<'a> {
key: Option<&'a CoseKey>,
algorithm: Option<Algorithm>,
iv: &'a [u8],
payload: Option<PayloadMode<'a>>,
external_aad: &'a [u8],
scratch: Vec<u8>,
}
impl<'a> Encrypt0Builder<'a> {
pub fn new() -> Self {
Self {
key: None,
algorithm: None,
iv: &[],
payload: None,
external_aad: &[],
scratch: vec![0; DEFAULT_SCRATCH],
}
}
pub fn key(mut self, key: &'a CoseKey) -> Self {
self.key = Some(key);
self
}
pub fn algorithm(mut self, algorithm: Algorithm) -> Self {
self.algorithm = Some(algorithm);
self
}
pub fn iv(mut self, iv: &'a [u8]) -> Self {
self.iv = iv;
self
}
pub fn payload(mut self, payload: PayloadMode<'a>) -> Self {
self.payload = Some(payload);
self
}
pub fn external_aad(mut self, external_aad: &'a [u8]) -> Self {
self.external_aad = external_aad;
self
}
pub fn scratch_len(mut self, len: usize) -> Self {
self.scratch.resize(len, 0);
self
}
pub fn encrypt_into<'out>(&mut self, out: &'out mut [u8]) -> Result<&'out [u8]> {
let payload = match self.payload.ok_or(Error::InvalidArgument)? {
PayloadMode::Attached(payload) => payload,
PayloadMode::Detached(_) => return Err(Error::InvalidArgument),
};
encrypt0_into(
self.key.ok_or(Error::InvalidArgument)?,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.iv,
payload,
self.external_aad,
&mut self.scratch,
out,
)
}
pub fn encrypt_to_vec(&mut self) -> Result<Vec<u8>> {
let payload = match self.payload.ok_or(Error::InvalidArgument)? {
PayloadMode::Attached(payload) => payload,
PayloadMode::Detached(_) => return Err(Error::InvalidArgument),
};
encrypt0_to_vec(
self.key.ok_or(Error::InvalidArgument)?,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.iv,
payload,
self.external_aad,
&mut self.scratch,
)
}
pub fn encrypt_detached_into(
&mut self,
out: &mut [u8],
detached_ciphertext: &mut [u8],
) -> Result<Encrypt0DetachedOutput> {
let payload = match self.payload.ok_or(Error::InvalidArgument)? {
PayloadMode::Detached(payload) => payload,
PayloadMode::Attached(_) => return Err(Error::InvalidArgument),
};
encrypt0_detached_into(
self.key.ok_or(Error::InvalidArgument)?,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.iv,
payload,
self.external_aad,
&mut self.scratch,
out,
detached_ciphertext,
)
}
pub fn decrypt_into(
&mut self,
input: &[u8],
detached_ciphertext: Option<&[u8]>,
plaintext: &mut [u8],
) -> Result<DecryptOutput> {
decrypt0_into(
self.key.ok_or(Error::InvalidArgument)?,
input,
detached_ciphertext,
self.external_aad,
&mut self.scratch,
plaintext,
)
}
}
impl Default for Encrypt0Builder<'_> {
fn default() -> Self {
Self::new()
}
}
pub struct Mac0Builder<'a> {
key: Option<&'a CoseKey>,
algorithm: Option<Algorithm>,
kid: Option<&'a [u8]>,
payload: Option<PayloadMode<'a>>,
external_aad: &'a [u8],
scratch: Vec<u8>,
}
impl<'a> Mac0Builder<'a> {
pub fn new() -> Self {
Self {
key: None,
algorithm: None,
kid: None,
payload: None,
external_aad: &[],
scratch: vec![0; DEFAULT_SCRATCH],
}
}
pub fn key(mut self, key: &'a CoseKey) -> Self {
self.key = Some(key);
self
}
pub fn algorithm(mut self, algorithm: Algorithm) -> Self {
self.algorithm = Some(algorithm);
self
}
pub fn kid(mut self, kid: &'a [u8]) -> Self {
self.kid = Some(kid);
self
}
pub fn payload(mut self, payload: PayloadMode<'a>) -> Self {
self.payload = Some(payload);
self
}
pub fn external_aad(mut self, external_aad: &'a [u8]) -> Self {
self.external_aad = external_aad;
self
}
pub fn scratch_len(mut self, len: usize) -> Self {
self.scratch.resize(len, 0);
self
}
pub fn mac_into<'out>(&mut self, out: &'out mut [u8]) -> Result<&'out [u8]> {
mac0_into(
self.key.ok_or(Error::InvalidArgument)?,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.kid,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
out,
)
}
pub fn mac_to_vec(&mut self) -> Result<Vec<u8>> {
mac0_to_vec(
self.key.ok_or(Error::InvalidArgument)?,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.kid,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
)
}
pub fn verify<'inbuf>(
&mut self,
input: &'inbuf [u8],
detached_payload: Option<&[u8]>,
) -> Result<MacVerifyOutput<'inbuf>> {
verify_mac0(
self.key.ok_or(Error::InvalidArgument)?,
input,
detached_payload,
self.external_aad,
&mut self.scratch,
)
}
}
impl Default for Mac0Builder<'_> {
fn default() -> Self {
Self::new()
}
}
pub struct SignBuilder<'a> {
signers: Vec<Signature<'a>>,
payload: Option<PayloadMode<'a>>,
external_aad: &'a [u8],
scratch: Vec<u8>,
rng: Option<NonNull<crate::raw::WC_RNG>>,
}
impl<'a> SignBuilder<'a> {
pub fn new() -> Self {
Self {
signers: Vec::new(),
payload: None,
external_aad: &[],
scratch: vec![0; DEFAULT_SCRATCH],
rng: None,
}
}
pub fn signer(mut self, signer: Signature<'a>) -> Self {
self.signers.push(signer);
self
}
pub fn payload(mut self, payload: PayloadMode<'a>) -> Self {
self.payload = Some(payload);
self
}
pub fn external_aad(mut self, external_aad: &'a [u8]) -> Self {
self.external_aad = external_aad;
self
}
pub fn rng(mut self, rng: NonNull<crate::raw::WC_RNG>) -> Self {
self.rng = Some(rng);
self
}
pub fn sign_into<'out>(&mut self, out: &'out mut [u8]) -> Result<&'out [u8]> {
sign_into(
&self.signers,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
out,
self.rng,
)
}
pub fn sign_to_vec(&mut self) -> Result<Vec<u8>> {
sign_to_vec(
&self.signers,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
self.rng,
)
}
pub fn verify<'inbuf>(
&mut self,
key: &CoseKey,
signer_index: usize,
input: &'inbuf [u8],
detached_payload: Option<&[u8]>,
) -> Result<VerifyOutput<'inbuf>> {
verify_sign(
key,
signer_index,
input,
detached_payload,
self.external_aad,
&mut self.scratch,
)
}
}
impl Default for SignBuilder<'_> {
fn default() -> Self {
Self::new()
}
}
pub struct EncryptBuilder<'a> {
recipients: Vec<Recipient<'a>>,
algorithm: Option<Algorithm>,
iv: &'a [u8],
payload: Option<PayloadMode<'a>>,
external_aad: &'a [u8],
scratch: Vec<u8>,
rng: Option<NonNull<crate::raw::WC_RNG>>,
}
impl<'a> EncryptBuilder<'a> {
pub fn new() -> Self {
Self {
recipients: Vec::new(),
algorithm: None,
iv: &[],
payload: None,
external_aad: &[],
scratch: vec![0; DEFAULT_SCRATCH],
rng: None,
}
}
pub fn recipient(mut self, recipient: Recipient<'a>) -> Self {
self.recipients.push(recipient);
self
}
pub fn algorithm(mut self, algorithm: Algorithm) -> Self {
self.algorithm = Some(algorithm);
self
}
pub fn iv(mut self, iv: &'a [u8]) -> Self {
self.iv = iv;
self
}
pub fn payload(mut self, payload: PayloadMode<'a>) -> Self {
self.payload = Some(payload);
self
}
pub fn external_aad(mut self, external_aad: &'a [u8]) -> Self {
self.external_aad = external_aad;
self
}
pub fn rng(mut self, rng: NonNull<crate::raw::WC_RNG>) -> Self {
self.rng = Some(rng);
self
}
pub fn encrypt_into<'out>(&mut self, out: &'out mut [u8]) -> Result<&'out [u8]> {
let payload = match self.payload.ok_or(Error::InvalidArgument)? {
PayloadMode::Attached(payload) => payload,
PayloadMode::Detached(_) => {
return encrypt_detached_into(
&self.recipients,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.iv,
match self.payload.ok_or(Error::InvalidArgument)? {
PayloadMode::Detached(payload) => payload,
PayloadMode::Attached(_) => unreachable!(),
},
self.external_aad,
&mut self.scratch,
out,
self.rng,
)
}
};
encrypt_into(
&self.recipients,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.iv,
payload,
self.external_aad,
&mut self.scratch,
out,
self.rng,
)
}
pub fn encrypt_to_vec(&mut self) -> Result<Vec<u8>> {
let payload = match self.payload.ok_or(Error::InvalidArgument)? {
PayloadMode::Attached(payload) => payload,
PayloadMode::Detached(_) => return Err(Error::InvalidArgument),
};
encrypt_to_vec(
&self.recipients,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.iv,
payload,
self.external_aad,
&mut self.scratch,
self.rng,
)
}
pub fn decrypt_into(
&mut self,
recipient: &Recipient<'_>,
recipient_index: usize,
input: &[u8],
detached_ciphertext: Option<&[u8]>,
plaintext: &mut [u8],
) -> Result<DecryptOutput> {
decrypt_into(
recipient,
recipient_index,
input,
detached_ciphertext,
self.external_aad,
&mut self.scratch,
plaintext,
)
}
}
impl Default for EncryptBuilder<'_> {
fn default() -> Self {
Self::new()
}
}
pub struct MacBuilder<'a> {
recipients: Vec<Recipient<'a>>,
algorithm: Option<Algorithm>,
payload: Option<PayloadMode<'a>>,
external_aad: &'a [u8],
scratch: Vec<u8>,
}
impl<'a> MacBuilder<'a> {
pub fn new() -> Self {
Self {
recipients: Vec::new(),
algorithm: None,
payload: None,
external_aad: &[],
scratch: vec![0; DEFAULT_SCRATCH],
}
}
pub fn recipient(mut self, recipient: Recipient<'a>) -> Self {
self.recipients.push(recipient);
self
}
pub fn algorithm(mut self, algorithm: Algorithm) -> Self {
self.algorithm = Some(algorithm);
self
}
pub fn payload(mut self, payload: PayloadMode<'a>) -> Self {
self.payload = Some(payload);
self
}
pub fn external_aad(mut self, external_aad: &'a [u8]) -> Self {
self.external_aad = external_aad;
self
}
pub fn mac_into<'out>(&mut self, out: &'out mut [u8]) -> Result<&'out [u8]> {
mac_into(
&self.recipients,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
out,
)
}
pub fn mac_to_vec(&mut self) -> Result<Vec<u8>> {
mac_to_vec(
&self.recipients,
self.algorithm.ok_or(Error::InvalidArgument)?,
self.payload.ok_or(Error::InvalidArgument)?,
self.external_aad,
&mut self.scratch,
)
}
pub fn verify<'inbuf>(
&mut self,
recipient: &Recipient<'_>,
recipient_index: usize,
input: &'inbuf [u8],
detached_payload: Option<&[u8]>,
) -> Result<MacVerifyOutput<'inbuf>> {
verify_mac(
recipient,
recipient_index,
input,
detached_payload,
self.external_aad,
&mut self.scratch,
)
}
}
impl Default for MacBuilder<'_> {
fn default() -> Self {
Self::new()
}
}