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 }