1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

crypto: add .free() and .reset() methods to reduce memory leaks with -autofree (#16992)

* Fix unsafe pointer

I was compile vab with '-prod' and it was needed  to fix and it is of course warning

* Add files via upload

* reduce memory  leak s sha512

* add method .free() and .reset() for some
This commit is contained in:
MatejMagat305 2023-01-16 16:30:40 +01:00 committed by GitHub
parent 92fd12c18a
commit 6bf6a40e0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 187 additions and 8 deletions

View File

@ -24,6 +24,18 @@ mut:
dec []u32 dec []u32
} }
// free the resources taken by the AesCipher `c`
[unsafe]
pub fn (mut c AesCipher) free() {
$if prealloc {
return
}
unsafe {
c.enc.free()
c.dec.free()
}
}
// new_cipher creates and returns a new [[AesCipher](#AesCipher)]. // new_cipher creates and returns a new [[AesCipher](#AesCipher)].
// The key argument should be the AES key, // The key argument should be the AES key,
// either 16, 24, or 32 bytes to select // either 16, 24, or 32 bytes to select

View File

@ -27,6 +27,18 @@ mut:
minor string minor string
} }
// free the resources taken by the Hashed `h`
[unsafe]
pub fn (mut h Hashed) free() {
$if prealloc {
return
}
unsafe {
h.salt.free()
h.hash.free()
}
}
const magic_cipher_data = [u8(0x4f), 0x72, 0x70, 0x68, 0x65, 0x61, 0x6e, 0x42, 0x65, 0x68, 0x6f, const magic_cipher_data = [u8(0x4f), 0x72, 0x70, 0x68, 0x65, 0x61, 0x6e, 0x42, 0x65, 0x68, 0x6f,
0x6c, 0x64, 0x65, 0x72, 0x53, 0x63, 0x72, 0x79, 0x44, 0x6f, 0x75, 0x62, 0x74] 0x6c, 0x64, 0x65, 0x72, 0x53, 0x63, 0x72, 0x79, 0x44, 0x6f, 0x75, 0x62, 0x74]

View File

