-
Notifications
You must be signed in to change notification settings - Fork 155
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Requesting an example #576
Comments
Haven't cracked into this as I'm currently working on another PR rn but it would really help if you could post a dump of your specific compiler errors and warnings. I do think that more/better examples would definitely be a good thing though. |
Hey! I got it working on my end. Important parts of the code. I think my biggest confusion point was on what a Generic Array is, and how to construct it. use crypto::{
aead::{heapless::Vec, AeadCore, AeadInPlace, KeyInit},
ChaCha20Poly1305 as Poly, Key, Nonce,
};
pub struct CipherError {}
/// Generate a key; provide this as an option for the user to run, eg in the PC config.
pub fn genkey() -> Key {
let mut rng = Rng {};
Poly::generate_key(&mut rng)
}
pub struct Cipher {
/// A 256-bit key. We share this between the radios.
pub key: Key,
pub cipher: Poly,
/// The nonce is unique per message. 96-bits.
pub nonce: Nonce,
}
impl Cipher {
pub fn new(key: &Key) -> Self {
let mut rng = Rng {};
Self {
key: key.clone(),
cipher: Poly::new(&key),
nonce: Poly::generate_nonce(&mut rng),
}
}
/// Update the nonce; run this prior to sending each message. Send the nonce with the message.
pub fn update_nonce(&mut self) {
let mut rng = Rng {};
self.nonce = Poly::generate_nonce(&mut rng)
}
}
/// Data must include space for the auth. It will extend the effective message length.
pub fn encrypt(data: &mut [u8], cipher: &Cipher) -> Result<(), CipherError> {
// We must use heapless here, or else implement a trait like it for an array.
// Note: buffer needs 16-bytes overhead for auth tag
let len = data.len();
let mut buffer: Vec<u8, { RADIO_BUF_SIZE as usize }> = Vec::new();
buffer.extend_from_slice(&data[..len - AUTH_SIZE]).ok();
// "associated data is the AD in AEAD. basically its an arbitrary value what you can "mix" a MAC of
// into the AEAD's cipherext + authentication tag output. this lets you transmit the AEAD in
// plaintext but still validate it was the right one upon later decryption of the ciphertext.
// they are also used to add more context into an encryption operation for cotext binding etc
// since the wrong AD when decrypting will fail the whole operation"
let associated_data = [];
// Encrypt `buffer` in-place, replacing the plaintext contents with ciphertext
if cipher
.cipher
.encrypt_in_place(&cipher.nonce, &associated_data, &mut buffer)
.is_err()
{
return Err(CipherError {});
}
data.clone_from_slice(&buffer[..len]);
Ok(())
}
/// The decrypted data will be of the unencrypted (shorter) length. The input data must
/// not include the nonce.
pub fn decrypt(data: &mut [u8], cipher: &Cipher) -> Result<(), CipherError> {
let len = data.len(); // includes payload and auth; no nonce.
let mut buffer: Vec<u8, { RADIO_BUF_SIZE as usize }> = Vec::new();
buffer.extend_from_slice(data).ok();
let associated_data = [];
// Decrypt `buffer` in-place, replacing its ciphertext context with the original plaintext
if cipher
.cipher
.decrypt_in_place(&cipher.nonce, &associated_data, &mut buffer)
.is_err()
{
return Err(CipherError {});
}
// Write the decrypted message to the relevant (first) part of the data.
data[..len - AUTH_SIZE].clone_from_slice(&buffer[..len - AUTH_SIZE]);
// Write 0s to the part of the buffer taken up by the auth.
data[len - AUTH_SIZE..len].clone_from_slice(&[0; AUTH_SIZE]);
Ok(())
} |
Yeah that's actually a major criticism of mine lol. See the issue below yours in the issues list. I'm working on a PR that adds documentation that spells out this connection more explicitly. |
Hi! Does anyone have an example of basic operation, that includes a function or struct field containing each relevant type (key, poly, nonce)? Thank you!
Here is my non-compiling attempt:
Cargo.toml:
Program:
The text was updated successfully, but these errors were encountered: