2021-01-18 15:20:06 +03:00
|
|
|
// Copyright (c) 2019-2021 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.
|
2019-08-02 07:37:19 +03:00
|
|
|
// 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
|
|
|
|
|
2020-04-26 14:49:31 +03:00
|
|
|
import crypto.internal.subtle
|
2019-07-25 18:49:57 +03:00
|
|
|
|
2019-12-06 15:24:53 +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
|
|
|
)
|
|
|
|
|
|
|
|
// A cipher is an instance of AES encryption using a particular key.
|
|
|
|
struct AesCipher {
|
2020-06-30 15:19:22 +03:00
|
|
|
mut:
|
2019-07-25 18:49:57 +03:00
|
|
|
enc []u32
|
|
|
|
dec []u32
|
|
|
|
}
|
|
|
|
|
|
|
|
// new_cipher creates and returns a new cipher.Block.
|
|
|
|
// The key argument should be the AES key,
|
|
|
|
// either 16, 24, or 32 bytes to select
|
|
|
|
// AES-128, AES-192, or AES-256.
|
|
|
|
pub fn new_cipher(key []byte) AesCipher {
|
|
|
|
k := key.len
|
2019-10-27 12:36:38 +03:00
|
|
|
match k {
|
2020-11-11 19:16:45 +03:00
|
|
|
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)
|
|
|
|
}
|
|
|
|
|
2020-11-11 19:16:45 +03:00
|
|
|
pub fn (c &AesCipher) block_size() int {
|
|
|
|
return block_size
|
|
|
|
}
|
2019-07-25 18:49:57 +03:00
|
|
|
|
2020-06-30 15:19:22 +03:00
|
|
|
pub fn (c &AesCipher) encrypt(mut dst []byte, mut src []byte) {
|
2019-10-24 14:48:20 +03:00
|
|
|
if src.len < block_size {
|
2019-07-25 18:49:57 +03:00
|
|
|
panic('crypto.aes: input not full block')
|
|
|
|
}
|
2019-10-24 14:48:20 +03:00
|
|
|
if dst.len < 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]) {
|
2020-06-30 15:19:22 +03:00
|
|
|
if subtle.inexact_overlap((*dst)[..block_size], (*src)[..block_size]) {
|
2019-07-25 18:49:57 +03:00
|
|
|
panic('crypto.aes: invalid buffer overlap')
|
|
|
|
}
|
|
|
|
// for now use generic version
|
2020-06-30 15:19:22 +03:00
|
|
|
encrypt_block_generic(c.enc, mut dst, src)
|
2019-07-25 18:49:57 +03:00
|
|
|
}
|
|
|
|
|
2020-06-30 15:19:22 +03:00
|
|
|
pub fn (c &AesCipher) decrypt(mut dst []byte, mut src []byte) {
|
2019-10-24 14:48:20 +03:00
|
|
|
if src.len < block_size {
|
2019-07-25 18:49:57 +03:00
|
|
|
panic('crypto.aes: input not full block')
|
|
|
|
}
|
2019-10-24 14:48:20 +03:00
|
|
|
if dst.len < block_size {
|
2019-07-25 18:49:57 +03:00
|
|
|
panic('crypto.aes: output not full block')
|
|
|
|
}
|
2020-06-30 15:19:22 +03:00
|
|
|
if subtle.inexact_overlap((*dst)[..block_size], (*src)[..block_size]) {
|
2019-07-25 18:49:57 +03:00
|
|
|
panic('crypto.aes: invalid buffer overlap')
|
|
|
|
}
|
|
|
|
// for now use generic version
|
2020-06-30 15:19:22 +03:00
|
|
|
decrypt_block_generic(c.dec, mut dst, src)
|
2019-07-25 18:49:57 +03:00
|
|
|
}
|