v
Зеркало из https://github.com/vlang/v
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4// Based off: https://github.com/golang/go/blob/master/src/crypto/aes
5// Last commit: https://github.com/golang/go/commit/691a2d457ab1bf03bd46d4b69e0f93b8993c0055
6module aes
7
8import crypto.cipher
9import crypto.internal.subtle
10
11// The AES block size in bytes.
12pub const block_size = 16
13
14// AesCipher represents an AES encryption using a particular key.
15// It follows the API of golang's `cipher.Block` and is designed to
16// handle only one block of data at a time. In most cases, you
17// probably want to encrypt and decrypt using [[AesCbc](#AesCbc)]
18struct AesCipher {
19block_size int = block_size
20mut:
21enc []u32
22dec []u32
23}
24
25// free the resources taken by the AesCipher `c`
26@[unsafe]
27pub fn (mut c AesCipher) free() {
28$if prealloc {
29return
30}
31unsafe {
32c.enc.free()
33c.dec.free()
34}
35}
36
37// new_cipher creates and returns a new [[AesCipher](#AesCipher)].
38// The key argument should be the AES key,
39// either 16, 24, or 32 bytes to select
40// AES-128, AES-192, or AES-256.
41pub fn new_cipher(key []u8) cipher.Block {
42k := key.len
43match k {
4416, 24, 32 {
45// break
46}
47else {
48panic('crypto.aes: invalid key size ' + k.str())
49// return error('crypto.aes: invalid key size ' + k.str())
50}
51}
52// for now use generic version
53return new_cipher_generic(key)
54}
55
56// block_size returns the block size of the checksum in bytes.
57pub fn (c &AesCipher) block_size() int {
58return block_size
59}
60
61// encrypt encrypts the first block of data in `src` to `dst`.
62// NOTE: `dst` and `src` are both mutable for performance reasons.
63// NOTE: `dst` and `src` must both be pre-allocated to the correct length.
64// NOTE: `dst` and `src` may be the same (overlapping entirely).
65pub fn (c &AesCipher) encrypt(mut dst []u8, src []u8) {
66if src.len < block_size {
67panic('crypto.aes: input not full block')
68}
69if dst.len < block_size {
70panic('crypto.aes: output not full block')
71}
72// if subtle.inexact_overlap(dst[:block_size], src[:block_size]) {
73if subtle.inexact_overlap(dst[..block_size], src[..block_size]) {
74panic('crypto.aes: invalid buffer overlap')
75}
76// for now use generic version
77encrypt_block_generic(c.enc, mut dst, src)
78}
79
80// decrypt decrypts the first block of data in `src` to `dst`.
81// NOTE: `dst` and `src` are both mutable for performance reasons.
82// NOTE: `dst` and `src` must both be pre-allocated to the correct length.
83// NOTE: `dst` and `src` may be the same (overlapping entirely).
84pub fn (c &AesCipher) decrypt(mut dst []u8, src []u8) {
85if src.len < block_size {
86panic('crypto.aes: input not full block')
87}
88if dst.len < block_size {
89panic('crypto.aes: output not full block')
90}
91if subtle.inexact_overlap(dst[..block_size], src[..block_size]) {
92panic('crypto.aes: invalid buffer overlap')
93}
94// for now use generic version
95decrypt_block_generic(c.dec, mut dst, src)
96}
97