github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/crypto/tls/cipher_suites.go (about)

     1  // Copyright 2010 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 tls
     6  
     7  import (
     8  	"crypto/aes"
     9  	"crypto/cipher"
    10  	"crypto/des"
    11  	"crypto/hmac"
    12  	"crypto/rc4"
    13  	"crypto/sha1"
    14  	"crypto/x509"
    15  	"hash"
    16  )
    17  
    18  // a keyAgreement implements the client and server side of a TLS key agreement
    19  // protocol by generating and processing key exchange messages.
    20  type keyAgreement interface {
    21  	// On the server side, the first two methods are called in order.
    22  
    23  	// In the case that the key agreement protocol doesn't use a
    24  	// ServerKeyExchange message, generateServerKeyExchange can return nil,
    25  	// nil.
    26  	generateServerKeyExchange(*Config, *Certificate, *clientHelloMsg, *serverHelloMsg) (*serverKeyExchangeMsg, error)
    27  	processClientKeyExchange(*Config, *Certificate, *clientKeyExchangeMsg, uint16) ([]byte, error)
    28  
    29  	// On the client side, the next two methods are called in order.
    30  
    31  	// This method may not be called if the server doesn't send a
    32  	// ServerKeyExchange message.
    33  	processServerKeyExchange(*Config, *clientHelloMsg, *serverHelloMsg, *x509.Certificate, *serverKeyExchangeMsg) error
    34  	generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate) ([]byte, *clientKeyExchangeMsg, error)
    35  }
    36  
    37  // A cipherSuite is a specific combination of key agreement, cipher and MAC
    38  // function. All cipher suites currently assume RSA key agreement.
    39  type cipherSuite struct {
    40  	id uint16
    41  	// the lengths, in bytes, of the key material needed for each component.
    42  	keyLen int
    43  	macLen int
    44  	ivLen  int
    45  	ka     func() keyAgreement
    46  	// If elliptic is set, a server will only consider this ciphersuite if
    47  	// the ClientHello indicated that the client supports an elliptic curve
    48  	// and point format that we can handle.
    49  	elliptic bool
    50  	cipher   func(key, iv []byte, isRead bool) interface{}
    51  	mac      func(version uint16, macKey []byte) macFunction
    52  }
    53  
    54  var cipherSuites = []*cipherSuite{
    55  	{TLS_RSA_WITH_RC4_128_SHA, 16, 20, 0, rsaKA, false, cipherRC4, macSHA1},
    56  	{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, false, cipher3DES, macSHA1},
    57  	{TLS_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, rsaKA, false, cipherAES, macSHA1},
    58  	{TLS_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, rsaKA, false, cipherAES, macSHA1},
    59  	{TLS_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
    60  	{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
    61  	{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
    62  	{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
    63  }
    64  
    65  func cipherRC4(key, iv []byte, isRead bool) interface{} {
    66  	cipher, _ := rc4.NewCipher(key)
    67  	return cipher
    68  }
    69  
    70  func cipher3DES(key, iv []byte, isRead bool) interface{} {
    71  	block, _ := des.NewTripleDESCipher(key)
    72  	if isRead {
    73  		return cipher.NewCBCDecrypter(block, iv)
    74  	}
    75  	return cipher.NewCBCEncrypter(block, iv)
    76  }
    77  
    78  func cipherAES(key, iv []byte, isRead bool) interface{} {
    79  	block, _ := aes.NewCipher(key)
    80  	if isRead {
    81  		return cipher.NewCBCDecrypter(block, iv)
    82  	}
    83  	return cipher.NewCBCEncrypter(block, iv)
    84  }
    85  
    86  // macSHA1 returns a macFunction for the given protocol version.
    87  func macSHA1(version uint16, key []byte) macFunction {
    88  	if version == versionSSL30 {
    89  		mac := ssl30MAC{
    90  			h:   sha1.New(),
    91  			key: make([]byte, len(key)),
    92  		}
    93  		copy(mac.key, key)
    94  		return mac
    95  	}
    96  	return tls10MAC{hmac.New(sha1.New, key)}
    97  }
    98  
    99  type macFunction interface {
   100  	Size() int
   101  	MAC(digestBuf, seq, data []byte) []byte
   102  }
   103  
   104  // ssl30MAC implements the SSLv3 MAC function, as defined in
   105  // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
   106  type ssl30MAC struct {
   107  	h   hash.Hash
   108  	key []byte
   109  }
   110  
   111  func (s ssl30MAC) Size() int {
   112  	return s.h.Size()
   113  }
   114  
   115  var ssl30Pad1 = [48]byte{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36}
   116  
   117  var ssl30Pad2 = [48]byte{0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c}
   118  
   119  func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte {
   120  	padLength := 48
   121  	if s.h.Size() == 20 {
   122  		padLength = 40
   123  	}
   124  
   125  	s.h.Reset()
   126  	s.h.Write(s.key)
   127  	s.h.Write(ssl30Pad1[:padLength])
   128  	s.h.Write(seq)
   129  	s.h.Write(record[:1])
   130  	s.h.Write(record[3:5])
   131  	s.h.Write(record[recordHeaderLen:])
   132  	digestBuf = s.h.Sum(digestBuf[:0])
   133  
   134  	s.h.Reset()
   135  	s.h.Write(s.key)
   136  	s.h.Write(ssl30Pad2[:padLength])
   137  	s.h.Write(digestBuf)
   138  	return s.h.Sum(digestBuf[:0])
   139  }
   140  
   141  // tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
   142  type tls10MAC struct {
   143  	h hash.Hash
   144  }
   145  
   146  func (s tls10MAC) Size() int {
   147  	return s.h.Size()
   148  }
   149  
   150  func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte {
   151  	s.h.Reset()
   152  	s.h.Write(seq)
   153  	s.h.Write(record)
   154  	return s.h.Sum(digestBuf[:0])
   155  }
   156  
   157  func rsaKA() keyAgreement {
   158  	return rsaKeyAgreement{}
   159  }
   160  
   161  func ecdheRSAKA() keyAgreement {
   162  	return new(ecdheRSAKeyAgreement)
   163  }
   164  
   165  // mutualCipherSuite returns a cipherSuite given a list of supported
   166  // ciphersuites and the id requested by the peer.
   167  func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
   168  	for _, id := range have {
   169  		if id == want {
   170  			for _, suite := range cipherSuites {
   171  				if suite.id == want {
   172  					return suite
   173  				}
   174  			}
   175  			return nil
   176  		}
   177  	}
   178  	return nil
   179  }
   180  
   181  // A list of the possible cipher suite ids. Taken from
   182  // http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
   183  const (
   184  	TLS_RSA_WITH_RC4_128_SHA            uint16 = 0x0005
   185  	TLS_RSA_WITH_3DES_EDE_CBC_SHA       uint16 = 0x000a
   186  	TLS_RSA_WITH_AES_128_CBC_SHA        uint16 = 0x002f
   187  	TLS_RSA_WITH_AES_256_CBC_SHA        uint16 = 0x0035
   188  	TLS_ECDHE_RSA_WITH_RC4_128_SHA      uint16 = 0xc011
   189  	TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
   190  	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA  uint16 = 0xc013
   191  	TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA  uint16 = 0xc014
   192  )