Skip to content

Commit e8ce10e

Browse files
tarcierinewpavlov
authored andcommitted
aead: Add Payload type (#48)
1 parent 64bdf2b commit e8ce10e

File tree

1 file changed

+72
-23
lines changed

1 file changed

+72
-23
lines changed

aead/src/lib.rs

Lines changed: 72 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ extern crate alloc;
77
pub use generic_array;
88

99
use alloc::vec::Vec;
10-
use generic_array::{GenericArray, ArrayLength, typenum::Unsigned};
10+
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
1111

1212
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
1313
pub struct Error;
@@ -33,22 +33,46 @@ pub trait Aead {
3333
/// ciphertext vs. a plaintext.
3434
type CiphertextOverhead: ArrayLength<u8> + Unsigned;
3535

36-
/// Encrypt the given plaintext slice, and return the resulting ciphertext
37-
/// as a vector of bytes.
38-
fn encrypt(
36+
/// Encrypt the given plaintext payload, and return the resulting
37+
/// ciphertext as a vector of bytes.
38+
///
39+
/// The `Payload` type can be used to provide Additional Associated Data
40+
/// (AAD) along with the message: this is an optional bytestring which is
41+
/// not encrypted, but *is* authenticated along with the message. Failure
42+
/// to pass the same AAD that was used during encryption will cause
43+
/// decryption to fail, which is useful if you would like to "bind" the
44+
/// ciphertext to some other identifier, like a digital signature key
45+
/// or other identifier.
46+
///
47+
/// If you don't care about AAD and just want to encrypt a plaintext
48+
/// message, `&[u8]` will automatically be coerced into a `Payload`:
49+
///
50+
/// ```nobuild
51+
/// let plaintext = b"Top secret message, handle with care";
52+
/// let ciphertext = cipher.encrypt(nonce, plaintext);
53+
/// ```
54+
fn encrypt<'msg, 'aad>(
3955
&mut self,
40-
additional_data: &[u8],
4156
nonce: &GenericArray<u8, Self::NonceSize>,
42-
plaintext: &[u8]
57+
plaintext: impl Into<Payload<'msg, 'aad>>,
4358
) -> Result<Vec<u8>, Error>;
4459

4560
/// Decrypt the given ciphertext slice, and return the resulting plaintext
4661
/// as a vector of bytes.
47-
fn decrypt(
62+
///
63+
/// See notes on `Aead::encrypt()` about allowable message payloads and
64+
/// Associated Additional Data (AAD).
65+
///
66+
/// If you have no AAD, you can call this as follows:
67+
///
68+
/// ```nobuild
69+
/// let ciphertext = b"...";
70+
/// let plaintext = cipher.decrypt(nonce, ciphertext)?;
71+
/// ```
72+
fn decrypt<'msg, 'aad>(
4873
&mut self,
49-
additional_data: &[u8],
5074
nonce: &GenericArray<u8, Self::NonceSize>,
51-
ciphertext: &[u8]
75+
ciphertext: impl Into<Payload<'msg, 'aad>>,
5276
) -> Result<Vec<u8>, Error>;
5377
}
5478

@@ -65,20 +89,24 @@ pub trait StatelessAead {
6589

6690
/// Encrypt the given plaintext slice, and return the resulting ciphertext
6791
/// as a vector of bytes.
68-
fn encrypt(
92+
///
93+
/// See notes on `Aead::encrypt()` about allowable message payloads and
94+
/// Associated Additional Data (AAD).
95+
fn encrypt<'msg, 'aad>(
6996
&self,
70-
additional_data: &[u8],
7197
nonce: &GenericArray<u8, Self::NonceSize>,
72-
plaintext: &[u8]
98+
plaintext: impl Into<Payload<'msg, 'aad>>,
7399
) -> Result<Vec<u8>, Error>;
74100

75101
/// Decrypt the given ciphertext slice, and return the resulting plaintext
76102
/// as a vector of bytes.
77-
fn decrypt(
103+
///
104+
/// See notes on `Aead::encrypt()` and `Aead::decrypt()` about allowable
105+
/// message payloads and Associated Additional Data (AAD).
106+
fn decrypt<'msg, 'aad>(
78107
&self,
79-
additional_data: &[u8],
80108
nonce: &GenericArray<u8, Self::NonceSize>,
81-
ciphertext: &[u8]
109+
ciphertext: impl Into<Payload<'msg, 'aad>>,
82110
) -> Result<Vec<u8>, Error>;
83111
}
84112

@@ -91,23 +119,44 @@ impl<Algo: StatelessAead> Aead for Algo {
91119

92120
/// Encrypt the given plaintext slice, and return the resulting ciphertext
93121
/// as a vector of bytes.
94-
fn encrypt(
122+
fn encrypt<'msg, 'aad>(
95123
&mut self,
96-
additional_data: &[u8],
97124
nonce: &GenericArray<u8, Self::NonceSize>,
98-
plaintext: &[u8]
125+
plaintext: impl Into<Payload<'msg, 'aad>>,
99126
) -> Result<Vec<u8>, Error> {
100-
<Self as StatelessAead>::encrypt(self, additional_data, nonce, plaintext)
127+
<Self as StatelessAead>::encrypt(self, nonce, plaintext)
101128
}
102129

103130
/// Decrypt the given ciphertext slice, and return the resulting plaintext
104131
/// as a vector of bytes.
105-
fn decrypt(
132+
fn decrypt<'msg, 'aad>(
106133
&mut self,
107-
additional_data: &[u8],
108134
nonce: &GenericArray<u8, Self::NonceSize>,
109-
ciphertext: &[u8]
135+
ciphertext: impl Into<Payload<'msg, 'aad>>,
110136
) -> Result<Vec<u8>, Error> {
111-
<Self as StatelessAead>::decrypt(self, additional_data, nonce, ciphertext)
137+
<Self as StatelessAead>::decrypt(self, nonce, ciphertext)
138+
}
139+
}
140+
141+
/// AEAD payloads are a combination of a message (plaintext or ciphertext)
142+
/// and "additional associated data" (AAD) to be authenticated (in cleartext)
143+
/// along with the message.
144+
///
145+
/// If you don't care about AAD, you can pass a `&[u8]` as the payload to
146+
/// `encrypt`/`decrypt` and it will automatically be coerced to this type.
147+
pub struct Payload<'msg, 'aad> {
148+
/// Message to be encrypted/decrypted
149+
pub msg: &'msg [u8],
150+
151+
/// Optional "additional associated data" to authenticate along with
152+
/// this message. If AAD is provided at the time the message is encrypted,
153+
/// the same AAD *MUST* be provided at the time the message is decrypted,
154+
/// or decryption will fail.
155+
pub aad: &'aad [u8],
156+
}
157+
158+
impl<'msg, 'aad> From<&'msg [u8]> for Payload<'msg, 'aad> {
159+
fn from(msg: &'msg [u8]) -> Self {
160+
Self { msg, aad: b"" }
112161
}
113162
}

0 commit comments

Comments
 (0)