Skip to content

Commit 180253f

Browse files
authored
x.crypto.chacha20poly1305: improve safety check and small cleanups (#25631)
1 parent 50fd4fd commit 180253f

File tree

1 file changed

+21
-14
lines changed
  • vlib/x/crypto/chacha20poly1305

1 file changed

+21
-14
lines changed

vlib/x/crypto/chacha20poly1305/psiv.v

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ pub fn new_psiv(key []u8) !&Chacha20Poly1305RE {
3838

3939
// set the values
4040
c := &Chacha20Poly1305RE{
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]
5452
pub 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]
6563
pub 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]
7573
pub struct Chacha20Poly1305RE implements AEAD {
7674
mut:
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 }
@@ -86,14 +83,18 @@ mut:
8683
// free releases resources taken by c. Dont use c after `.free` call.
8784
@[unsafe]
8885
pub 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]
115116
pub 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]
143147
pub 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

Comments
 (0)