@@ -38,8 +38,6 @@ pub fn new_psiv(key []u8) !&Chacha20Poly1305RE {
3838
3939 // set the values
4040 c := & Chacha20 Poly1305 RE{
41- key: key.clone ()
42- precomp: true
4341 mac_key: mac_key
4442 enc_key: enc_key
4543 po: po
@@ -52,18 +50,18 @@ pub fn new_psiv(key []u8) !&Chacha20Poly1305RE {
5250// within the end of ciphertext
5351@[direct_array_access]
5452pub fn psiv_encrypt (plaintext []u8 , key []u8 , nonce []u8 , ad []u8 ) ! []u8 {
55- c := new_psiv (key)!
53+ mut c := new_psiv (key)!
5654 out := c.encrypt (plaintext, nonce, ad)!
5755 unsafe { c.free () }
5856 return out
5957}
6058
6159// psiv_decrypt decrypts the ciphertext with provided key, nonce and additional data in ad.
62- // It also tries to validate message authenticated code within ciphertext compared with
60+ // It also tries to validate message authentication code within ciphertext compared with
6361// calculated tag. It returns successfully decrypted message or error on fails.
6462@[direct_array_access]
6563pub fn psiv_decrypt (ciphertext []u8 , key []u8 , nonce []u8 , ad []u8 ) ! []u8 {
66- c := new_psiv (key)!
64+ mut c := new_psiv (key)!
6765 out := c.decrypt (ciphertext, nonce, ad)!
6866 unsafe { c.free () }
6967 return out
@@ -74,10 +72,9 @@ pub fn psiv_decrypt(ciphertext []u8, key []u8, nonce []u8, ad []u8) ![]u8 {
7472@[noinit]
7573pub struct Chacha20Poly1305RE implements AEAD {
7674mut :
77- // An underlying 32-bytes of key
78- key []u8
79- // flags that tells derivation keys has been precomputed
80- precomp bool
75+ // flag that marked this instance should not be used again, set on .free call
76+ done bool
77+ // underlying derived keys, set on instance creation with new_psiv.
8178 mac_key [36 ]u8
8279 enc_key [36 ]u8
8380 po & poly1305 .Poly1305 = unsafe { nil }
8683// free releases resources taken by c. Dont use c after `.free` call.
8784@[unsafe ]
8885pub fn (mut c Chacha20Poly1305RE) free () {
86+ // if it already marked as done, just return
87+ if c.done {
88+ return
89+ }
8990 unsafe {
90- c.key.free ()
9191 // we reset derived keys
92- vmemset (c.mac_key, 0 , 36 )
93- vmemset (c.enc_key, 0 , 36 )
92+ vmemset (c.mac_key, 0 , c.mac_key.len )
93+ vmemset (c.enc_key, 0 , c.enc_key.len )
9494 c.po = nil
9595 }
96- c.precomp = false
96+ // mark this instance as done, no longer usable
97+ c.done = true
9798}
9899
99100// nonce_size return the size of the nonce of underlying c.
@@ -113,6 +114,9 @@ pub fn (c &Chacha20Poly1305RE) overhead() int {
113114// code stored within the end of ciphertext.
114115@[direct_array_access]
115116pub fn (c Chacha20Poly1305RE) encrypt (plaintext []u8 , nonce []u8 , ad []u8 ) ! []u8 {
117+ if c.done {
118+ return error ('Chacha20Poly1305RE.encrypt: instance marked as done, no longer usable' )
119+ }
116120 if nonce.len != nonce_size {
117121 return error ('Chacha20Poly1305RE.encrypt: bad nonce length, only support 12-bytes nonce' )
118122 }
@@ -141,6 +145,9 @@ pub fn (c Chacha20Poly1305RE) encrypt(plaintext []u8, nonce []u8, ad []u8) ![]u8
141145// calculated tag. It returns successfully decrypted message or error on fails.
142146@[direct_array_access]
143147pub fn (c Chacha20Poly1305RE) decrypt (ciphertext []u8 , nonce []u8 , ad []u8 ) ! []u8 {
148+ if c.done {
149+ return error ('Chacha20Poly1305RE.decrypt: instance marked as done, no longer usable' )
150+ }
144151 if ciphertext.len < tag_size {
145152 return error ('Chacha20Poly1305RE.decrypt: insufficient ciphertext length' )
146153 }
@@ -252,7 +259,7 @@ fn psiv_gen_tag(mut out []u8, mut po poly1305.Poly1305, input []u8, ad_len int,
252259
253260 // explicitly releases (reset) temporary allocated resources
254261 unsafe {
255- vmemset (drv_key, 0 , 36 )
262+ vmemset (drv_key, 0 , drv_key.len )
256263 ws.reset ()
257264 x.reset ()
258265 }
0 commit comments