redoubt_aead_aegis_x86/
lib.rs1#![no_std]
12#![warn(missing_docs)]
13
14#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
15extern crate alloc;
16
17#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
18use alloc::vec;
19#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
20use alloc::vec::Vec;
21
22#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
23use redoubt_aead_core::{AeadApi, AeadError, EntropyError};
24
25pub const KEY_SIZE: usize = 16;
27pub const NONCE_SIZE: usize = 16;
29pub const TAG_SIZE: usize = 16;
31
32#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
33unsafe extern "C" {
34 fn aegis128l_encrypt(
35 key: *const [u8; 16],
36 nonce: *const [u8; 16],
37 aad: *const u8,
38 aad_len: usize,
39 plaintext: *mut u8,
40 plaintext_len: usize,
41 tag: *mut [u8; 16],
42 );
43
44 fn aegis128l_decrypt(
45 key: *const [u8; 16],
46 nonce: *const [u8; 16],
47 aad: *const u8,
48 aad_len: usize,
49 ciphertext: *mut u8,
50 ciphertext_len: usize,
51 expected_tag: *const [u8; 16],
52 computed_tag: *mut [u8; 16],
53 );
54}
55
56pub struct Aegis128LX86Backend;
58
59#[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
60impl AeadApi for Aegis128LX86Backend {
61 fn api_encrypt(
62 &mut self,
63 key: &[u8],
64 nonce: &[u8],
65 aad: &[u8],
66 data: &mut [u8],
67 tag: &mut [u8],
68 ) -> Result<(), AeadError> {
69 let key: &[u8; KEY_SIZE] = key.try_into().map_err(|_| AeadError::InvalidKeySize)?;
70 let nonce: &[u8; NONCE_SIZE] = nonce.try_into().map_err(|_| AeadError::InvalidNonceSize)?;
71 let tag: &mut [u8; TAG_SIZE] = tag.try_into().map_err(|_| AeadError::InvalidTagSize)?;
72
73 unsafe {
74 aegis128l_encrypt(
75 key,
76 nonce,
77 aad.as_ptr(),
78 aad.len(),
79 data.as_mut_ptr(),
80 data.len(),
81 tag,
82 );
83 }
84
85 Ok(())
86 }
87
88 fn api_decrypt(
89 &mut self,
90 key: &[u8],
91 nonce: &[u8],
92 aad: &[u8],
93 data: &mut [u8],
94 tag: &[u8],
95 ) -> Result<(), AeadError> {
96 let key: &[u8; KEY_SIZE] = key.try_into().map_err(|_| AeadError::InvalidKeySize)?;
97 let nonce: &[u8; NONCE_SIZE] = nonce.try_into().map_err(|_| AeadError::InvalidNonceSize)?;
98 let tag: &[u8; TAG_SIZE] = tag.try_into().map_err(|_| AeadError::InvalidTagSize)?;
99
100 let mut computed_tag = [0u8; TAG_SIZE];
101
102 unsafe {
103 aegis128l_decrypt(
104 key,
105 nonce,
106 aad.as_ptr(),
107 aad.len(),
108 data.as_mut_ptr(),
109 data.len(),
110 tag,
111 &mut computed_tag,
112 );
113 }
114
115 if redoubt_util::constant_time_eq(&computed_tag, tag) {
116 Ok(())
117 } else {
118 Err(AeadError::AuthenticationFailed)
119 }
120 }
121
122 fn api_generate_nonce(&mut self) -> Result<Vec<u8>, EntropyError> {
123 let mut nonce = vec![0u8; NONCE_SIZE];
124 redoubt_rand::fill_with_random_bytes(&mut nonce)?;
125
126 Ok(nonce)
127 }
128
129 fn api_key_size(&self) -> usize {
130 KEY_SIZE
131 }
132
133 fn api_nonce_size(&self) -> usize {
134 NONCE_SIZE
135 }
136
137 fn api_tag_size(&self) -> usize {
138 TAG_SIZE
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
145 use super::Aegis128LX86Backend;
146
147 #[test]
148 fn instrumentation() {
149 let _ = super::Aegis128LX86Backend;
150 }
151
152 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
153 #[test]
154 fn test_aegis128l_wycheproof() {
155 redoubt_aead_aegis_wycheproof::run_aegis128l_wycheproof_tests(&mut Aegis128LX86Backend);
156 }
157
158 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
159 #[test]
160 fn test_aegis128l_roundtrip() {
161 redoubt_aead_aegis_wycheproof::run_aegis128l_roundtrip_tests(&mut Aegis128LX86Backend);
162 }
163
164 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
165 #[test]
166 fn test_aegis128l_flipped_tag() {
167 redoubt_aead_aegis_wycheproof::run_aegis128l_flipped_tag_tests(&mut Aegis128LX86Backend);
168 }
169
170 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
171 #[test]
172 fn test_aegis128l_invalid_size_encrypt() {
173 redoubt_aead_aegis_wycheproof::run_aegis128l_invalid_size_encrypt_tests(
174 &mut Aegis128LX86Backend,
175 );
176 }
177
178 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
179 #[test]
180 fn test_aegis128l_invalid_size_decrypt() {
181 redoubt_aead_aegis_wycheproof::run_aegis128l_invalid_size_decrypt_tests(
182 &mut Aegis128LX86Backend,
183 );
184 }
185
186 #[cfg(all(target_arch = "x86_64", not(target_os = "windows")))]
187 #[test]
188 fn test_aegis128l_generate_nonce() {
189 redoubt_aead_aegis_wycheproof::run_aegis128l_generate_nonce_test(&mut Aegis128LX86Backend);
190 }
191}