Skip to content

Commit 6cc11fb

Browse files
committed
feat(aead): add aws-lc backend for AES-GCM-SIV
1 parent 0a30895 commit 6cc11fb

1 file changed

Lines changed: 143 additions & 74 deletions

File tree

src/v1/aeadcipher/aes_gcm_siv.rs

Lines changed: 143 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,88 +1,157 @@
1-
use aes_gcm_siv::{
2-
aead::{generic_array::typenum::Unsigned, AeadCore, AeadInPlace, KeyInit, KeySizeUser},
3-
Aes128GcmSiv as CryptoAes128GcmSiv,
4-
Aes256GcmSiv as CryptoAes256GcmSiv,
5-
Key,
6-
Nonce,
7-
Tag,
8-
};
9-
10-
pub struct Aes128GcmSiv(CryptoAes128GcmSiv);
11-
12-
impl Aes128GcmSiv {
13-
pub fn new(key: &[u8]) -> Aes128GcmSiv {
14-
let key = Key::<CryptoAes128GcmSiv>::from_slice(key);
15-
Aes128GcmSiv(CryptoAes128GcmSiv::new(key))
16-
}
1+
use cfg_if::cfg_if;
172

18-
pub fn key_size() -> usize {
19-
<CryptoAes128GcmSiv as KeySizeUser>::KeySize::to_usize()
20-
}
3+
cfg_if! {
4+
if #[cfg(feature = "aws-lc")] {
5+
use aws_lc_rs::aead::{Aad, Algorithm, LessSafeKey, Nonce, UnboundKey, AES_128_GCM_SIV, AES_256_GCM_SIV};
216

22-
pub fn nonce_size() -> usize {
23-
<CryptoAes128GcmSiv as AeadCore>::NonceSize::to_usize()
24-
}
7+
struct AeadKey(LessSafeKey);
258

26-
pub fn tag_size() -> usize {
27-
<CryptoAes128GcmSiv as AeadCore>::TagSize::to_usize()
28-
}
9+
impl AeadKey {
10+
fn new(algorithm: &'static Algorithm, key: &[u8]) -> AeadKey {
11+
let unbound = UnboundKey::new(algorithm, key).expect("AEAD key");
12+
AeadKey(LessSafeKey::new(unbound))
13+
}
2914

30-
pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
31-
let nonce = Nonce::from_slice(nonce);
32-
let (plaintext, out_tag) =
33-
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
34-
let tag = self
35-
.0
36-
.encrypt_in_place_detached(nonce, &[], plaintext)
37-
.expect("AES_128_GCM_SIV encrypt");
38-
out_tag.copy_from_slice(tag.as_slice())
39-
}
15+
fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
16+
let nonce = Nonce::try_assume_unique_for_key(nonce).expect("AEAD nonce");
17+
let tag_len = self.0.algorithm().tag_len();
18+
let (plaintext, out_tag) =
19+
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - tag_len);
20+
let tag = self
21+
.0
22+
.seal_in_place_separate_tag(nonce, Aad::empty(), plaintext)
23+
.expect("AEAD encrypt");
24+
out_tag.copy_from_slice(tag.as_ref());
25+
}
4026

41-
pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
42-
let nonce = Nonce::from_slice(nonce);
43-
let (ciphertext, in_tag) =
44-
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
45-
let in_tag = Tag::from_slice(in_tag);
46-
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
47-
}
48-
}
27+
fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
28+
let nonce = Nonce::try_assume_unique_for_key(nonce).expect("AEAD nonce");
29+
self.0.open_in_place(nonce, Aad::empty(), ciphertext_in_plaintext_out).is_ok()
30+
}
31+
}
4932

