1
2
3
4
5 package fipstest
6
7 import (
8 "bytes"
9 "crypto/internal/cryptotest"
10 "crypto/internal/fips140/aes"
11 "crypto/internal/fips140/aes/gcm"
12 "crypto/internal/fips140/drbg"
13 "crypto/internal/fips140/sha3"
14 "encoding/hex"
15 "runtime"
16 "testing"
17 )
18
19 func TestXAESAllocations(t *testing.T) {
20 if runtime.GOARCH == "ppc64" || runtime.GOARCH == "ppc64le" {
21 t.Skip("Test reports non-zero allocation count. See issue #70448")
22 }
23 cryptotest.SkipTestAllocations(t)
24 if allocs := testing.AllocsPerRun(10, func() {
25 key := make([]byte, 32)
26 nonce := make([]byte, 24)
27 plaintext := make([]byte, 16)
28 aad := make([]byte, 16)
29 ciphertext := make([]byte, 0, 16+16)
30 ciphertext = xaesSeal(ciphertext, key, nonce, plaintext, aad)
31 if _, err := xaesOpen(plaintext[:0], key, nonce, ciphertext, aad); err != nil {
32 t.Fatal(err)
33 }
34 }); allocs > 0 {
35 t.Errorf("expected zero allocations, got %0.1f", allocs)
36 }
37 }
38
39 func TestXAES(t *testing.T) {
40 key := bytes.Repeat([]byte{0x01}, 32)
41 plaintext := []byte("XAES-256-GCM")
42 additionalData := []byte("c2sp.org/XAES-256-GCM")
43
44 nonce := make([]byte, 24)
45 ciphertext := make([]byte, len(plaintext)+16)
46
47 drbg.Read(nonce[:12])
48 c, _ := aes.New(key)
49 k := gcm.NewCounterKDF(c).DeriveKey(0x58, [12]byte(nonce))
50 a, _ := aes.New(k[:])
51 g, _ := gcm.New(a, 12, 16)
52 gcm.SealWithRandomNonce(g, nonce[12:], ciphertext, plaintext, additionalData)
53
54 got, err := xaesOpen(nil, key, nonce, ciphertext, additionalData)
55 if err != nil {
56 t.Fatal(err)
57 }
58 if !bytes.Equal(plaintext, got) {
59 t.Errorf("plaintext and got are not equal")
60 }
61 }
62
63
64
65
66
67
68
69
70 func xaesSeal(dst, key, nonce, plaintext, additionalData []byte) []byte {
71 c, _ := aes.New(key)
72 k := gcm.NewCounterKDF(c).DeriveKey(0x58, [12]byte(nonce))
73 n := nonce[12:]
74 a, _ := aes.New(k[:])
75 g, _ := gcm.New(a, 12, 16)
76 return g.Seal(dst, n, plaintext, additionalData)
77 }
78
79 func xaesOpen(dst, key, nonce, ciphertext, additionalData []byte) ([]byte, error) {
80 c, _ := aes.New(key)
81 k := gcm.NewCounterKDF(c).DeriveKey(0x58, [12]byte(nonce))
82 n := nonce[12:]
83 a, _ := aes.New(k[:])
84 g, _ := gcm.New(a, 12, 16)
85 return g.Open(dst, n, ciphertext, additionalData)
86 }
87
88 func TestXAESVectors(t *testing.T) {
89 key := bytes.Repeat([]byte{0x01}, 32)
90 nonce := []byte("ABCDEFGHIJKLMNOPQRSTUVWX")
91 plaintext := []byte("XAES-256-GCM")
92 ciphertext := xaesSeal(nil, key, nonce, plaintext, nil)
93 expected := "ce546ef63c9cc60765923609b33a9a1974e96e52daf2fcf7075e2271"
94 if got := hex.EncodeToString(ciphertext); got != expected {
95 t.Errorf("got: %s", got)
96 }
97 if decrypted, err := xaesOpen(nil, key, nonce, ciphertext, nil); err != nil {
98 t.Fatal(err)
99 } else if !bytes.Equal(plaintext, decrypted) {
100 t.Errorf("plaintext and decrypted are not equal")
101 }
102
103 key = bytes.Repeat([]byte{0x03}, 32)
104 aad := []byte("c2sp.org/XAES-256-GCM")
105 ciphertext = xaesSeal(nil, key, nonce, plaintext, aad)
106 expected = "986ec1832593df5443a179437fd083bf3fdb41abd740a21f71eb769d"
107 if got := hex.EncodeToString(ciphertext); got != expected {
108 t.Errorf("got: %s", got)
109 }
110 if decrypted, err := xaesOpen(nil, key, nonce, ciphertext, aad); err != nil {
111 t.Fatal(err)
112 } else if !bytes.Equal(plaintext, decrypted) {
113 t.Errorf("plaintext and decrypted are not equal")
114 }
115 }
116
117 func TestXAESAccumulated(t *testing.T) {
118 iterations := 10_000
119 expected := "e6b9edf2df6cec60c8cbd864e2211b597fb69a529160cd040d56c0c210081939"
120
121 s, d := sha3.NewShake128(), sha3.NewShake128()
122 for i := 0; i < iterations; i++ {
123 key := make([]byte, 32)
124 s.Read(key)
125 nonce := make([]byte, 24)
126 s.Read(nonce)
127 lenByte := make([]byte, 1)
128 s.Read(lenByte)
129 plaintext := make([]byte, int(lenByte[0]))
130 s.Read(plaintext)
131 s.Read(lenByte)
132 aad := make([]byte, int(lenByte[0]))
133 s.Read(aad)
134
135 ciphertext := xaesSeal(nil, key, nonce, plaintext, aad)
136 decrypted, err := xaesOpen(nil, key, nonce, ciphertext, aad)
137 if err != nil {
138 t.Fatal(err)
139 }
140 if !bytes.Equal(plaintext, decrypted) {
141 t.Errorf("plaintext and decrypted are not equal")
142 }
143
144 d.Write(ciphertext)
145 }
146 if got := hex.EncodeToString(d.Sum(nil)); got != expected {
147 t.Errorf("got: %s", got)
148 }
149 }
150
View as plain text