@@ -5,7 +5,9 @@ use crate::error::Unspecified;
5
5
use core:: fmt:: Debug ;
6
6
7
7
use super :: aead_ctx:: AeadCtx ;
8
- use super :: { Aad , Algorithm , AlgorithmID , Nonce , Tag , UnboundKey } ;
8
+ use super :: {
9
+ Aad , Algorithm , AlgorithmID , Nonce , Tag , UnboundKey , AES_128_GCM_SIV , AES_256_GCM_SIV ,
10
+ } ;
9
11
10
12
/// AEAD Cipher key using a randomized nonce.
11
13
///
@@ -14,6 +16,8 @@ use super::{Aad, Algorithm, AlgorithmID, Nonce, Tag, UnboundKey};
14
16
/// The following algorithms are supported:
15
17
/// * `AES_128_GCM`
16
18
/// * `AES_256_GCM`
19
+ /// * `AES_128_GCM_SIV`
20
+ /// * `AES_256_GCM_SIV`
17
21
///
18
22
/// Prefer this type in place of `LessSafeKey`, `OpeningKey`, `SealingKey`.
19
23
pub struct RandomizedNonceKey {
@@ -36,10 +40,13 @@ impl RandomizedNonceKey {
36
40
algorithm. tag_len ( ) ,
37
41
algorithm. nonce_len ( ) ,
38
42
) ,
39
- AlgorithmID :: AES_128_GCM_SIV
40
- | AlgorithmID :: AES_192_GCM
41
- | AlgorithmID :: AES_256_GCM_SIV
42
- | AlgorithmID :: CHACHA20_POLY1305 => return Err ( Unspecified ) ,
43
+ AlgorithmID :: AES_128_GCM_SIV => {
44
+ AeadCtx :: aes_128_gcm_siv ( key_bytes, algorithm. tag_len ( ) )
45
+ }
46
+ AlgorithmID :: AES_256_GCM_SIV => {
47
+ AeadCtx :: aes_256_gcm_siv ( key_bytes, algorithm. tag_len ( ) )
48
+ }
49
+ AlgorithmID :: AES_192_GCM | AlgorithmID :: CHACHA20_POLY1305 => return Err ( Unspecified ) ,
43
50
} ?;
44
51
Ok ( Self {
45
52
key : UnboundKey :: from ( ctx) ,
@@ -95,8 +102,15 @@ impl RandomizedNonceKey {
95
102
A : AsRef < [ u8 ] > ,
96
103
InOut : AsMut < [ u8 ] > + for < ' in_out > Extend < & ' in_out u8 > ,
97
104
{
105
+ let nonce = if self . algorithm == & AES_128_GCM_SIV || self . algorithm == & AES_256_GCM_SIV {
106
+ let mut nonce = vec ! [ 0u8 ; self . algorithm. nonce_len( ) ] ;
107
+ crate :: rand:: fill ( & mut nonce[ ..] ) ?;
108
+ Some ( Nonce :: try_assume_unique_for_key ( nonce. as_slice ( ) ) ?)
109
+ } else {
110
+ None
111
+ } ;
98
112
self . key
99
- . seal_in_place_append_tag ( None , aad. as_ref ( ) , in_out)
113
+ . seal_in_place_append_tag ( nonce , aad. as_ref ( ) , in_out)
100
114
}
101
115
102
116
/// Encrypts and signs (“seals”) data in place.
@@ -125,8 +139,15 @@ impl RandomizedNonceKey {
125
139
where
126
140
A : AsRef < [ u8 ] > ,
127
141
{
142
+ let nonce = if self . algorithm == & AES_128_GCM_SIV || self . algorithm == & AES_256_GCM_SIV {
143
+ let mut nonce = vec ! [ 0u8 ; self . algorithm. nonce_len( ) ] ;
144
+ crate :: rand:: fill ( & mut nonce[ ..] ) ?;
145
+ Some ( Nonce :: try_assume_unique_for_key ( nonce. as_slice ( ) ) ?)
146
+ } else {
147
+ None
148
+ } ;
128
149
self . key
129
- . seal_in_place_separate_tag ( None , aad. as_ref ( ) , in_out)
150
+ . seal_in_place_separate_tag ( nonce , aad. as_ref ( ) , in_out)
130
151
}
131
152
132
153
/// The key's AEAD algorithm.
@@ -149,7 +170,9 @@ impl Debug for RandomizedNonceKey {
149
170
#[ cfg( test) ]
150
171
mod tests {
151
172
use super :: { Aad , RandomizedNonceKey } ;
152
- use crate :: aead:: { AES_128_GCM , AES_256_GCM , CHACHA20_POLY1305 } ;
173
+ use crate :: aead:: {
174
+ AES_128_GCM , AES_128_GCM_SIV , AES_256_GCM , AES_256_GCM_SIV , CHACHA20_POLY1305 ,
175
+ } ;
153
176
use crate :: test:: from_hex;
154
177
use paste:: paste;
155
178
@@ -221,5 +244,20 @@ mod tests {
221
244
222
245
test_randnonce ! ( aes_128_gcm, & AES_128_GCM , TEST_128_BIT_KEY , & 16 , & 12 ) ;
223
246
test_randnonce ! ( aes_256_gcm, & AES_256_GCM , TEST_256_BIT_KEY , & 16 , & 12 ) ;
247
+ test_randnonce ! (
248
+ aes_128_gcm_siv,
249
+ & AES_128_GCM_SIV ,
250
+ TEST_128_BIT_KEY ,
251
+ & 16 ,
252
+ & 12
253
+ ) ;
254
+ test_randnonce ! (
255
+ aes_256_gcm_siv,
256
+ & AES_256_GCM_SIV ,
257
+ TEST_256_BIT_KEY ,
258
+ & 16 ,
259
+ & 12
260
+ ) ;
261
+
224
262
test_randnonce ! ( chacha20_poly1305, & CHACHA20_POLY1305 , TEST_256_BIT_KEY ) ;
225
263
}
0 commit comments