Skip to content

Commit 8e15625

Browse files
committed
refactor: move SSL AEAD implementation to ssl.rs
1 parent 2ecf788 commit 8e15625

6 files changed

Lines changed: 371 additions & 381 deletions

File tree

src/aead.rs

Lines changed: 15 additions & 262 deletions
Original file line numberDiff line numberDiff line change
@@ -4,270 +4,18 @@
44
// option. This file may not be copied, modified, or distributed
55
// except according to those terms.
66

7-
use std::{
8-
fmt,
9-
os::raw::{c_char, c_int, c_uint},
10-
ptr::null_mut,
11-
};
7+
use std::{os::raw::c_int, ptr::null_mut};
128

139
use crate::{
14-
constants::{Cipher, Version},
15-
err::{sec::SEC_ERROR_BAD_DATA, Error, Res},
16-
experimental_api,
10+
err::{Error, Res},
1711
p11::{
18-
self, Context, PK11SymKey, PK11_AEADOp, PK11_CreateContextBySymKey, CKA_DECRYPT,
19-
CKA_ENCRYPT, CKA_NSS_MESSAGE, CKG_GENERATE_COUNTER_XOR, CKG_NO_GENERATE, CKM_AES_GCM,
12+
self, Context, PK11_AEADOp, PK11_CreateContextBySymKey, CKA_DECRYPT, CKA_ENCRYPT,
13+
CKA_NSS_MESSAGE, CKG_GENERATE_COUNTER_XOR, CKG_NO_GENERATE, CKM_AES_GCM,
2014
CKM_CHACHA20_POLY1305, CK_ATTRIBUTE_TYPE, CK_GENERATOR_FUNCTION, CK_MECHANISM_TYPE,
2115
},
22-
prtypes::{PRUint16, PRUint64, PRUint8},
23-
scoped_ptr, secstatus_to_res,
24-
ssl::SSLAeadContext,
25-
SECItemBorrowed, SymKey,
16+
secstatus_to_res, SECItemBorrowed, SymKey,
2617
};
2718

