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

99 lines
3.0 KiB
V
Raw Normal View History

2022-01-04 12:21:08 +03:00
// Copyright (c) 2019-2022 Alexander Medvednikov. All rights reserved.
2019-07-25 18:49:57 +03:00
// Use of this source code is governed by an MIT license
// that can be found in the LICENSE file.
// Based off: https://github.com/golang/go/blob/master/src/crypto/aes
// Last commit: https://github.com/golang/go/commit/691a2d457ab1bf03bd46d4b69e0f93b8993c0055
2019-07-25 18:49:57 +03:00
module aes
import crypto.cipher
2020-04-26 14:49:31 +03:00
import crypto.internal.subtle
2019-07-25 18:49:57 +03:00
pub const (
2019-07-25 18:49:57 +03:00
// The AES block size in bytes.
2019-10-24 14:48:20 +03:00
block_size = 16
2019-07-25 18:49:57 +03:00
)
// AesCipher represents an AES encryption using a particular key.
// It follows the API of golang's `cipher.Block` and is designed to
// handle only one block of data at a time. In most cases, you
// probably want to encrypt and decrypt using [[AesCbc](#AesCbc)]
2019-07-25 18:49:57 +03:00
struct AesCipher {
block_size int = aes.block_size
mut:
2019-07-25 18:49:57 +03:00
enc []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)].
2019-07-25 18:49:57 +03:00
// The key argument should be the AES key,
// either 16, 24, or 32 bytes to select
// AES-128, AES-192, or AES-256.
2022-04-15 15:35:35 +03:00
pub fn new_cipher(key []u8) cipher.Block {
2019-07-25 18:49:57 +03:00
k := key.len
2019-10-27 12:36:38 +03:00
match k {
16, 24, 32 {
// break
}
else {
panic('crypto.aes: invalid key size ' + k.str())
// return error('crypto.aes: invalid key size ' + k.str())
}
2019-10-27 12:36:38 +03:00
}
2019-07-25 18:49:57 +03:00
// for now use generic version
return new_cipher_generic(key)
}
// block_size returns the block size of the checksum in bytes.
pub fn (c &AesCipher) block_size() int {
return aes.block_size
}
2019-07-25 18:49:57 +03:00
// encrypt encrypts the first block of data in `src` to `dst`.
// NOTE: `dst` and `src` are both mutable for performance reasons.
// NOTE: `dst` and `src` must both be pre-allocated to the correct length.
// NOTE: `dst` and `src` may be the same (overlapping entirely).
2022-04-15 15:35:35 +03:00
pub fn (c &AesCipher) encrypt(mut dst []u8, src []u8) {
if src.len < aes.block_size {
2019-07-25 18:49:57 +03:00
panic('crypto.aes: input not full block')
}
if dst.len < aes.block_size {
2019-07-25 18:49:57 +03:00
panic('crypto.aes: output not full block')
}
2019-10-24 14:48:20 +03:00
// if subtle.inexact_overlap(dst[:block_size], src[:block_size]) {
if subtle.inexact_overlap(dst[..aes.block_size], src[..aes.block_size]) {
2019-07-25 18:49:57 +03:00
panic('crypto.aes: invalid buffer overlap')
}
// for now use generic version
encrypt_block_generic(c.enc, mut dst, src)
2019-07-25 18:49:57 +03:00
}
// decrypt decrypts the first block of data in `src` to `dst`.
// NOTE: `dst` and `src` are both mutable for performance reasons.
// NOTE: `dst` and `src` must both be pre-allocated to the correct length.
// NOTE: `dst` and `src` may be the same (overlapping entirely).
2022-04-15 15:35:35 +03:00
pub fn (c &AesCipher) decrypt(mut dst []u8, src []u8) {
if src.len < aes.block_size {
2019-07-25 18:49:57 +03:00
panic('crypto.aes: input not full block')
}
if dst.len < aes.block_size {
2019-07-25 18:49:57 +03:00
panic('crypto.aes: output not full block')
}
if subtle.inexact_overlap(dst[..aes.block_size], src[..aes.block_size]) {
2019-07-25 18:49:57 +03:00
panic('crypto.aes: invalid buffer overlap')
}
// for now use generic version
decrypt_block_generic(c.dec, mut dst, src)
2019-07-25 18:49:57 +03:00
}