/// All the nonces are the same length. Exploit that. pubconst NONCE_LEN: usize = 12; /// The portion of the nonce that is a counter. const COUNTER_LEN: usize = mem::size_of::<SequenceNumber>(); /// The NSS API insists on us identifying the tag separately, which is awful. /// All of the AEAD functions here have a tag of this length, so use a fixed offset. const TAG_LEN: usize = 16;
pubtype SequenceNumber = u64;
/// All the lengths used by `PK11_AEADOp` are signed. This converts to that. fn c_int_len<T>(l: T) -> c_int where
T: TryInto<c_int>,
T::Error: std::error::Error,
{
l.try_into().unwrap()
}
/// This is an AEAD instance that uses the pubstruct Aead {
mode: Mode, #[allow(dead_code)]
algorithm: AeadId,
ctx: Context,
nonce_base: [u8; NONCE_LEN],
decrypt_counter: SequenceNumber,
}
impl Decrypt for Aead { fn open(&mutself, aad: &[u8], ct: &[u8]) -> Res<Vec<u8>> {
assert_eq!(self.mode, Mode::Decrypt); // Note: NSS doesn't do any nonce generation for decryption, which is CRAZY. let counter = self.decrypt_counter; self.decrypt_counter += 1; self.open_seq(aad, counter, ct)
}
fn alg(&self) -> AeadId { self.algorithm
}
}
impl Encrypt for Aead { fn seal(&mutself, aad: &[u8], pt: &[u8]) -> Res<Vec<u8>> {
assert_eq!(self.mode, Mode::Encrypt); // A copy for the nonce generator to write into. But we don't use the value. letmut nonce = self.nonce_base;
// Ciphertext with enough space for the tag. // Even though we give the operation a separate buffer for the tag, // reserve the capacity on allocation. letmut ct = vec![0; pt.len() + TAG_LEN]; letmut ct_len: c_int = 0; letmut tag = vec![0; TAG_LEN];
secstatus_to_res(unsafe {
PK11_AEADOp( self.ctx.ptr(),
CK_GENERATOR_FUNCTION::from(CKG_GENERATE_COUNTER_XOR),
c_int_len(NONCE_LEN - COUNTER_LEN), // Fixed portion of the nonce.
nonce.as_mut_ptr(),
c_int_len(nonce.len()),
aad.as_ptr(),
c_int_len(aad.len()),
ct.as_mut_ptr(),
&raw mut ct_len,
c_int_len(ct.len()), // signed :(
tag.as_mut_ptr(),
c_int_len(tag.len()),
pt.as_ptr(),
c_int_len(pt.len()),
)
})?;
ct.truncate(usize::try_from(ct_len).unwrap());
debug_assert_eq!(ct.len(), pt.len());
ct.append(&mut tag);
Ok(ct)
}
fn alg(&self) -> AeadId { self.algorithm
}
}
#[cfg(test)] mod test { usesuper::{ super::{super::hpke::Aead as AeadId, init},
Aead, Mode, SequenceNumber, NONCE_LEN,
}; usecrate::crypto::{Decrypt, Encrypt};
/// Check that the first invocation of encryption matches expected values. /// Also check decryption of the same. fn check0(
algorithm: AeadId,
key: &[u8],
nonce: &[u8; NONCE_LEN],
aad: &[u8],
pt: &[u8],
ct: &[u8],
) {
init(); let k = Aead::import_key(algorithm, key).unwrap();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.