github.com/olivere/camlistore@v0.0.0-20140121221811-1b7ac2da0199/third_party/code.google.com/p/go.crypto/ssh/cipher.go (about)

     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/rc4"
    11  )
    12  
    13  // streamDump is used to dump the initial keystream for stream ciphers. It is a
    14  // a write-only buffer, and not intended for reading so do not require a mutex.
    15  var streamDump [512]byte
    16  
    17  // noneCipher implements cipher.Stream and provides no encryption. It is used
    18  // by the transport before the first key-exchange.
    19  type noneCipher struct{}
    20  
    21  func (c noneCipher) XORKeyStream(dst, src []byte) {
    22  	copy(dst, src)
    23  }
    24  
    25  func newAESCTR(key, iv []byte) (cipher.Stream, error) {
    26  	c, err := aes.NewCipher(key)
    27  	if err != nil {
    28  		return nil, err
    29  	}
    30  	return cipher.NewCTR(c, iv), nil
    31  }
    32  
    33  func newRC4(key, iv []byte) (cipher.Stream, error) {
    34  	return rc4.NewCipher(key)
    35  }
    36  
    37  type cipherMode struct {
    38  	keySize  int
    39  	ivSize   int
    40  	skip     int
    41  	createFn func(key, iv []byte) (cipher.Stream, error)
    42  }
    43  
    44  func (c *cipherMode) createCipher(key, iv []byte) (cipher.Stream, error) {
    45  	if len(key) < c.keySize {
    46  		panic("ssh: key length too small for cipher")
    47  	}
    48  	if len(iv) < c.ivSize {
    49  		panic("ssh: iv too small for cipher")
    50  	}
    51  
    52  	stream, err := c.createFn(key[:c.keySize], iv[:c.ivSize])
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	for remainingToDump := c.skip; remainingToDump > 0; {
    58  		dumpThisTime := remainingToDump
    59  		if dumpThisTime > len(streamDump) {
    60  			dumpThisTime = len(streamDump)
    61  		}
    62  		stream.XORKeyStream(streamDump[:dumpThisTime], streamDump[:dumpThisTime])
    63  		remainingToDump -= dumpThisTime
    64  	}
    65  
    66  	return stream, nil
    67  }
    68  
    69  // Specifies a default set of ciphers and a preference order. This is based on
    70  // OpenSSH's default client preference order, minus algorithms that are not
    71  // implemented.
    72  var DefaultCipherOrder = []string{
    73  	"aes128-ctr", "aes192-ctr", "aes256-ctr",
    74  	"arcfour256", "arcfour128",
    75  }
    76  
    77  var cipherModes = map[string]*cipherMode{
    78  	// Ciphers from RFC4344, which introduced many CTR-based ciphers. Algorithms
    79  	// are defined in the order specified in the RFC.
    80  	"aes128-ctr": {16, aes.BlockSize, 0, newAESCTR},
    81  	"aes192-ctr": {24, aes.BlockSize, 0, newAESCTR},
    82  	"aes256-ctr": {32, aes.BlockSize, 0, newAESCTR},
    83  
    84  	// Ciphers from RFC4345, which introduces security-improved arcfour ciphers.
    85  	// They are defined in the order specified in the RFC.
    86  	"arcfour128": {16, 0, 1536, newRC4},
    87  	"arcfour256": {32, 0, 1536, newRC4},
    88  }