-
Notifications
You must be signed in to change notification settings - Fork 0
/
c11.go
87 lines (73 loc) · 2.19 KB
/
c11.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package main
import (
"crypto/aes"
"fmt"
mrand "math/rand/v2"
)
// encryptionOracle generates a random AES key and returns an aesWorker that
// encrypts with it.
func encryptionOracle(plainText []byte) ([]byte, error) {
padded, err := addRandomNoise(plainText)
if err != nil {
return nil, fmt.Errorf("secretly adding noise to plain text: %s", err)
}
key, err := randomBytes(aes.BlockSize, aes.BlockSize)
if err != nil {
return nil, fmt.Errorf("generating random AES key: %s", err)
}
if coinFlip := mrand.IntN(2); coinFlip == 0 {
return encryptAesEcb(padded, key)
}
iv, err := randomBytes(aes.BlockSize, aes.BlockSize)
if err != nil {
const formatStr = "generating random IV for AES CBC encryption: %s"
return nil, fmt.Errorf(formatStr, err)
}
return encryptAesCbc(padded, key, iv)
}
// encryptAesEcb encrypts a plain text using AES-128 in ECB mode with the given
// key.
func encryptAesEcb(plainText, key []byte) ([]byte, error) {
plainText = padPkcs7(plainText, aes.BlockSize)
encrypter, err := aesEncrypter(key)
if err != nil {
return nil, err
}
var (
plainTextLen = len(plainText)
blockSize = aes.BlockSize
nBlocks = (plainTextLen + blockSize - 1) / blockSize
cipherText = make([]byte, 0, plainTextLen)
)
for b := range nBlocks {
var (
start = b * blockSize
end = start + blockSize
)
cipherText = append(cipherText, encrypter(plainText[start:end])...)
}
return cipherText, nil
}
// encryptAesEcbString is a wrapper of encryptAesEcb for when you have a plain
// text to encrypt and a key to encrypt it as strings.
func encryptAesEcbString(plainText, key string) (string, error) {
cipherText, err := encryptAesEcb([]byte(plainText), []byte(key))
return string(cipherText), err
}
// addRandomNoise prepends and appends random bytes to the given data.
// It does not modify the forged data slice.
func addRandomNoise(data []byte) ([]byte, error) {
prefix, err := randomBytes(5, 10)
if err != nil {
return nil, err
}
suffix, err := randomBytes(5, 10)
if err != nil {
return nil, err
}
buf := make([]byte, len(prefix)+len(data)+len(suffix))
copy(buf, prefix)
copy(buf[len(prefix):], data)
copy(buf[len(prefix)+len(data):], suffix)
return buf, nil
}