FAQ
Reviewers: golang-dev_googlegroups.com,

Message:
Hello golang-dev@googlegroups.com,

I'd like you to review this change to
https://code.google.com/p/go


Description:
crypto/tls: allow alternate low-level cryptographic functions

crypto/tls relies on the crypto/ implementations of AES, 3DES,
MD5, SHA1 and RC4. For performance or security reasons it may
be preferable to use alternate implementations (such as a Go
wrapper to OpenSSL).

This change enables use of alternate AES, 3DES, MD5, SHA1 and
RC4 function by setting global functions that crypto/tls uses
to create cipher or hash objects. By default the standard Go
implementations are used.

Please review this at https://codereview.appspot.com/7197048/

Affected files:
M src/pkg/crypto/tls/cipher_suites.go
M src/pkg/crypto/tls/key_agreement.go
M src/pkg/crypto/tls/prf.go


Index: src/pkg/crypto/tls/cipher_suites.go
===================================================================
--- a/src/pkg/crypto/tls/cipher_suites.go
+++ b/src/pkg/crypto/tls/cipher_suites.go
@@ -9,6 +9,7 @@
"crypto/cipher"
"crypto/des"
"crypto/hmac"
+ "crypto/md5"
"crypto/rc4"
"crypto/sha1"
"crypto/x509"
@@ -34,6 +35,44 @@
generateClientKeyExchange(*Config, *clientHelloMsg, *x509.Certificate)
([]byte, *clientKeyExchangeMsg, error)
}

+func sha1New() hash.Hash {
+ return sha1.New()
+}
+
+func md5New() hash.Hash {
+ return md5.New()
+}
+
+func rc4NewCipher(key []byte) (interface{}, error) {
+ return rc4.NewCipher(key)
+}
+
+func aesNewCipher(key []byte) (cipher.Block, error) {
+ return aes.NewCipher(key)
+}
+
+func desNewTripleDESCipher(key []byte) (cipher.Block, error) {
+ return des.NewTripleDESCipher(key)
+}
+
+// Functions that create ciphers and cryptographic hashes. Change them
+// to substitute alternative implementations
+var (
+ AESNewCipher func(key []byte) (cipher.Block, error)
+ RC4NewCipher func(key []byte) (interface{}, error)
+ DESNewTripleDESCipher func(key []byte) (cipher.Block, error)
+ MD5New func() hash.Hash
+ SHA1New func() hash.Hash
+)
+
+func init() {
+ AESNewCipher = aesNewCipher
+ RC4NewCipher = rc4NewCipher
+ DESNewTripleDESCipher = desNewTripleDESCipher
+ MD5New = md5New
+ SHA1New = sha1New
+}
+
// A cipherSuite is a specific combination of key agreement, cipher and MAC
// function. All cipher suites currently assume RSA key agreement.
type cipherSuite struct {
@@ -63,12 +102,12 @@
}

func cipherRC4(key, iv []byte, isRead bool) interface{} {
- cipher, _ := rc4.NewCipher(key)
+ cipher, _ := RC4NewCipher(key)
return cipher
}

func cipher3DES(key, iv []byte, isRead bool) interface{} {
- block, _ := des.NewTripleDESCipher(key)
+ block, _ := DESNewTripleDESCipher(key)
if isRead {
return cipher.NewCBCDecrypter(block, iv)
}
@@ -76,7 +115,7 @@
}

