OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / ssh / cipher.go
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package ssh
6
7 import (
8         "crypto/aes"
9         "crypto/cipher"
10         "crypto/des"
11         "crypto/rc4"
12         "crypto/subtle"
13         "encoding/binary"
14         "errors"
15         "fmt"
16         "hash"
17         "io"
18         "io/ioutil"
19 )
20
21 const (
22         packetSizeMultiple = 16 // TODO(huin) this should be determined by the cipher.
23
24         // RFC 4253 section 6.1 defines a minimum packet size of 32768 that implementations
25         // MUST be able to process (plus a few more kilobytes for padding and mac). The RFC
26         // indicates implementations SHOULD be able to handle larger packet sizes, but then
27         // waffles on about reasonable limits.
28         //
29         // OpenSSH caps their maxPacket at 256kB so we choose to do
30         // the same. maxPacket is also used to ensure that uint32
31         // length fields do not overflow, so it should remain well
32         // below 4G.
33         maxPacket = 256 * 1024
34 )
35
36 // noneCipher implements cipher.Stream and provides no encryption. It is used
37 // by the transport before the first key-exchange.
38 type noneCipher struct{}
39
40 func (c noneCipher) XORKeyStream(dst, src []byte) {
41         copy(dst, src)
42 }
43
44 func newAESCTR(key, iv []byte) (cipher.Stream, error) {
45         c, err := aes.NewCipher(key)
46         if err != nil {
47                 return nil, err
48         }
49         return cipher.NewCTR(c, iv), nil
50 }
51
52 func newRC4(key, iv []byte) (cipher.Stream, error) {
53         return rc4.NewCipher(key)
54 }
55
56 type streamCipherMode struct {
57         keySize    int
58         ivSize     int
59         skip       int
60         createFunc func(key, iv []byte) (cipher.Stream, error)
61 }
62
63 func (c *streamCipherMode) createStream(key, iv []byte) (cipher.Stream, error) {
64         if len(key) < c.keySize {
65                 panic("ssh: key length too small for cipher")
66         }
67         if len(iv) < c.ivSize {
68                 panic("ssh: iv too small for cipher")
69         }
70
71         stream, err := c.createFunc(key[:c.keySize], iv[:c.ivSize])
72         if err != nil {
73                 return nil, err
74         }
75
76         var streamDump []byte
77         if c.skip > 0 {
78                 streamDump = make([]byte, 512)
79         }
80
81         for remainingToDump := c.skip; remainingToDump > 0; {
82                 dumpThisTime := remainingToDump
83                 if dumpThisTime > len(streamDump) {
84                         dumpThisTime = len(streamDump)
85                 }
86                 stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
87                 remainingToDump -= dumpThisTime
88         }
89
90         return stream, nil
91 }
92
93 // cipherModes documents properties of supported ciphers. Ciphers not included
94 // are not supported and will not be negotiated, even if explicitly requested in
95 // ClientConfig.Crypto.Ciphers.
96 var cipherModes = map[string]*streamCipherMode{
97         // Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
98         // are defined in the order specified in the RFC.
99         "aes128-ctr": {16, aes.BlockSize, 0, newAESCTR},
100         "aes192-ctr": {24, aes.BlockSize, 0, newAESCTR},
101         "aes256-ctr": {32, aes.BlockSize, 0, newAESCTR},
102
103         // Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
104         // They are defined in the order specified in the RFC.
105         "arcfour128": {16, 0, 1536, newRC4},
106         "arcfour256": {32, 0, 1536, newRC4},
107
108         // Cipher defined in RFC 4253, which describes SSH Transport Layer Protocol.
109         // Note that this cipher is not safe, as stated in RFC 4253: "Arcfour (and
110         // RC4) has problems with weak keys, and should be used with caution."
111         // RFC4345 introduces improved versions of Arcfour.
112         "arcfour": {16, 0, 0, newRC4},
113
114         // AES-GCM is not a stream cipher, so it is constructed with a
115         // special case. If we add any more non-stream ciphers, we
116         // should invest a cleaner way to do this.
117         gcmCipherID: {16, 12, 0, nil},
118
119         // CBC mode is insecure and so is not included in the default config.
120         // (See http://www.isg.rhul.ac.uk/~kp/SandPfinal.pdf). If absolutely
121         // needed, it's possible to specify a custom Config to enable it.
122         // You should expect that an active attacker can recover plaintext if
123         // you do.
124         aes128cbcID: {16, aes.BlockSize, 0, nil},
125
126         // 3des-cbc is insecure and is disabled by default.
127         tripledescbcID: {24, des.BlockSize, 0, nil},
128 }
129
130 // prefixLen is the length of the packet prefix that contains the packet length
131 // and number of padding bytes.
132 const prefixLen = 5
133
134 // streamPacketCipher is a packetCipher using a stream cipher.
135 type streamPacketCipher struct {
136         mac    hash.Hash
137         cipher cipher.Stream
138         etm    bool
139
140         // The following members are to avoid per-packet allocations.
141         prefix      [prefixLen]byte
142         seqNumBytes [4]byte
143         padding     [2 * packetSizeMultiple]byte
144         packetData  []byte
145         macResult   []byte
146 }
147
148 // readPacket reads and decrypt a single packet from the reader argument.
149 func (s *streamPacketCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
150         if _, err := io.ReadFull(r, s.prefix[:]); err != nil {
151                 return nil, err
152         }
153
154         var encryptedPaddingLength [1]byte
155         if s.mac != nil && s.etm {
156                 copy(encryptedPaddingLength[:], s.prefix[4:5])
157                 s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
158         } else {
159                 s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
160         }
161
162         length := binary.BigEndian.Uint32(s.prefix[0:4])
163         paddingLength := uint32(s.prefix[4])
164
165         var macSize uint32
166         if s.mac != nil {
167                 s.mac.Reset()
168                 binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
169                 s.mac.Write(s.seqNumBytes[:])
170                 if s.etm {
171                         s.mac.Write(s.prefix[:4])
172                         s.mac.Write(encryptedPaddingLength[:])
173                 } else {
174                         s.mac.Write(s.prefix[:])
175                 }
176                 macSize = uint32(s.mac.Size())
177         }
178
179         if length <= paddingLength+1 {
180                 return nil, errors.New("ssh: invalid packet length, packet too small")
181         }
182
183         if length > maxPacket {
184                 return nil, errors.New("ssh: invalid packet length, packet too large")
185         }
186
187         // the maxPacket check above ensures that length-1+macSize
188         // does not overflow.
189         if uint32(cap(s.packetData)) < length-1+macSize {
190                 s.packetData = make([]byte, length-1+macSize)
191         } else {
192                 s.packetData = s.packetData[:length-1+macSize]
193         }
194
195         if _, err := io.ReadFull(r, s.packetData); err != nil {
196                 return nil, err
197         }
198         mac := s.packetData[length-1:]
199         data := s.packetData[:length-1]
200
201         if s.mac != nil && s.etm {
202                 s.mac.Write(data)
203         }
204
205         s.cipher.XORKeyStream(data, data)
206
207         if s.mac != nil {
208                 if !s.etm {
209                         s.mac.Write(data)
210                 }
211                 s.macResult = s.mac.Sum(s.macResult[:0])
212                 if subtle.ConstantTimeCompare(s.macResult, mac) != 1 {
213                         return nil, errors.New("ssh: MAC failure")
214                 }
215         }
216
217         return s.packetData[:length-paddingLength-1], nil
218 }
219
220 // writePacket encrypts and sends a packet of data to the writer argument
221 func (s *streamPacketCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
222         if len(packet) > maxPacket {
223                 return errors.New("ssh: packet too large")
224         }
225
226         aadlen := 0
227         if s.mac != nil && s.etm {
228                 // packet length is not encrypted for EtM modes
229                 aadlen = 4
230         }
231
232         paddingLength := packetSizeMultiple - (prefixLen+len(packet)-aadlen)%packetSizeMultiple
233         if paddingLength < 4 {
234                 paddingLength += packetSizeMultiple
235         }
236
237         length := len(packet) + 1 + paddingLength
238         binary.BigEndian.PutUint32(s.prefix[:], uint32(length))
239         s.prefix[4] = byte(paddingLength)
240         padding := s.padding[:paddingLength]
241         if _, err := io.ReadFull(rand, padding); err != nil {
242                 return err
243         }
244
245         if s.mac != nil {
246                 s.mac.Reset()
247                 binary.BigEndian.PutUint32(s.seqNumBytes[:], seqNum)
248                 s.mac.Write(s.seqNumBytes[:])
249
250                 if s.etm {
251                         // For EtM algorithms, the packet length must stay unencrypted,
252                         // but the following data (padding length) must be encrypted
253                         s.cipher.XORKeyStream(s.prefix[4:5], s.prefix[4:5])
254                 }
255
256                 s.mac.Write(s.prefix[:])
257
258                 if !s.etm {
259                         // For non-EtM algorithms, the algorithm is applied on unencrypted data
260                         s.mac.Write(packet)
261                         s.mac.Write(padding)
262                 }
263         }
264
265         if !(s.mac != nil && s.etm) {
266                 // For EtM algorithms, the padding length has already been encrypted
267                 // and the packet length must remain unencrypted
268                 s.cipher.XORKeyStream(s.prefix[:], s.prefix[:])
269         }
270
271         s.cipher.XORKeyStream(packet, packet)
272         s.cipher.XORKeyStream(padding, padding)
273
274         if s.mac != nil && s.etm {
275                 // For EtM algorithms, packet and padding must be encrypted
276                 s.mac.Write(packet)
277                 s.mac.Write(padding)
278         }
279
280         if _, err := w.Write(s.prefix[:]); err != nil {
281                 return err
282         }
283         if _, err := w.Write(packet); err != nil {
284                 return err
285         }
286         if _, err := w.Write(padding); err != nil {
287                 return err
288         }
289
290         if s.mac != nil {
291                 s.macResult = s.mac.Sum(s.macResult[:0])
292                 if _, err := w.Write(s.macResult); err != nil {
293                         return err
294                 }
295         }
296
297         return nil
298 }
299
300 type gcmCipher struct {
301         aead   cipher.AEAD
302         prefix [4]byte
303         iv     []byte
304         buf    []byte
305 }
306
307 func newGCMCipher(iv, key, macKey []byte) (packetCipher, error) {
308         c, err := aes.NewCipher(key)
309         if err != nil {
310                 return nil, err
311         }
312
313         aead, err := cipher.NewGCM(c)
314         if err != nil {
315                 return nil, err
316         }
317
318         return &gcmCipher{
319                 aead: aead,
320                 iv:   iv,
321         }, nil
322 }
323
324 const gcmTagSize = 16
325
326 func (c *gcmCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
327         // Pad out to multiple of 16 bytes. This is different from the
328         // stream cipher because that encrypts the length too.
329         padding := byte(packetSizeMultiple - (1+len(packet))%packetSizeMultiple)
330         if padding < 4 {
331                 padding += packetSizeMultiple
332         }
333
334         length := uint32(len(packet) + int(padding) + 1)
335         binary.BigEndian.PutUint32(c.prefix[:], length)
336         if _, err := w.Write(c.prefix[:]); err != nil {
337                 return err
338         }
339
340         if cap(c.buf) < int(length) {
341                 c.buf = make([]byte, length)
342         } else {
343                 c.buf = c.buf[:length]
344         }
345
346         c.buf[0] = padding
347         copy(c.buf[1:], packet)
348         if _, err := io.ReadFull(rand, c.buf[1+len(packet):]); err != nil {
349                 return err
350         }
351         c.buf = c.aead.Seal(c.buf[:0], c.iv, c.buf, c.prefix[:])
352         if _, err := w.Write(c.buf); err != nil {
353                 return err
354         }
355         c.incIV()
356
357         return nil
358 }
359
360 func (c *gcmCipher) incIV() {
361         for i := 4 + 7; i >= 4; i-- {
362                 c.iv[i]++
363                 if c.iv[i] != 0 {
364                         break
365                 }
366         }
367 }
368
369 func (c *gcmCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
370         if _, err := io.ReadFull(r, c.prefix[:]); err != nil {
371                 return nil, err
372         }
373         length := binary.BigEndian.Uint32(c.prefix[:])
374         if length > maxPacket {
375                 return nil, errors.New("ssh: max packet length exceeded.")
376         }
377
378         if cap(c.buf) < int(length+gcmTagSize) {
379                 c.buf = make([]byte, length+gcmTagSize)
380         } else {
381                 c.buf = c.buf[:length+gcmTagSize]
382         }
383
384         if _, err := io.ReadFull(r, c.buf); err != nil {
385                 return nil, err
386         }
387
388         plain, err := c.aead.Open(c.buf[:0], c.iv, c.buf, c.prefix[:])
389         if err != nil {
390                 return nil, err
391         }
392         c.incIV()
393
394         padding := plain[0]
395         if padding < 4 {
396                 // padding is a byte, so it automatically satisfies
397                 // the maximum size, which is 255.
398                 return nil, fmt.Errorf("ssh: illegal padding %d", padding)
399         }
400
401         if int(padding+1) >= len(plain) {
402                 return nil, fmt.Errorf("ssh: padding %d too large", padding)
403         }
404         plain = plain[1 : length-uint32(padding)]
405         return plain, nil
406 }
407
408 // cbcCipher implements aes128-cbc cipher defined in RFC 4253 section 6.1
409 type cbcCipher struct {
410         mac       hash.Hash
411         macSize   uint32
412         decrypter cipher.BlockMode
413         encrypter cipher.BlockMode
414
415         // The following members are to avoid per-packet allocations.
416         seqNumBytes [4]byte
417         packetData  []byte
418         macResult   []byte
419
420         // Amount of data we should still read to hide which
421         // verification error triggered.
422         oracleCamouflage uint32
423 }
424
425 func newCBCCipher(c cipher.Block, iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
426         cbc := &cbcCipher{
427                 mac:        macModes[algs.MAC].new(macKey),
428                 decrypter:  cipher.NewCBCDecrypter(c, iv),
429                 encrypter:  cipher.NewCBCEncrypter(c, iv),
430                 packetData: make([]byte, 1024),
431         }
432         if cbc.mac != nil {
433                 cbc.macSize = uint32(cbc.mac.Size())
434         }
435
436         return cbc, nil
437 }
438
439 func newAESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
440         c, err := aes.NewCipher(key)
441         if err != nil {
442                 return nil, err
443         }
444
445         cbc, err := newCBCCipher(c, iv, key, macKey, algs)
446         if err != nil {
447                 return nil, err
448         }
449
450         return cbc, nil
451 }
452
453 func newTripleDESCBCCipher(iv, key, macKey []byte, algs directionAlgorithms) (packetCipher, error) {
454         c, err := des.NewTripleDESCipher(key)
455         if err != nil {
456                 return nil, err
457         }
458
459         cbc, err := newCBCCipher(c, iv, key, macKey, algs)
460         if err != nil {
461                 return nil, err
462         }
463
464         return cbc, nil
465 }
466
467 func maxUInt32(a, b int) uint32 {
468         if a > b {
469                 return uint32(a)
470         }
471         return uint32(b)
472 }
473
474 const (
475         cbcMinPacketSizeMultiple = 8
476         cbcMinPacketSize         = 16
477         cbcMinPaddingSize        = 4
478 )
479
480 // cbcError represents a verification error that may leak information.
481 type cbcError string
482
483 func (e cbcError) Error() string { return string(e) }
484
485 func (c *cbcCipher) readPacket(seqNum uint32, r io.Reader) ([]byte, error) {
486         p, err := c.readPacketLeaky(seqNum, r)
487         if err != nil {
488                 if _, ok := err.(cbcError); ok {
489                         // Verification error: read a fixed amount of
490                         // data, to make distinguishing between
491                         // failing MAC and failing length check more
492                         // difficult.
493                         io.CopyN(ioutil.Discard, r, int64(c.oracleCamouflage))
494                 }
495         }
496         return p, err
497 }
498
499 func (c *cbcCipher) readPacketLeaky(seqNum uint32, r io.Reader) ([]byte, error) {
500         blockSize := c.decrypter.BlockSize()
501
502         // Read the header, which will include some of the subsequent data in the
503         // case of block ciphers - this is copied back to the payload later.
504         // How many bytes of payload/padding will be read with this first read.
505         firstBlockLength := uint32((prefixLen + blockSize - 1) / blockSize * blockSize)
506         firstBlock := c.packetData[:firstBlockLength]
507         if _, err := io.ReadFull(r, firstBlock); err != nil {
508                 return nil, err
509         }
510
511         c.oracleCamouflage = maxPacket + 4 + c.macSize - firstBlockLength
512
513         c.decrypter.CryptBlocks(firstBlock, firstBlock)
514         length := binary.BigEndian.Uint32(firstBlock[:4])
515         if length > maxPacket {
516                 return nil, cbcError("ssh: packet too large")
517         }
518         if length+4 < maxUInt32(cbcMinPacketSize, blockSize) {
519                 // The minimum size of a packet is 16 (or the cipher block size, whichever
520                 // is larger) bytes.
521                 return nil, cbcError("ssh: packet too small")
522         }
523         // The length of the packet (including the length field but not the MAC) must
524         // be a multiple of the block size or 8, whichever is larger.
525         if (length+4)%maxUInt32(cbcMinPacketSizeMultiple, blockSize) != 0 {
526                 return nil, cbcError("ssh: invalid packet length multiple")
527         }
528
529         paddingLength := uint32(firstBlock[4])
530         if paddingLength < cbcMinPaddingSize || length <= paddingLength+1 {
531                 return nil, cbcError("ssh: invalid packet length")
532         }
533
534         // Positions within the c.packetData buffer:
535         macStart := 4 + length
536         paddingStart := macStart - paddingLength
537
538         // Entire packet size, starting before length, ending at end of mac.
539         entirePacketSize := macStart + c.macSize
540
541         // Ensure c.packetData is large enough for the entire packet data.
542         if uint32(cap(c.packetData)) < entirePacketSize {
543                 // Still need to upsize and copy, but this should be rare at runtime, only
544                 // on upsizing the packetData buffer.
545                 c.packetData = make([]byte, entirePacketSize)
546                 copy(c.packetData, firstBlock)
547         } else {
548                 c.packetData = c.packetData[:entirePacketSize]
549         }
550
551         if n, err := io.ReadFull(r, c.packetData[firstBlockLength:]); err != nil {
552                 return nil, err
553         } else {
554                 c.oracleCamouflage -= uint32(n)
555         }
556
557         remainingCrypted := c.packetData[firstBlockLength:macStart]
558         c.decrypter.CryptBlocks(remainingCrypted, remainingCrypted)
559
560         mac := c.packetData[macStart:]
561         if c.mac != nil {
562                 c.mac.Reset()
563                 binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
564                 c.mac.Write(c.seqNumBytes[:])
565                 c.mac.Write(c.packetData[:macStart])
566                 c.macResult = c.mac.Sum(c.macResult[:0])
567                 if subtle.ConstantTimeCompare(c.macResult, mac) != 1 {
568                         return nil, cbcError("ssh: MAC failure")
569                 }
570         }
571
572         return c.packetData[prefixLen:paddingStart], nil
573 }
574
575 func (c *cbcCipher) writePacket(seqNum uint32, w io.Writer, rand io.Reader, packet []byte) error {
576         effectiveBlockSize := maxUInt32(cbcMinPacketSizeMultiple, c.encrypter.BlockSize())
577
578         // Length of encrypted portion of the packet (header, payload, padding).
579         // Enforce minimum padding and packet size.
580         encLength := maxUInt32(prefixLen+len(packet)+cbcMinPaddingSize, cbcMinPaddingSize)
581         // Enforce block size.
582         encLength = (encLength + effectiveBlockSize - 1) / effectiveBlockSize * effectiveBlockSize
583
584         length := encLength - 4
585         paddingLength := int(length) - (1 + len(packet))
586
587         // Overall buffer contains: header, payload, padding, mac.
588         // Space for the MAC is reserved in the capacity but not the slice length.
589         bufferSize := encLength + c.macSize
590         if uint32(cap(c.packetData)) < bufferSize {
591                 c.packetData = make([]byte, encLength, bufferSize)
592         } else {
593                 c.packetData = c.packetData[:encLength]
594         }
595
596         p := c.packetData
597
598         // Packet header.
599         binary.BigEndian.PutUint32(p, length)
600         p = p[4:]
601         p[0] = byte(paddingLength)
602
603         // Payload.
604         p = p[1:]
605         copy(p, packet)
606
607         // Padding.
608         p = p[len(packet):]
609         if _, err := io.ReadFull(rand, p); err != nil {
610                 return err
611         }
612
613         if c.mac != nil {
614                 c.mac.Reset()
615                 binary.BigEndian.PutUint32(c.seqNumBytes[:], seqNum)
616                 c.mac.Write(c.seqNumBytes[:])
617                 c.mac.Write(c.packetData)
618                 // The MAC is now appended into the capacity reserved for it earlier.
619                 c.packetData = c.mac.Sum(c.packetData)
620         }
621
622         c.encrypter.CryptBlocks(c.packetData[:encLength], c.packetData[:encLength])
623
624         if _, err := w.Write(c.packetData); err != nil {
625                 return err
626         }
627
628         return nil
629 }