src/pkg/crypto/tls/cipher_suites.go - The Go Programming Language

Golang

Source file src/pkg/crypto/tls/cipher_suites.go

     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_ECDHE_RSA_WITH_RC4_128_SHA, 16, 20, 0, ecdheRSAKA, true, cipherRC4, macSHA1},
    59		{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, true, cipher3DES, macSHA1},
    60		{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdheRSAKA, true, cipherAES, macSHA1},
    61	}
    62	
    63	func cipherRC4(key, iv []byte, isRead bool) interface{} {
    64		cipher, _ := rc4.NewCipher(key)
    65		return cipher
    66	}
    67	
    68	func cipher3DES(key, iv []byte, isRead bool) interface{} {
    69		block, _ := des.NewTripleDESCipher(key)
    70		if isRead {
    71			return cipher.NewCBCDecrypter(block, iv)
    72		}
    73		return cipher.NewCBCEncrypter(block, iv)
    74	}
    75	
    76	func cipherAES(key, iv []byte, isRead bool) interface{} {
    77		block, _ := aes.NewCipher(key)
    78		if isRead {
    79			return cipher.NewCBCDecrypter(block, iv)
    80		}
    81		return cipher.NewCBCEncrypter(block, iv)
    82	}
    83	
    84	// macSHA1 returns a macFunction for the given protocol version.
    85	func macSHA1(version uint16, key []byte) macFunction {
    86		if version == versionSSL30 {
    87			mac := ssl30MAC{
    88				h:   sha1.New(),
    89				key: make([]byte, len(key)),
    90			}
    91			copy(mac.key, key)
    92			return mac
    93		}
    94		return tls10MAC{hmac.New(sha1.New, key)}
    95	}
    96	
    97	type macFunction interface {
    98		Size() int
    99		MAC(digestBuf, seq, data []byte) []byte
   100	}
   101	
   102	// ssl30MAC implements the SSLv3 MAC function, as defined in
   103	// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 5.2.3.1
   104	type ssl30MAC struct {
   105		h   hash.Hash
   106		key []byte
   107	}
   108	
   109	func (s ssl30MAC) Size() int {
   110		return s.h.Size()
   111	}
   112	
   113	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}
   114	
   115	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}
   116	
   117	func (s ssl30MAC) MAC(digestBuf, seq, record []byte) []byte {
   118		padLength := 48
   119		if s.h.Size() == 20 {
   120			padLength = 40
   121		}
   122	
   123		s.h.Reset()
   124		s.h.Write(s.key)
   125		s.h.Write(ssl30Pad1[:padLength])
   126		s.h.Write(seq)
   127		s.h.Write(record[:1])
   128		s.h.Write(record[3:5])
   129		s.h.Write(record[recordHeaderLen:])
   130		digestBuf = s.h.Sum(digestBuf[:0])
   131	
   132		s.h.Reset()
   133		s.h.Write(s.key)
   134		s.h.Write(ssl30Pad2[:padLength])
   135		s.h.Write(digestBuf)
   136		return s.h.Sum(digestBuf[:0])
   137	}
   138	
   139	// tls10MAC implements the TLS 1.0 MAC function. RFC 2246, section 6.2.3.
   140	type tls10MAC struct {
   141		h hash.Hash
   142	}
   143	
   144	func (s tls10MAC) Size() int {
   145		return s.h.Size()
   146	}
   147	
   148	func (s tls10MAC) MAC(digestBuf, seq, record []byte) []byte {
   149		s.h.Reset()
   150		s.h.Write(seq)
   151		s.h.Write(record)
   152		return s.h.Sum(digestBuf[:0])
   153	}
   154	
   155	func rsaKA() keyAgreement {
   156		return rsaKeyAgreement{}
   157	}
   158	
   159	func ecdheRSAKA() keyAgreement {
   160		return new(ecdheRSAKeyAgreement)
   161	}
   162	
   163	// mutualCipherSuite returns a cipherSuite given a list of supported
   164	// ciphersuites and the id requested by the peer.
   165	func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
   166		for _, id := range have {
   167			if id == want {
   168				for _, suite := range cipherSuites {
   169					if suite.id == want {
   170						return suite
   171					}
   172				}
   173				return nil
   174			}
   175		}
   176		return nil
   177	}
   178	
   179	// A list of the possible cipher suite ids. Taken from
   180	// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
   181	const (
   182		TLS_RSA_WITH_RC4_128_SHA            uint16 = 0x0005
   183		TLS_RSA_WITH_3DES_EDE_CBC_SHA       uint16 = 0x000a
   184		TLS_RSA_WITH_AES_128_CBC_SHA        uint16 = 0x002f
   185		TLS_ECDHE_RSA_WITH_RC4_128_SHA      uint16 = 0xc011
   186		TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0xc012
   187		TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA  uint16 = 0xc013
   188	)