@@ -8,7 +8,12 @@ import (
8
8
"bytes"
9
9
"crypto"
10
10
"crypto/rand"
11
+ "encoding/binary"
12
+ "io"
11
13
"testing"
14
+
15
+ "golang.org/x/crypto/chacha20"
16
+ "golang.org/x/crypto/internal/poly1305"
12
17
)
13
18
14
19
func TestDefaultCiphersExist (t * testing.T ) {
@@ -129,3 +134,98 @@ func TestCBCOracleCounterMeasure(t *testing.T) {
129
134
lastRead = bytesRead
130
135
}
131
136
}
137
+
138
+ func TestCVE202143565 (t * testing.T ) {
139
+ tests := []struct {
140
+ cipher string
141
+ constructPacket func (packetCipher ) io.Reader
142
+ }{
143
+ {
144
+ cipher : gcmCipherID ,
145
+ constructPacket : func (client packetCipher ) io.Reader {
146
+ internalCipher := client .(* gcmCipher )
147
+ b := & bytes.Buffer {}
148
+ prefix := [4 ]byte {}
149
+ if _ , err := b .Write (prefix [:]); err != nil {
150
+ t .Fatal (err )
151
+ }
152
+ internalCipher .buf = internalCipher .aead .Seal (internalCipher .buf [:0 ], internalCipher .iv , []byte {}, prefix [:])
153
+ if _ , err := b .Write (internalCipher .buf ); err != nil {
154
+ t .Fatal (err )
155
+ }
156
+ internalCipher .incIV ()
157
+
158
+ return b
159
+ },
160
+ },
161
+ {
162
+ cipher : chacha20Poly1305ID ,
163
+ constructPacket : func (client packetCipher ) io.Reader {
164
+ internalCipher := client .(* chacha20Poly1305Cipher )
165
+ b := & bytes.Buffer {}
166
+
167
+ nonce := make ([]byte , 12 )
168
+ s , err := chacha20 .NewUnauthenticatedCipher (internalCipher .contentKey [:], nonce )
169
+ if err != nil {
170
+ t .Fatal (err )
171
+ }
172
+ var polyKey , discardBuf [32 ]byte
173
+ s .XORKeyStream (polyKey [:], polyKey [:])
174
+ s .XORKeyStream (discardBuf [:], discardBuf [:]) // skip the next 32 bytes
175
+
176
+ internalCipher .buf = make ([]byte , 4 + poly1305 .TagSize )
177
+ binary .BigEndian .PutUint32 (internalCipher .buf , 0 )
178
+ ls , err := chacha20 .NewUnauthenticatedCipher (internalCipher .lengthKey [:], nonce )
179
+ if err != nil {
180
+ t .Fatal (err )
181
+ }
182
+ ls .XORKeyStream (internalCipher .buf , internalCipher .buf [:4 ])
183
+ if _ , err := io .ReadFull (rand .Reader , internalCipher .buf [4 :4 ]); err != nil {
184
+ t .Fatal (err )
185
+ }
186
+
187
+ s .XORKeyStream (internalCipher .buf [4 :], internalCipher .buf [4 :4 ])
188
+
189
+ var tag [poly1305 .TagSize ]byte
190
+ poly1305 .Sum (& tag , internalCipher .buf [:4 ], & polyKey )
191
+
192
+ copy (internalCipher .buf [4 :], tag [:])
193
+
194
+ if _ , err := b .Write (internalCipher .buf ); err != nil {
195
+ t .Fatal (err )
196
+ }
197
+
198
+ return b
199
+ },
200
+ },
201
+ }
202
+
203
+ for _ , tc := range tests {
204
+ mac := "hmac-sha2-256"
205
+
206
+ kr := & kexResult {Hash : crypto .SHA1 }
207
+ algs := directionAlgorithms {
208
+ Cipher : tc .cipher ,
209
+ MAC : mac ,
210
+ Compression : "none" ,
211
+ }
212
+ client , err := newPacketCipher (clientKeys , algs , kr )
213
+ if err != nil {
214
+ t .Fatalf ("newPacketCipher(client, %q, %q): %v" , tc .cipher , mac , err )
215
+ }
216
+ server , err := newPacketCipher (clientKeys , algs , kr )
217
+ if err != nil {
218
+ t .Fatalf ("newPacketCipher(client, %q, %q): %v" , tc .cipher , mac , err )
219
+ }
220
+
221
+ b := tc .constructPacket (client )
222
+
223
+ wantErr := "ssh: empty packet"
224
+ _ , err = server .readCipherPacket (0 , b )
225
+ if err == nil {
226
+ t .Fatalf ("readCipherPacket(%q, %q): didn't fail with empty packet" , tc .cipher , mac )
227
+ } else if err .Error () != wantErr {
228
+ t .Fatalf ("readCipherPacket(%q, %q): unexpected error, got %q, want %q" , tc .cipher , mac , err , wantErr )
229
+ }
230
+ }
231
+ }
0 commit comments