28-
/// Trait for AEAD (Authenticated Encryption with Associated Data) operations.
29-
///
30-
/// This trait provides a common interface for both real and null AEAD implementations,
31-
/// eliminating code duplication and allowing for consistent usage patterns.
32-
pub trait AeadTrait {
33-
/// Create a new AEAD instance.
34-
///
35-
/// # Errors
36-
///
37-
/// Returns `Error` when the underlying crypto operations fail.
38-
fn new(version: Version, cipher: Cipher, secret: &SymKey, prefix: &str) -> Res<Self>
39-
where
40-
Self: Sized;
41-
42-
/// Get the expansion size (authentication tag length) for this AEAD.
43-
fn expansion(&self) -> usize;
44-
45-
/// Encrypt plaintext with associated data.
46-
///
47-
/// # Errors
48-
///
49-
/// Returns `Error` when encryption fails.
50-
fn encrypt<'a>(
51-
&self,
52-
count: u64,
53-
aad: &[u8],
54-
input: &[u8],
55-
output: &'a mut [u8],
56-
) -> Res<&'a [u8]>;
57-
58-
/// Encrypt plaintext in place with associated data.
59-
///
60-
/// # Errors
61-
///
62-
/// Returns `Error` when encryption fails.
63-
fn encrypt_in_place<'a>(&self, count: u64, aad: &[u8], data: &'a mut [u8])
64-
-> Res<&'a mut [u8]>;
65-
66-
/// Decrypt ciphertext with associated data.
67-
///
68-
/// # Errors
69-
///
70-
/// Returns `Error` when decryption or authentication fails.
71-
fn decrypt<'a>(
72-
&self,
73-
count: u64,
74-
aad: &[u8],
75-
input: &[u8],
76-
output: &'a mut [u8],
77-
) -> Res<&'a [u8]>;
78-
79-
/// Decrypt ciphertext in place with associated data.
80-
///
81-
/// # Errors
82-
///
83-
/// Returns `Error` when decryption or authentication fails.
84-
fn decrypt_in_place<'a>(&self, count: u64, aad: &[u8], data: &'a mut [u8])
85-
-> Res<&'a mut [u8]>;
86-
}
87-
88-
experimental_api!(SSL_MakeAead(
89-
version: PRUint16,
90-
cipher: PRUint16,
91-
secret: *mut PK11SymKey,
92-
label_prefix: *const c_char,
93-
label_prefix_len: c_uint,
94-
ctx: *mut *mut SSLAeadContext,
95-
));
96-
experimental_api!(SSL_AeadEncrypt(
97-
ctx: *const SSLAeadContext,
98-
counter: PRUint64,
99-
aad: *const PRUint8,
100-
aad_len: c_uint,
101-
input: *const PRUint8,
102-
input_len: c_uint,
103-
output: *const PRUint8,
104-
output_len: *mut c_uint,
105-
max_output: c_uint
106-
));
107-
experimental_api!(SSL_AeadDecrypt(
108-
ctx: *const SSLAeadContext,
109-
counter: PRUint64,
110-
aad: *const PRUint8,
111-
aad_len: c_uint,
112-
input: *const PRUint8,
113-
input_len: c_uint,
114-
output: *const PRUint8,
115-
output_len: *mut c_uint,
116-
max_output: c_uint
117-
));
118-
experimental_api!(SSL_DestroyAead(ctx: *mut SSLAeadContext));
119-
scoped_ptr!(AeadContext, SSLAeadContext, SSL_DestroyAead);
120-
121-
pub struct RealAead {
122-
ctx: AeadContext,
123-
}
124-
125-
impl RealAead {
126-
unsafe fn from_raw(
127-
version: Version,
128-
cipher: Cipher,
129-
secret: *mut PK11SymKey,
130-
prefix: &str,
131-
) -> Res<Self> {
132-
let p = prefix.as_bytes();
133-
let mut ctx: *mut SSLAeadContext = null_mut();
134-
SSL_MakeAead(
135-
version,
136-
cipher,
137-
secret,
138-
p.as_ptr().cast(),
139-
c_uint::try_from(p.len())?,
140-
&mut ctx,
141-
)?;
142-
Ok(Self {
143-
ctx: AeadContext::from_ptr(ctx)?,
144-
})
145-
}
146-
}
147-
148-
impl AeadTrait for RealAead {
149-
fn new(version: Version, cipher: Cipher, secret: &SymKey, prefix: &str) -> Res<Self> {
150-
let s: *mut PK11SymKey = **secret;
151-
unsafe { Self::from_raw(version, cipher, s, prefix) }
152-
}
153-
154-
fn expansion(&self) -> usize {
155-
16
156-
}
157-
158-
fn encrypt<'a>(
159-
&self,
160-
count: u64,
161-
aad: &[u8],
162-
input: &[u8],
163-
output: &'a mut [u8],
164-
) -> Res<&'a [u8]> {
165-
let mut l: c_uint = 0;
166-
unsafe {
167-
SSL_AeadEncrypt(
168-
*self.ctx,
169-
count,
170-
aad.as_ptr(),
171-
c_uint::try_from(aad.len())?,
172-
input.as_ptr(),
173-
c_uint::try_from(input.len())?,
174-
output.as_mut_ptr(),
175-
&mut l,
176-
c_uint::try_from(output.len())?,
177-
)
178-
}?;
179-
Ok(&output[..l.try_into()?])
180-
}
181-
182-
fn encrypt_in_place<'a>(
183-
&self,
184-
count: u64,
185-
aad: &[u8],
186-
data: &'a mut [u8],
187-
) -> Res<&'a mut [u8]> {
188-
if data.len() < self.expansion() {
189-
return Err(Error::from(SEC_ERROR_BAD_DATA));
190-
}
191-
192-
let mut l: c_uint = 0;
193-
unsafe {
194-
SSL_AeadEncrypt(
195-
*self.ctx,
196-
count,
197-
aad.as_ptr(),
198-
c_uint::try_from(aad.len())?,
199-
data.as_ptr(),
200-
c_uint::try_from(data.len() - self.expansion())?,
201-
data.as_mut_ptr(),
202-
&mut l,
203-
c_uint::try_from(data.len())?,
204-
)
205-
}?;
206-
debug_assert_eq!(usize::try_from(l)?, data.len());
207-
Ok(data)
208-
}
209-
210-
fn decrypt<'a>(
211-
&self,
212-
count: u64,
213-
aad: &[u8],
214-
input: &[u8],
215-
output: &'a mut [u8],
216-
) -> Res<&'a [u8]> {
217-
let mut l: c_uint = 0;
218-
unsafe {
219-
// Note that NSS insists upon having extra space available for decryption, so
220-
// the buffer for `output` should be the same length as `input`, even though
221-
// the final result will be shorter.
222-
SSL_AeadDecrypt(
223-
*self.ctx,
224-
count,
225-
aad.as_ptr(),
226-
c_uint::try_from(aad.len())?,
227-
input.as_ptr(),
228-
c_uint::try_from(input.len())?,
229-
output.as_mut_ptr(),
230-
&mut l,
231-
c_uint::try_from(output.len())?,
232-
)
233-
}?;
234-
Ok(&output[..l.try_into()?])
235-
}
236-
237-
fn decrypt_in_place<'a>(
238-
&self,
239-
count: u64,
240-
aad: &[u8],
241-
data: &'a mut [u8],
242-
) -> Res<&'a mut [u8]> {
243-
let mut l: c_uint = 0;
244-
unsafe {
245-
// Note that NSS insists upon having extra space available for decryption, so
246-
// the buffer for `output` should be the same length as `input`, even though
247-
// the final result will be shorter.
248-
SSL_AeadDecrypt(
249-
*self.ctx,
250-
count,
251-
aad.as_ptr(),
252-
c_uint::try_from(aad.len())?,
253-
data.as_ptr(),
254-
c_uint::try_from(data.len())?,
255-
data.as_mut_ptr(),
256-
&mut l,
257-
c_uint::try_from(data.len())?,
258-
)
259-
}?;
260-
debug_assert_eq!(usize::try_from(l)?, data.len() - self.expansion());
261-
Ok(&mut data[..l.try_into()?])
262-
}
263-
}
264-
265-
impl fmt::Debug for RealAead {
266-
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
267-
write!(f, "[AEAD Context]")
268-
}
269-
}
270-
27119
/// All the nonces are the same length. Exploit that.
27220
pub const NONCE_LEN: usize = 12;
27321

