v2 / vlib / crypto / aes / aes.v
97 lines · 88 sloc · 2.91 KB · 8e35f4d9848f7ad35d857a187dddbfd2eca5e19d
Raw
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 {
19 block_size int = block_size
20mut:
21 enc []u32
22 dec []u32
23}
24
25// free the resources taken by the AesCipher `c`
26@[unsafe]
27pub fn (mut c AesCipher) free() {
28 $if prealloc {
29 return
30 }
31 unsafe {
32 c.enc.free()
33 c.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 {
42 k := key.len
43 match k {
44 16, 24, 32 {
45 // break
46 }
47 else {
48 panic('crypto.aes: invalid key size ' + k.str())
49 // return error('crypto.aes: invalid key size ' + k.str())
50 }
51 }
52
53 // for now use generic version
54 return new_cipher_generic(key)
55}
56
57// block_size returns the block size of the checksum in bytes.
58pub fn (c &AesCipher) block_size() int {
59 return block_size
60}
61
62// encrypt encrypts the first block of data in `src` to `dst`.
63// NOTE: `dst` and `src` are both mutable for performance reasons.
64// NOTE: `dst` and `src` must both be pre-allocated to the correct length.
65// NOTE: `dst` and `src` may be the same (overlapping entirely).
66pub fn (c &AesCipher) encrypt(mut dst []u8, src []u8) {
67 if src.len < block_size {
68 panic('crypto.aes: input not full block')
69 }
70 if dst.len < block_size {
71 panic('crypto.aes: output not full block')
72 }
73 // if subtle.inexact_overlap(dst[:block_size], src[:block_size]) {
74 if subtle.inexact_overlap(dst[..block_size], src[..block_size]) {
75 panic('crypto.aes: invalid buffer overlap')
76 }
77 // for now use generic version
78 encrypt_block_generic(c.enc, mut dst, src)
79}
80
81// decrypt decrypts the first block of data in `src` to `dst`.
82// NOTE: `dst` and `src` are both mutable for performance reasons.
83// NOTE: `dst` and `src` must both be pre-allocated to the correct length.
84// NOTE: `dst` and `src` may be the same (overlapping entirely).
85pub fn (c &AesCipher) decrypt(mut dst []u8, src []u8) {
86 if src.len < block_size {
87 panic('crypto.aes: input not full block')
88 }
89 if dst.len < block_size {
90 panic('crypto.aes: output not full block')
91 }
92 if subtle.inexact_overlap(dst[..block_size], src[..block_size]) {
93 panic('crypto.aes: invalid buffer overlap')
94 }
95 // for now use generic version
96 decrypt_block_generic(c.dec, mut dst, src)
97}
98