@ -19,6 +19,19 @@ mut:
tmp []u8 tmp []u8
} }
// free the resources taken by the Cbc `x`
[unsafe]
pub fn (mut x Cbc) free() {
$if prealloc {
return
}
unsafe {
// x.b.free() TODO add?
x.iv.free()
x.tmp.free()
}
}
// internal // internal
fn new_des_cbc(b Block, iv []u8) Cbc { fn new_des_cbc(b Block, iv []u8) Cbc {
return Cbc{ return Cbc{

View File

@ -20,6 +20,19 @@ mut:
decrypt bool decrypt bool
} }
// free the resources taken by the Cfb `x`
[unsafe]
pub fn (mut x Cfb) free() {
$if prealloc {
return
}
unsafe {
// x.b.free() TODO add?
x.out.free()
x.next.free()
}
}
// new_cfb_encrypter returns a `Cfb` which encrypts with cipher feedback mode, // new_cfb_encrypter returns a `Cfb` which encrypts with cipher feedback mode,
// using the given Block. The iv must be the same length as the Block's block // using the given Block. The iv must be the same length as the Block's block
// size // size

View File

@ -21,6 +21,19 @@ mut:
out_used int out_used int
} }
// free the resources taken by the Ctr `c`
[unsafe]
pub fn (mut x Ctr) free() {
$if prealloc {
return
}
unsafe {
// x.b.free() TODO add?
x.out.free()
x.next.free()
}
}
// new_ctr returns a Ctr which encrypts/decrypts using the given Block in // new_ctr returns a Ctr which encrypts/decrypts using the given Block in
// counter mode. The length of iv must be the same as the Block's block size. // counter mode. The length of iv must be the same as the Block's block size.
pub fn new_ctr(b Block, iv []u8) Ctr { pub fn new_ctr(b Block, iv []u8) Ctr {

View File

@ -33,9 +33,23 @@ mut:
len u64 len u64
} }
fn (mut d Digest) reset() { // free the resources taken by the Digest `d`
[unsafe]
pub fn (mut d Digest) free() {
$if prealloc {
return
}
unsafe { d.x.free() }
}
fn (mut d Digest) init() {
d.s = []u32{len: (4)} d.s = []u32{len: (4)}
d.x = []u8{len: md5.block_size} d.x = []u8{len: md5.block_size}
d.reset()
}
// reset the state of the Digest `d`
pub fn (mut d Digest) reset() {
d.s[0] = u32(md5.init0) d.s[0] = u32(md5.init0)
d.s[1] = u32(md5.init1) d.s[1] = u32(md5.init1)
d.s[2] = u32(md5.init2) d.s[2] = u32(md5.init2)
@ -47,7 +61,7 @@ fn (mut d Digest) reset() {
// new returns a new Digest (implementing hash.Hash) computing the MD5 checksum. // new returns a new Digest (implementing hash.Hash) computing the MD5 checksum.
pub fn new() &Digest { pub fn new() &Digest {
mut d := &Digest{} mut d := &Digest{}
d.reset() d.init()
return d return d
} }

View File

@ -6,3 +6,23 @@ import crypto.md5
fn test_crypto_md5() { fn test_crypto_md5() {
assert md5.sum('this is a md5 checksum.'.bytes()).hex() == '6fb421ff99036547655984da12973431' assert md5.sum('this is a md5 checksum.'.bytes()).hex() == '6fb421ff99036547655984da12973431'
} }
fn test_crypto_md5_writer() {
mut digest := md5.new()
digest.write('this is a'.bytes()) or { assert false }
digest.write(' md5 checksum.'.bytes()) or { assert false }
sum := digest.sum([])
assert sum.hex() == '6fb421ff99036547655984da12973431'
}
fn test_crypto_md5_writer_reset() {
mut digest := md5.new()
digest.write('this is a'.bytes()) or { assert false }
digest.write(' md5 checksum.'.bytes()) or { assert false }
_ = digest.sum([])
digest.reset()
digest.write('this is a'.bytes()) or { assert false }
digest.write(' md5 checksum.'.bytes()) or { assert false }
sum := digest.sum([])
assert sum.hex() == '6fb421ff99036547655984da12973431'
}

View File

@ -20,6 +20,15 @@ mut:
j u8 j u8
} }
// free the resources taken by the Cipher `c`
[unsafe]
pub fn (mut c Cipher) free() {
$if prealloc {
return
}
unsafe { c.s.free() }
}
// new_cipher creates and returns a new Cipher. The key argument should be the // new_cipher creates and returns a new Cipher. The key argument should be the
// RC4 key, at least 1 byte and at most 256 bytes. // RC4 key, at least 1 byte and at most 256 bytes.
pub fn new_cipher(key []u8) !Cipher { pub fn new_cipher(key []u8) !Cipher {

View File

@ -35,9 +35,26 @@ mut:
len u64 len u64
} }
fn (mut d Digest) reset() { // free the resources taken by the Digest `d`
[unsafe]
pub fn (mut d Digest) free() {
$if prealloc {
return
}
unsafe {
d.x.free()
d.h.free()
}
}
fn (mut d Digest) init() {
d.x = []u8{len: sha1.chunk} d.x = []u8{len: sha1.chunk}
d.h = []u32{len: (5)} d.h = []u32{len: (5)}
d.reset()
}
// reset the state of the Digest `d`
pub fn (mut d Digest) reset() {
d.h[0] = u32(sha1.init0) d.h[0] = u32(sha1.init0)
d.h[1] = u32(sha1.init1) d.h[1] = u32(sha1.init1)
d.h[2] = u32(sha1.init2) d.h[2] = u32(sha1.init2)
@ -50,7 +67,7 @@ fn (mut d Digest) reset() {
// new returns a new Digest (implementing hash.Hash) computing the SHA1 checksum. // new returns a new Digest (implementing hash.Hash) computing the SHA1 checksum.
pub fn new() &Digest { pub fn new() &Digest {
mut d := &Digest{} mut d := &Digest{}
d.reset() d.init()
return d return d
} }

View File

@ -6,3 +6,23 @@ import crypto.sha1
fn test_crypto_sha1() { fn test_crypto_sha1() {
assert sha1.sum('This is a sha1 checksum.'.bytes()).hex() == 'e100d74442faa5dcd59463b808983c810a8eb5a1' assert sha1.sum('This is a sha1 checksum.'.bytes()).hex() == 'e100d74442faa5dcd59463b808983c810a8eb5a1'
} }
fn test_crypto_sha1_writer() {
mut digest := sha1.new()
digest.write('This is a'.bytes()) or { assert false }
digest.write(' sha1 checksum.'.bytes()) or { assert false }
sum := digest.sum([])
assert sum.hex() == 'e100d74442faa5dcd59463b808983c810a8eb5a1'
}
fn test_crypto_sha1_writer_reset() {
mut digest := sha1.new()
digest.write('This is a'.bytes()) or { assert false }
digest.write(' sha1 checksum.'.bytes()) or { assert false }
_ = digest.sum([])
digest.reset()
digest.write('This is a'.bytes()) or { assert false }
digest.write(' sha1 checksum.'.bytes()) or { assert false }
sum := digest.sum([])
assert sum.hex() == 'e100d74442faa5dcd59463b808983c810a8eb5a1'
}

View File

@ -63,6 +63,7 @@ pub fn (mut d Digest) free() {
fn (mut d Digest) init() { fn (mut d Digest) init() {
d.h = []u32{len: (8)} d.h = []u32{len: (8)}
d.x = []u8{len: sha256.chunk} d.x = []u8{len: sha256.chunk}
d.reset()
} }
// reset the state of the Digest `d` // reset the state of the Digest `d`
@ -94,7 +95,6 @@ pub fn (mut d Digest) reset() {
pub fn new() &Digest { pub fn new() &Digest {
mut d := &Digest{} mut d := &Digest{}
d.init() d.init()
d.reset()
return d return d
} }
@ -103,7 +103,6 @@ pub fn new224() &Digest {
mut d := &Digest{} mut d := &Digest{}
d.is224 = true d.is224 = true
d.init() d.init()
d.reset()
return d return d
} }

View File

@ -70,9 +70,26 @@ mut:
function crypto.Hash function crypto.Hash
} }
fn (mut d Digest) reset() { // free the resources taken by the Digest `d`
[unsafe]
pub fn (mut d Digest) free() {
$if prealloc {
return
}
unsafe {
d.x.free()
d.h.free()
}
}
fn (mut d Digest) init() {
d.h = []u64{len: (8)} d.h = []u64{len: (8)}
d.x = []u8{len: sha512.chunk} d.x = []u8{len: sha512.chunk}
d.reset()
}
// reset the state of the Digest `d`
pub fn (mut d Digest) reset() {
match d.function { match d.function {
.sha384 { .sha384 {
d.h[0] = sha512.init0_384 d.h[0] = sha512.init0_384
@ -124,7 +141,7 @@ fn new_digest(hash crypto.Hash) &Digest {
mut d := &Digest{ mut d := &Digest{
function: hash function: hash
} }
d.reset() d.init()
return d return d
} }

View File

@ -6,3 +6,23 @@ import crypto.sha512
fn test_crypto_sha512() { fn test_crypto_sha512() {
assert sha512.sum512('This is a sha512 checksum.'.bytes()).hex() == '4143e55fcba7e39b20f62a1368e5eb28f64a8859458886117ac66027832e0f9f5263daec688c439d2d0fa07059334668d39e59543039703dbb7e03ec9da7f8d7' assert sha512.sum512('This is a sha512 checksum.'.bytes()).hex() == '4143e55fcba7e39b20f62a1368e5eb28f64a8859458886117ac66027832e0f9f5263daec688c439d2d0fa07059334668d39e59543039703dbb7e03ec9da7f8d7'
} }
fn test_crypto_sha512_writer() {
mut digest := sha512.new_digest(.sha512)
digest.write('This is a'.bytes()) or { assert false }
digest.write(' sha512 checksum.'.bytes()) or { assert false }
sum := digest.checksum()
assert sum.hex() == '4143e55fcba7e39b20f62a1368e5eb28f64a8859458886117ac66027832e0f9f5263daec688c439d2d0fa07059334668d39e59543039703dbb7e03ec9da7f8d7'
}
fn test_crypto_sha512_writer_reset() {
mut digest := sha512.new_digest(.sha512)
digest.write('This is a'.bytes()) or { assert false }
digest.write(' sha512 checksum.'.bytes()) or { assert false }
_ = digest.checksum()
digest.reset()
digest.write('This is a'.bytes()) or { assert false }
digest.write(' sha512 checksum.'.bytes()) or { assert false }
sum := digest.checksum()
assert sum.hex() == '4143e55fcba7e39b20f62a1368e5eb28f64a8859458886117ac66027832e0f9f5263daec688c439d2d0fa07059334668d39e59543039703dbb7e03ec9da7f8d7'
}