ceremonyclient/bedlam/pkg/crypto/cipher/cbc/cbc.qcl
Cassandra Heart dbd95bd9e9
v2.1.0 (#439)
* v2.1.0 [omit consensus and adjacent] - this commit will be amended with the full release after the file copy is complete

* 2.1.0 main node rollup
2025-09-30 02:48:15 -05:00

92 lines
2.4 KiB
Go

// -*- go -*-
//
// Copyright (c) 2021-2024 Markku Rossi
//
// All rights reserved.
//
// Package cbc implements the cipher block chaining (CBC) mode of
// operation for block ciphers.
package cbc
import (
"crypto/aes"
)
// PadAES pads the data to AES cipher block boundary. The padding is
// filled with byte value describing the padding length. Note that
// data will be always padded. If the original data is already padded,
// the padding will be one full AES block.
func PadAES(data []byte) []byte {
padLen := aes.BlockSize - len(data)%aes.BlockSize
var padded [len(data) + padLen]byte
for i := 0; i < padLen; i++ {
padded[len(data)+i] = byte(padLen)
}
copy(padded, data)
return padded
}
// EncryptAES128 encrypts the data in AES-CBC mode. The key specifies
// the AES encryption key and iv is a random initialization
// vector. The data must be padded to AES block size.
//
// // Case #1: Encrypting 16 bytes (1 block) using AES-CBC with 128-bit key
// // Key : 0x06a9214036b8a15b512e03d534120006
// // IV : 0x3dafba429d9eb430b422da802c9fac41
// // Plaintext : "Single block msg"
// // Ciphertext: 0xe353779c1079aeb82708942dbe77181a
//
// key := []byte{
// 0x06, 0xa9, 0x21, 0x40, 0x36, 0xb8, 0xa1, 0x5b,
// 0x51, 0x2e, 0x03, 0xd5, 0x34, 0x12, 0x00, 0x06,
// }
// iv := []byte{
// 0x3d, 0xaf, 0xba, 0x42, 0x9d, 0x9e, 0xb4, 0x30,
// 0xb4, 0x22, 0xda, 0x80, 0x2c, 0x9f, 0xac, 0x41,
// }
// plain := []byte("Single block msg")
//
// cipher := cbc.EncryptAES128(key, iv, plain)
// => e353779c1079aeb82708942dbe77181a
func EncryptAES128(key [16]byte, iv [aes.BlockSize]byte, data []byte) []byte {
var block [aes.BlockSize]byte
copy(block, iv)
var plain [aes.BlockSize]byte
var cipher [len(data)]byte
for i := 0; i < len(data)/aes.BlockSize; i++ {
copy(plain, data[i*aes.BlockSize:])
for j := 0; j < aes.BlockSize; j++ {
plain[j] ^= block[j]
}
//block = aes.Block128(key, plain)
block = aes.EncryptBlock(key, plain)
copy(cipher[i*aes.BlockSize:], block)
}
return cipher
}
func DecryptAES128(key [16]byte, iv [aes.BlockSize]byte, data []byte) []byte {
var block [aes.BlockSize]byte
var cipher [aes.BlockSize]byte
var plain [len(data)]byte
for i := 0; i < len(data)/aes.BlockSize; i++ {
copy(cipher, data[i*aes.BlockSize:])
block = aes.DecryptBlock(key, cipher)
for j := 0; j < aes.BlockSize; j++ {
block[j] ^= iv[j]
}
copy(plain[i*aes.BlockSize:], block)
copy(iv, cipher)
}
return plain
}