diff --git a/vlib/crypto/aes/aes.v b/vlib/crypto/aes/aes.v index a159048f3e..bf9edafb15 100644 --- a/vlib/crypto/aes/aes.v +++ b/vlib/crypto/aes/aes.v @@ -24,6 +24,18 @@ mut: 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)]. // The key argument should be the AES key, // either 16, 24, or 32 bytes to select diff --git a/vlib/crypto/bcrypt/bcrypt.v b/vlib/crypto/bcrypt/bcrypt.v index 9398959d42..b396552dcf 100644 --- a/vlib/crypto/bcrypt/bcrypt.v +++ b/vlib/crypto/bcrypt/bcrypt.v @@ -27,6 +27,18 @@ mut: 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, 0x6c, 0x64, 0x65, 0x72, 0x53, 0x63, 0x72, 0x79, 0x44, 0x6f, 0x75, 0x62, 0x74] diff --git a/vlib/crypto/cipher/cbc.v b/vlib/crypto/cipher/cbc.v index 67730e3d8e..2e901700a0 100644 --- a/vlib/crypto/cipher/cbc.v +++ b/vlib/crypto/cipher/cbc.v @@ -19,6 +19,19 @@ mut: 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 fn new_des_cbc(b Block, iv []u8) Cbc { return Cbc{ diff --git a/vlib/crypto/cipher/cfb.v b/vlib/crypto/cipher/cfb.v index a2853df914..527a3ab007 100644 --- a/vlib/crypto/cipher/cfb.v +++ b/vlib/crypto/cipher/cfb.v @@ -20,6 +20,19 @@ mut: 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, // using the given Block. The iv must be the same length as the Block's block // size diff --git a/vlib/crypto/cipher/ctr.v b/vlib/crypto/cipher/ctr.v index b23be26257..fc8962ce99 100644 --- a/vlib/crypto/cipher/ctr.v +++ b/vlib/crypto/cipher/ctr.v @@ -21,6 +21,19 @@ mut: 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 // 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 { diff --git a/vlib/crypto/md5/md5.v b/vlib/crypto/md5/md5.v index 6a6dc49f90..1450ba0f2d 100644 --- a/vlib/crypto/md5/md5.v +++ b/vlib/crypto/md5/md5.v @@ -33,9 +33,23 @@ mut: 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.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[1] = u32(md5.init1) 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. pub fn new() &Digest { mut d := &Digest{} - d.reset() + d.init() return d } diff --git a/vlib/crypto/md5/md5_test.v b/vlib/crypto/md5/md5_test.v index 0081a8fd77..6edf166beb 100644 --- a/vlib/crypto/md5/md5_test.v +++ b/vlib/crypto/md5/md5_test.v @@ -6,3 +6,23 @@ import crypto.md5 fn test_crypto_md5() { 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' +} diff --git a/vlib/crypto/rc4/rc4.v b/vlib/crypto/rc4/rc4.v index cf533a2bde..dc5f5595d1 100644 --- a/vlib/crypto/rc4/rc4.v +++ b/vlib/crypto/rc4/rc4.v @@ -20,6 +20,15 @@ mut: 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 // RC4 key, at least 1 byte and at most 256 bytes. pub fn new_cipher(key []u8) !Cipher { diff --git a/vlib/crypto/sha1/sha1.v b/vlib/crypto/sha1/sha1.v index 4f7622c38d..96084e4705 100644 --- a/vlib/crypto/sha1/sha1.v +++ b/vlib/crypto/sha1/sha1.v @@ -35,9 +35,26 @@ mut: 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.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[1] = u32(sha1.init1) 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. pub fn new() &Digest { mut d := &Digest{} - d.reset() + d.init() return d } diff --git a/vlib/crypto/sha1/sha1_test.v b/vlib/crypto/sha1/sha1_test.v index b063d8aec4..e9a4b52421 100644 --- a/vlib/crypto/sha1/sha1_test.v +++ b/vlib/crypto/sha1/sha1_test.v @@ -6,3 +6,23 @@ import crypto.sha1 fn test_crypto_sha1() { 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' +} diff --git a/vlib/crypto/sha256/sha256.v b/vlib/crypto/sha256/sha256.v index 89638bce4c..717fb58275 100644 --- a/vlib/crypto/sha256/sha256.v +++ b/vlib/crypto/sha256/sha256.v @@ -63,6 +63,7 @@ pub fn (mut d Digest) free() { fn (mut d Digest) init() { d.h = []u32{len: (8)} d.x = []u8{len: sha256.chunk} + d.reset() } // reset the state of the Digest `d` @@ -94,7 +95,6 @@ pub fn (mut d Digest) reset() { pub fn new() &Digest { mut d := &Digest{} d.init() - d.reset() return d } @@ -103,7 +103,6 @@ pub fn new224() &Digest { mut d := &Digest{} d.is224 = true d.init() - d.reset() return d } diff --git a/vlib/crypto/sha512/sha512.v b/vlib/crypto/sha512/sha512.v index 56e559dc98..af68ccf2fd 100644 --- a/vlib/crypto/sha512/sha512.v +++ b/vlib/crypto/sha512/sha512.v @@ -70,9 +70,26 @@ mut: 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.x = []u8{len: sha512.chunk} + d.reset() +} + +// reset the state of the Digest `d` +pub fn (mut d Digest) reset() { match d.function { .sha384 { d.h[0] = sha512.init0_384 @@ -124,7 +141,7 @@ fn new_digest(hash crypto.Hash) &Digest { mut d := &Digest{ function: hash } - d.reset() + d.init() return d } diff --git a/vlib/crypto/sha512/sha512_test.v b/vlib/crypto/sha512/sha512_test.v index cfc96d76fe..624602d893 100644 --- a/vlib/crypto/sha512/sha512_test.v +++ b/vlib/crypto/sha512/sha512_test.v @@ -6,3 +6,23 @@ import crypto.sha512 fn test_crypto_sha512() { 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' +}