@@ -13,6 +13,8 @@ use pyo3::IntoPy;
13
13
pub ( crate ) struct CipherContext {
14
14
ctx : openssl:: cipher_ctx:: CipherCtx ,
15
15
py_mode : pyo3:: PyObject ,
16
+ py_algorithm : pyo3:: PyObject ,
17
+ side : openssl:: symm:: Mode ,
16
18
}
17
19
18
20
impl CipherContext {
@@ -113,9 +115,44 @@ impl CipherContext {
113
115
Ok ( CipherContext {
114
116
ctx,
115
117
py_mode : mode. into ( ) ,
118
+ py_algorithm : algorithm. into ( ) ,
119
+ side,
116
120
} )
117
121
}
118
122
123
+ fn reset_nonce ( & mut self , py : pyo3:: Python < ' _ > , nonce : CffiBuf < ' _ > ) -> CryptographyResult < ( ) > {
124
+ if !self
125
+ . py_mode
126
+ . bind ( py)
127
+ . is_instance ( & types:: MODE_WITH_NONCE . get ( py) ?) ?
128
+ && !self
129
+ . py_algorithm
130
+ . bind ( py)
131
+ . is_instance ( & types:: CHACHA20 . get ( py) ?) ?
132
+ {
133
+ return Err ( CryptographyError :: from (
134
+ exceptions:: UnsupportedAlgorithm :: new_err ( (
135
+ "This algorithm or mode does not support resetting the nonce." ,
136
+ exceptions:: Reasons :: UNSUPPORTED_CIPHER ,
137
+ ) ) ,
138
+ ) ) ;
139
+ }
140
+ if nonce. as_bytes ( ) . len ( ) != self . ctx . iv_length ( ) {
141
+ return Err ( CryptographyError :: from (
142
+ pyo3:: exceptions:: PyValueError :: new_err ( format ! (
143
+ "Nonce must be {} bytes long" ,
144
+ self . ctx. iv_length( )
145
+ ) ) ,
146
+ ) ) ;
147
+ }
148
+ let init_op = match self . side {
149
+ openssl:: symm:: Mode :: Encrypt => openssl:: cipher_ctx:: CipherCtxRef :: encrypt_init,
150
+ openssl:: symm:: Mode :: Decrypt => openssl:: cipher_ctx:: CipherCtxRef :: decrypt_init,
151
+ } ;
152
+ init_op ( & mut self . ctx , None , None , Some ( nonce. as_bytes ( ) ) ) ?;
153
+ Ok ( ( ) )
154
+ }
155
+
119
156
fn update < ' p > (
120
157
& mut self ,
121
158
py : pyo3:: Python < ' p > ,
@@ -236,6 +273,10 @@ impl PyCipherContext {
236
273
get_mut_ctx ( self . ctx . as_mut ( ) ) ?. update ( py, buf. as_bytes ( ) )
237
274
}
238
275
276
+ fn reset_nonce ( & mut self , py : pyo3:: Python < ' _ > , nonce : CffiBuf < ' _ > ) -> CryptographyResult < ( ) > {
277
+ get_mut_ctx ( self . ctx . as_mut ( ) ) ?. reset_nonce ( py, nonce)
278
+ }
279
+
239
280
fn update_into (
240
281
& mut self ,
241
282
py : pyo3:: Python < ' _ > ,
@@ -340,6 +381,10 @@ impl PyAEADEncryptionContext {
340
381
} ) ?
341
382
. clone_ref ( py) )
342
383
}
384
+
385
+ fn reset_nonce ( & mut self , py : pyo3:: Python < ' _ > , nonce : CffiBuf < ' _ > ) -> CryptographyResult < ( ) > {
386
+ get_mut_ctx ( self . ctx . as_mut ( ) ) ?. reset_nonce ( py, nonce)
387
+ }
343
388
}
344
389
345
390
#[ pyo3:: pymethods]
@@ -468,6 +513,10 @@ impl PyAEADDecryptionContext {
468
513
self . ctx = None ;
469
514
Ok ( result)
470
515
}
516
+
517
+ fn reset_nonce ( & mut self , py : pyo3:: Python < ' _ > , nonce : CffiBuf < ' _ > ) -> CryptographyResult < ( ) > {
518
+ get_mut_ctx ( self . ctx . as_mut ( ) ) ?. reset_nonce ( py, nonce)
519
+ }
471
520
}
472
521
473
522
#[ pyo3:: pyfunction]
0 commit comments