50-
pub struct Aes256GcmSiv(CryptoAes256GcmSiv);
33+
macro_rules! aead_gcm_siv_cipher {
34+
($name:ident, $algorithm:ident) => {
35+
pub struct $name(AeadKey);
5136

52-
impl Aes256GcmSiv {
53-
pub fn new(key: &[u8]) -> Aes256GcmSiv {
54-
let key = Key::<CryptoAes256GcmSiv>::from_slice(key);
55-
Aes256GcmSiv(CryptoAes256GcmSiv::new(key))
56-
}
37+
impl $name {
38+
pub fn new(key: &[u8]) -> $name {
39+
$name(AeadKey::new(&$algorithm, key))
40+
}
5741

58-
pub fn key_size() -> usize {
59-
<CryptoAes256GcmSiv as KeySizeUser>::KeySize::to_usize()
60-
}
42+
pub fn key_size() -> usize {
43+
$algorithm.key_len()
44+
}
6145

62-
pub fn nonce_size() -> usize {
63-
<CryptoAes256GcmSiv as AeadCore>::NonceSize::to_usize()
64-
}
46+
pub fn nonce_size() -> usize {
47+
$algorithm.nonce_len()
48+
}
6549

66-
pub fn tag_size() -> usize {
67-
<CryptoAes256GcmSiv as AeadCore>::TagSize::to_usize()
68-
}
50+
pub fn tag_size() -> usize {
51+
$algorithm.tag_len()
52+
}
6953

70-
pub fn encrypt(&mut self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
71-
let nonce = Nonce::from_slice(nonce);
72-
let (plaintext, out_tag) =
73-
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
74-
let tag = self
75-
.0
76-
.encrypt_in_place_detached(nonce, &[], plaintext)
77-
.expect("AES_256_GCM_SIV encrypt");
78-
out_tag.copy_from_slice(tag.as_slice())
79-
}
54+
pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
55+
self.0.encrypt(nonce, plaintext_in_ciphertext_out)
56+
}
57+
58+
pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
59+
self.0.decrypt(nonce, ciphertext_in_plaintext_out)
60+
}
61+
}
62+
};
63+
}
64+
65+
aead_gcm_siv_cipher!(Aes128GcmSiv, AES_128_GCM_SIV);
66+
aead_gcm_siv_cipher!(Aes256GcmSiv, AES_256_GCM_SIV);
67+
} else {
68+
use aes_gcm_siv::{
69+
aead::{generic_array::typenum::Unsigned, AeadCore, AeadInPlace, KeyInit, KeySizeUser},
70+
Aes128GcmSiv as CryptoAes128GcmSiv,
71+
Aes256GcmSiv as CryptoAes256GcmSiv,
72+
Key,
73+
Nonce,
74+
Tag,
75+
};
76+
77+
pub struct Aes128GcmSiv(CryptoAes128GcmSiv);
78+
79+
impl Aes128GcmSiv {
80+
pub fn new(key: &[u8]) -> Aes128GcmSiv {
81+
let key = Key::<CryptoAes128GcmSiv>::from_slice(key);
82+
Aes128GcmSiv(CryptoAes128GcmSiv::new(key))
83+
}
84+
85+
pub fn key_size() -> usize {
86+
<CryptoAes128GcmSiv as KeySizeUser>::KeySize::to_usize()
87+
}
88+
89+
pub fn nonce_size() -> usize {
90+
<CryptoAes128GcmSiv as AeadCore>::NonceSize::to_usize()
91+
}
92+
93+
pub fn tag_size() -> usize {
94+
<CryptoAes128GcmSiv as AeadCore>::TagSize::to_usize()
95+
}
96+
97+
pub fn encrypt(&self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
98+
let nonce = Nonce::from_slice(nonce);
99+
let (plaintext, out_tag) =
100+
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
101+
let tag = self
102+
.0
103+
.encrypt_in_place_detached(nonce, &[], plaintext)
104+
.expect("AES_128_GCM_SIV encrypt");
105+
out_tag.copy_from_slice(tag.as_slice())
106+
}
107+
108+
pub fn decrypt(&self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
109+
let nonce = Nonce::from_slice(nonce);
110+
let (ciphertext, in_tag) =
111+
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
112+
let in_tag = Tag::from_slice(in_tag);
113+
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
114+
}
115+
}
116+
117+
pub struct Aes256GcmSiv(CryptoAes256GcmSiv);
118+
119+
impl Aes256GcmSiv {
120+
pub fn new(key: &[u8]) -> Aes256GcmSiv {
121+
let key = Key::<CryptoAes256GcmSiv>::from_slice(key);
122+
Aes256GcmSiv(CryptoAes256GcmSiv::new(key))
123+
}
124+
125+
pub fn key_size() -> usize {
126+
<CryptoAes256GcmSiv as KeySizeUser>::KeySize::to_usize()
127+
}
128+
129+
pub fn nonce_size() -> usize {
130+
<CryptoAes256GcmSiv as AeadCore>::NonceSize::to_usize()
131+
}
132+
133+
pub fn tag_size() -> usize {
134+
<CryptoAes256GcmSiv as AeadCore>::TagSize::to_usize()
135+
}
136+
137+
pub fn encrypt(&mut self, nonce: &[u8], plaintext_in_ciphertext_out: &mut [u8]) {
138+
let nonce = Nonce::from_slice(nonce);
139+
let (plaintext, out_tag) =
140+
plaintext_in_ciphertext_out.split_at_mut(plaintext_in_ciphertext_out.len() - Self::tag_size());
141+
let tag = self
142+
.0
143+
.encrypt_in_place_detached(nonce, &[], plaintext)
144+
.expect("AES_256_GCM_SIV encrypt");
145+
out_tag.copy_from_slice(tag.as_slice())
146+
}
80147

81-
pub fn decrypt(&mut self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
82-
let nonce = Nonce::from_slice(nonce);
83-
let (ciphertext, in_tag) =
84-
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
85-
let in_tag = Tag::from_slice(in_tag);
86-
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
148+
pub fn decrypt(&mut self, nonce: &[u8], ciphertext_in_plaintext_out: &mut [u8]) -> bool {
149+
let nonce = Nonce::from_slice(nonce);
150+
let (ciphertext, in_tag) =
151+
ciphertext_in_plaintext_out.split_at_mut(ciphertext_in_plaintext_out.len() - Self::tag_size());
152+
let in_tag = Tag::from_slice(in_tag);
153+
self.0.decrypt_in_place_detached(nonce, &[], ciphertext, in_tag).is_ok()
154+
}
155+
}
87156
}
88157
}

0 commit comments

Comments
 (0)