func cipherAES(key, iv []byte, isRead bool) interface{} {
- block, _ := aes.NewCipher(key)
+ block, _ := AESNewCipher(key)
if isRead {
return cipher.NewCBCDecrypter(block, iv)
}
@@ -87,13 +126,13 @@
func macSHA1(version uint16, key []byte) macFunction {
if version == versionSSL30 {
mac := ssl30MAC{
- h: sha1.New(),
+ h: SHA1New(),
key: make([]byte, len(key)),
}
copy(mac.key, key)
return mac
}
- return tls10MAC{hmac.New(sha1.New, key)}
+ return tls10MAC{hmac.New(SHA1New, key)}
}

type macFunction interface {
Index: src/pkg/crypto/tls/key_agreement.go
===================================================================
--- a/src/pkg/crypto/tls/key_agreement.go
+++ b/src/pkg/crypto/tls/key_agreement.go
@@ -86,13 +86,13 @@
// concatenation of an MD5 and SHA1 hash.
func md5SHA1Hash(slices ...[]byte) []byte {
md5sha1 := make([]byte, md5.Size+sha1.Size)
- hmd5 := md5.New()
+ hmd5 := MD5New()
for _, slice := range slices {
hmd5.Write(slice)
}
copy(md5sha1, hmd5.Sum(nil))

- hsha1 := sha1.New()
+ hsha1 := SHA1New()
for _, slice := range slices {
hsha1.Write(slice)
}
Index: src/pkg/crypto/tls/prf.go
===================================================================
--- a/src/pkg/crypto/tls/prf.go
+++ b/src/pkg/crypto/tls/prf.go
@@ -6,8 +6,6 @@

import (
"crypto/hmac"
- "crypto/md5"
- "crypto/sha1"
"hash"
)

@@ -45,8 +43,8 @@

// pRF10 implements the TLS 1.0 pseudo-random function, as defined in RFC
2246, section 5.
func pRF10(result, secret, label, seed []byte) {
- hashSHA1 := sha1.New
- hashMD5 := md5.New
+ hashSHA1 := SHA1New
+ hashMD5 := MD5New

labelAndSeed := make([]byte, len(label)+len(seed))
copy(labelAndSeed, label)
@@ -65,8 +63,8 @@
// pRF30 implements the SSL 3.0 pseudo-random function, as defined in
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6.
func pRF30(result, secret, label, seed []byte) {
- hashSHA1 := sha1.New()
- hashMD5 := md5.New()
+ hashSHA1 := SHA1New()
+ hashMD5 := MD5New()

done := 0
i := 0
@@ -153,7 +151,7 @@
}

func newFinishedHash(version uint16) finishedHash {
- return finishedHash{md5.New(), sha1.New(), md5.New(), sha1.New(), version}
+ return finishedHash{MD5New(), SHA1New(), MD5New(), SHA1New(), version}
}

// A finishedHash calculates the hash of a set of handshake messages
suitable

Search Discussions

  • Russ Cox at Jan 23, 2013 at 10:20 pm
    If you want to sub in faster implementations, why not compile a copy of Go
    with those implementations in the standard places?

    Russ
  • John Graham-Cumming at Jan 23, 2013 at 10:23 pm

    On Wed, Jan 23, 2013 at 10:19 PM, Russ Cox wrote:

    If you want to sub in faster implementations, why not compile a copy of Go
    with those implementations in the standard places?

    I can, but then it means that I am maintaining a local copy of Go which I'd
    rather avoid. And it may be the case that others have the same speed
    critical need for using OpenSSL (or similar) primitives.

    John.
  • Brad Fitzpatrick at Jan 23, 2013 at 10:46 pm

    On Wed, Jan 23, 2013 at 2:22 PM, John Graham-Cumming wrote:
    On Wed, Jan 23, 2013 at 10:19 PM, Russ Cox wrote:

    If you want to sub in faster implementations, why not compile a copy of
    Go with those implementations in the standard places?

    I can, but then it means that I am maintaining a local copy of Go which
    I'd rather avoid. And it may be the case that others have the same speed
    critical need for using OpenSSL (or similar) primitives.

    One fear is that this crutch leads to everybody doing this, and Go's crypto
    not getting faster.
  • Adam Langley at Jan 23, 2013 at 10:52 pm
    We already have a registry of hash functions in crypto. I think a
    patch that gets the hash function from that registry rather than
    directly would be fine. That registry was designed to allow for
    optional hash functions, but using it to switch out implementations
    isn't a bother.

    However, this change adds an extra registry just in crypto/tls, and
    just for a few functions. I don't think that's good. That's why I
    suggested that the cipher implementations couldn't be switched out on
    the golang-nuts thread.


    Cheers

    AGL
  • John Graham-Cumming at Jan 23, 2013 at 11:03 pm

    On Wed, Jan 23, 2013 at 10:52 PM, Adam Langley wrote:

    We already have a registry of hash functions in crypto. I think a
    patch that gets the hash function from that registry rather than
    directly would be fine. That registry was designed to allow for
    optional hash functions, but using it to switch out implementations
    isn't a bother.
    Yes, it would be possible to use the hash registry, but RC4 is also needed
    so it would be necessary create a block cipher (or just cipher) registry as
    well so that crypto/tls could get RC4 from it.

    I'm happy to write code to do that if people think it would be acceptable.
    If that's not acceptable then I'll withdraw this CL and will maintain a
    local Go.
  • Dave Cheney at Jan 24, 2013 at 1:17 am

    One fear is that this crutch leads to everybody doing this, and Go's crypto
    not getting faster.
    I understand that John has a deadline, and the squeaky wheel gets the
    grease, but I share Brad's concern. Additionally I see this as an
    optional feature of the standard library, which means it'll probably
    break, and nobody will notice for a long time.

    Although unqualified, I am happy to assist manually translating
    (properly licensed) code from other public domain projects into plan 9
    asm if that will help.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-dev @
categoriesgo
postedJan 23, '13 at 7:33p
activeJan 24, '13 at 1:17a
posts7
users6
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase