-
Notifications
You must be signed in to change notification settings - Fork 0
/
symmetric_test.go
185 lines (149 loc) · 4.95 KB
/
symmetric_test.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
// Test code for symmetric key ops. You should not need to modify this code,
// if any of these tests fail there is likely a problem with your Go
// language installation.
//
// SECURITY WARNING: This code is meant for educational purposes and may
// contain vulnerabilities or other bugs. Please do not use it for
// security-critical applications.
//
// Original version
// Joseph Bonneau February 2019
package chatterbox
import (
"bytes"
"encoding/hex"
"testing"
)
func TestAESKeyGeneration(t *testing.T) {
if bytes.Equal(NewSymmetricKey().Key, NewSymmetricKey().Key) {
t.Fatal("Key generation should produce unique keys")
}
}
func TestEncryptionDecryption(t *testing.T) {
k1 := NewSymmetricKey()
plaintext := "test"
data := []byte("extra")
iv := NewIV()
ciphertext := k1.AuthenticatedEncrypt(plaintext, data, iv)
decrypted, err := k1.AuthenticatedDecrypt(ciphertext, data, iv)
if err != nil {
t.Fatal("Decryption of valid ciphertext produced authentication error")
}
iv2 := NewIV()
if bytes.Equal(ciphertext, k1.AuthenticatedEncrypt(plaintext, data, iv2)) {
t.Fatal("Encryption under same key, different IV should produce distinct ciphertexts")
}
if plaintext != decrypted {
t.Fatal("Decryption did not return original message")
}
}
func TestZeroizeSymmetricKey(t *testing.T) {
k1 := NewSymmetricKey()
plaintext := "test"
data := []byte("extra")
iv := NewIV()
ciphertext := k1.AuthenticatedEncrypt(plaintext, data, iv)
k1.Zeroize()
if _, err := k1.AuthenticatedDecrypt(ciphertext, data, iv); err == nil {
t.Fatal("Decryption did not fail with zeroized key")
}
k2 := NewSymmetricKey()
k2.Zeroize()
if !bytes.Equal(k1.Key, k2.Key) {
t.Fatal("Zeroized keys should be identical")
}
}
func TestAuthentication(t *testing.T) {
k1 := NewSymmetricKey()
plaintext := "test"
data := []byte("extra")
iv := NewIV()
ciphertext := k1.AuthenticatedEncrypt(plaintext, data, iv)
// flip a bit in ciphertext
ciphertext[2] ^= 0x1
if _, err := k1.AuthenticatedDecrypt(ciphertext, data, iv); err == nil {
t.Fatal("Decryption did not fail on bit flip")
}
// undo bit flip in ciphertext
ciphertext[2] ^= 0x1
// flip a bit in additional data
data[2] ^= 0x1
if _, err := k1.AuthenticatedDecrypt(ciphertext, data, iv); err == nil {
t.Fatal("Decryption did not fail on additional data alteration")
}
// undo bit flip in data
data[2] ^= 0x1
// flip a bit in additional data
iv[2] ^= 0x1
if _, err := k1.AuthenticatedDecrypt(ciphertext, data, iv); err == nil {
t.Fatal("Decryption did not fail on IV alteration")
}
// undo bit flip in data
iv[2] ^= 0x1
if _, err := NewSymmetricKey().AuthenticatedDecrypt(ciphertext, data, iv); err == nil {
t.Fatal("Decryption did not fail with different key")
}
}
func TestDerivation(t *testing.T) {
k1 := NewSymmetricKey()
k11 := k1.DeriveKey(0x01)
if bytes.Equal(k1.Key, k11.Key) {
t.Fatal("Key derivation should lead to different key")
}
plaintext := "test"
data := []byte("extra")
iv := NewIV()
ciphertext := k11.AuthenticatedEncrypt(plaintext, data, iv)
if recovered, err := k11.AuthenticatedDecrypt(ciphertext, data, iv); err != nil || recovered != plaintext {
t.Fatal("Derived key should be usable")
}
if !bytes.Equal(k11.Key, k1.DeriveKey(0x01).Key) {
t.Fatal("Key derivation should be deterministic")
}
if bytes.Equal(k11.Key, k1.DeriveKey(0x02).Key) {
t.Fatal("Key derivation should be dependent on label")
}
}
func TestCombination(t *testing.T) {
k1 := NewSymmetricKey()
k2 := NewSymmetricKey()
k12 := CombineKeys(k1, k2)
plaintext := "test"
data := []byte("extra")
iv := NewIV()
k12.AuthenticatedEncrypt(plaintext, data, iv)
if bytes.Equal(k1.Key, k12.Key) || bytes.Equal(k2.Key, k12.Key) {
t.Fatal("Key combination should produce new key")
}
if !bytes.Equal(k12.Key, CombineKeys(k1, k2).Key) {
t.Fatal("Key derivation should be deterministic")
}
}
// This test vector is specific to AES-GCM and will fail for other algorithms.
func TestVectorAESGCM(t *testing.T) {
SetFixedRandomness(true)
defer SetFixedRandomness(false)
k1 := NewSymmetricKey()
iv := NewIV()
expected, _ := hex.DecodeString("66687AADF862BD776C8FC18B8E9F8E20089714856EE233B3902A591D0D5F2925")
if !bytes.Equal(k1.Key, expected) {
t.Fatal("Key generation failed to match test vector")
}
plaintext := "test"
data := []byte("extra")
ciphertext := k1.AuthenticatedEncrypt(plaintext, data, iv)
expected, _ = hex.DecodeString("D1D96BBF2413638BE50654B2CDA85252D8EC47E1")
if !bytes.Equal(ciphertext, expected) {
t.Fatal("Encryption failed to produce correct test vector")
}
k2 := k1.DeriveKey(0x11)
expected, _ = hex.DecodeString("1FEFFCD1EC39D618EAAFF762A341B0658C4A08FD7B7BE091CD821F3F57B3EDC0")
if !bytes.Equal(k2.Key, expected) {
t.Fatal("Key derivation failed to match test vector")
}
k3 := CombineKeys(k1, k2)
expected, _ = hex.DecodeString("BD4EBCB9AEA251A758ED77FE1E44B32193A741283D351825A2B0A155B85D36E4")
if !bytes.Equal(k3.Key, expected) {
t.Fatal("Key derivation failed to match test vector")
}
}