@@ -7,7 +7,7 @@ extern crate alloc;
7
7
pub use generic_array;
8
8
9
9
use alloc:: vec:: Vec ;
10
- use generic_array:: { GenericArray , ArrayLength , typenum :: Unsigned } ;
10
+ use generic_array:: { typenum :: Unsigned , ArrayLength , GenericArray } ;
11
11
12
12
#[ derive( Clone , Copy , Debug , Eq , Hash , Ord , PartialEq , PartialOrd ) ]
13
13
pub struct Error ;
@@ -33,22 +33,46 @@ pub trait Aead {
33
33
/// ciphertext vs. a plaintext.
34
34
type CiphertextOverhead : ArrayLength < u8 > + Unsigned ;
35
35
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 > (
39
55
& mut self ,
40
- additional_data : & [ u8 ] ,
41
56
nonce : & GenericArray < u8 , Self :: NonceSize > ,
42
- plaintext : & [ u8 ]
57
+ plaintext : impl Into < Payload < ' msg , ' aad > > ,
43
58
) -> Result < Vec < u8 > , Error > ;
44
59
45
60
/// Decrypt the given ciphertext slice, and return the resulting plaintext
46
61
/// 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 > (
48
73
& mut self ,
49
- additional_data : & [ u8 ] ,
50
74
nonce : & GenericArray < u8 , Self :: NonceSize > ,
51
- ciphertext : & [ u8 ]
75
+ ciphertext : impl Into < Payload < ' msg , ' aad > > ,
52
76
) -> Result < Vec < u8 > , Error > ;
53
77
}
54
78
@@ -65,20 +89,24 @@ pub trait StatelessAead {
65
89
66
90
/// Encrypt the given plaintext slice, and return the resulting ciphertext
67
91
/// 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 > (
69
96
& self ,
70
- additional_data : & [ u8 ] ,
71
97
nonce : & GenericArray < u8 , Self :: NonceSize > ,
72
- plaintext : & [ u8 ]
98
+ plaintext : impl Into < Payload < ' msg , ' aad > > ,
73
99
) -> Result < Vec < u8 > , Error > ;
74
100
75
101
/// Decrypt the given ciphertext slice, and return the resulting plaintext
76
102
/// 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 > (
78
107
& self ,
79
- additional_data : & [ u8 ] ,
80
108
nonce : & GenericArray < u8 , Self :: NonceSize > ,
81
- ciphertext : & [ u8 ]
109
+ ciphertext : impl Into < Payload < ' msg , ' aad > > ,
82
110
) -> Result < Vec < u8 > , Error > ;
83
111
}
84
112
@@ -91,23 +119,44 @@ impl<Algo: StatelessAead> Aead for Algo {
91
119
92
120
/// Encrypt the given plaintext slice, and return the resulting ciphertext
93
121
/// as a vector of bytes.
94
- fn encrypt (
122
+ fn encrypt < ' msg , ' aad > (
95
123
& mut self ,
96
- additional_data : & [ u8 ] ,
97
124
nonce : & GenericArray < u8 , Self :: NonceSize > ,
98
- plaintext : & [ u8 ]
125
+ plaintext : impl Into < Payload < ' msg , ' aad > > ,
99
126
) -> Result < Vec < u8 > , Error > {
100
- <Self as StatelessAead >:: encrypt ( self , additional_data , nonce, plaintext)
127
+ <Self as StatelessAead >:: encrypt ( self , nonce, plaintext)
101
128
}
102
129
103
130
/// Decrypt the given ciphertext slice, and return the resulting plaintext
104
131
/// as a vector of bytes.
105
- fn decrypt (
132
+ fn decrypt < ' msg , ' aad > (
106
133
& mut self ,
107
- additional_data : & [ u8 ] ,
108
134
nonce : & GenericArray < u8 , Self :: NonceSize > ,
109
- ciphertext : & [ u8 ]
135
+ ciphertext : impl Into < Payload < ' msg , ' aad > > ,
110
136
) -> 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"" }
112
161
}
113
162
}
0 commit comments