@@ -370,7 +118,7 @@ impl Aead {
370118
})
371119
}
372120

373-
pub fn seal(&mut self, aad: &[u8], pt: &[u8]) -> Result<Vec<u8>, Error> {
121+
pub fn encrypt(&mut self, aad: &[u8], pt: &[u8]) -> Result<Vec<u8>, Error> {
374122
crate::init()?;
375123

376124
assert_eq!(self.mode, Mode::Encrypt);
@@ -406,7 +154,12 @@ impl Aead {
406154
Ok(ct)
407155
}
408156

409-
pub fn open(&mut self, aad: &[u8], seq: SequenceNumber, ct: &[u8]) -> Result<Vec<u8>, Error> {
157+
pub fn decrypt(
158+
&mut self,
159+
aad: &[u8],
160+
seq: SequenceNumber,
161+
ct: &[u8],
162+
) -> Result<Vec<u8>, Error> {
410163
crate::init()?;
411164

412165
assert_eq!(self.mode, Mode::Decrypt);
@@ -462,11 +215,11 @@ mod test {
462215
let k = Aead::import_key(algorithm, key).unwrap();
463216

464217
let mut enc = Aead::new(Mode::Encrypt, algorithm, &k, *nonce).unwrap();
465-
let ciphertext = enc.seal(aad, pt).unwrap();
218+
let ciphertext = enc.encrypt(aad, pt).unwrap();
466219
assert_eq!(&ciphertext[..], ct);
467220

468221
let mut dec = Aead::new(Mode::Decrypt, algorithm, &k, *nonce).unwrap();
469-
let plaintext = dec.open(aad, 0, ct).unwrap();
222+
let plaintext = dec.decrypt(aad, 0, ct).unwrap();
470223
assert_eq!(&plaintext[..], pt);
471224
}
472225

@@ -481,7 +234,7 @@ mod test {
481234
) {
482235
let k = Aead::import_key(algorithm, key).unwrap();
483236
let mut dec = Aead::new(Mode::Decrypt, algorithm, &k, *nonce).unwrap();
484-
let plaintext = dec.open(aad, seq, ct).unwrap();
237+
let plaintext = dec.decrypt(aad, seq, ct).unwrap();
485238
assert_eq!(&plaintext[..], pt);
486239
}
487240

0 commit comments

Comments
 (0)