OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [crypto/] [tls/] [prf.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 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/hmac"
9
        "crypto/md5"
10
        "crypto/sha1"
11
        "hash"
12
)
13
 
14
// Split a premaster secret in two as specified in RFC 4346, section 5.
15
func splitPreMasterSecret(secret []byte) (s1, s2 []byte) {
16
        s1 = secret[0 : (len(secret)+1)/2]
17
        s2 = secret[len(secret)/2:]
18
        return
19
}
20
 
21
// pHash implements the P_hash function, as defined in RFC 4346, section 5.
22
func pHash(result, secret, seed []byte, hash func() hash.Hash) {
23
        h := hmac.New(hash, secret)
24
        h.Write(seed)
25
        a := h.Sum(nil)
26
 
27
        j := 0
28
        for j < len(result) {
29
                h.Reset()
30
                h.Write(a)
31
                h.Write(seed)
32
                b := h.Sum(nil)
33
                todo := len(b)
34
                if j+todo > len(result) {
35
                        todo = len(result) - j
36
                }
37
                copy(result[j:j+todo], b)
38
                j += todo
39
 
40
                h.Reset()
41
                h.Write(a)
42
                a = h.Sum(nil)
43
        }
44
}
45
 
46
// pRF10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5.
47
func pRF10(result, secret, label, seed []byte) {
48
        hashSHA1 := sha1.New
49
        hashMD5 := md5.New
50
 
51
        labelAndSeed := make([]byte, len(label)+len(seed))
52
        copy(labelAndSeed, label)
53
        copy(labelAndSeed[len(label):], seed)
54
 
55
        s1, s2 := splitPreMasterSecret(secret)
56
        pHash(result, s1, labelAndSeed, hashMD5)
57
        result2 := make([]byte, len(result))
58
        pHash(result2, s2, labelAndSeed, hashSHA1)
59
 
60
        for i, b := range result2 {
61
                result[i] ^= b
62
        }
63
}
64
 
65
// pRF30 implements the SSL 3.0 pseudo-random function, as defined in
66
// www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6.
67
func pRF30(result, secret, label, seed []byte) {
68
        hashSHA1 := sha1.New()
69
        hashMD5 := md5.New()
70
 
71
        done := 0
72
        i := 0
73
        // RFC5246 section 6.3 says that the largest PRF output needed is 128
74
        // bytes. Since no more ciphersuites will be added to SSLv3, this will
75
        // remain true. Each iteration gives us 16 bytes so 10 iterations will
76
        // be sufficient.
77
        var b [11]byte
78
        for done < len(result) {
79
                for j := 0; j <= i; j++ {
80
                        b[j] = 'A' + byte(i)
81
                }
82
 
83
                hashSHA1.Reset()
84
                hashSHA1.Write(b[:i+1])
85
                hashSHA1.Write(secret)
86
                hashSHA1.Write(seed)
87
                digest := hashSHA1.Sum(nil)
88
 
89
                hashMD5.Reset()
90
                hashMD5.Write(secret)
91
                hashMD5.Write(digest)
92
 
93
                done += copy(result[done:], hashMD5.Sum(nil))
94
                i++
95
        }
96
}
97
 
98
const (
99
        tlsRandomLength      = 32 // Length of a random nonce in TLS 1.1.
100
        masterSecretLength   = 48 // Length of a master secret in TLS 1.1.
101
        finishedVerifyLength = 12 // Length of verify_data in a Finished message.
102
)
103
 
104
var masterSecretLabel = []byte("master secret")
105
var keyExpansionLabel = []byte("key expansion")
106
var clientFinishedLabel = []byte("client finished")
107
var serverFinishedLabel = []byte("server finished")
108
 
109
// keysFromPreMasterSecret generates the connection keys from the pre master
110
// secret, given the lengths of the MAC key, cipher key and IV, as defined in
111
// RFC 2246, section 6.3.
112
func keysFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (masterSecret, clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) {
113
        prf := pRF10
114
        if version == versionSSL30 {
115
                prf = pRF30
116
        }
117
 
118
        var seed [tlsRandomLength * 2]byte
119
        copy(seed[0:len(clientRandom)], clientRandom)
120
        copy(seed[len(clientRandom):], serverRandom)
121
        masterSecret = make([]byte, masterSecretLength)
122
        prf(masterSecret, preMasterSecret, masterSecretLabel, seed[0:])
123
 
124
        copy(seed[0:len(clientRandom)], serverRandom)
125
        copy(seed[len(serverRandom):], clientRandom)
126
 
127
        n := 2*macLen + 2*keyLen + 2*ivLen
128
        keyMaterial := make([]byte, n)
129
        prf(keyMaterial, masterSecret, keyExpansionLabel, seed[0:])
130
        clientMAC = keyMaterial[:macLen]
131
        keyMaterial = keyMaterial[macLen:]
132
        serverMAC = keyMaterial[:macLen]
133
        keyMaterial = keyMaterial[macLen:]
134
        clientKey = keyMaterial[:keyLen]
135
        keyMaterial = keyMaterial[keyLen:]
136
        serverKey = keyMaterial[:keyLen]
137
        keyMaterial = keyMaterial[keyLen:]
138
        clientIV = keyMaterial[:ivLen]
139
        keyMaterial = keyMaterial[ivLen:]
140
        serverIV = keyMaterial[:ivLen]
141
        return
142
}
143
 
144
func newFinishedHash(version uint16) finishedHash {
145
        return finishedHash{md5.New(), sha1.New(), md5.New(), sha1.New(), version}
146
}
147
 
148
// A finishedHash calculates the hash of a set of handshake messages suitable
149
// for including in a Finished message.
150
type finishedHash struct {
151
        clientMD5  hash.Hash
152
        clientSHA1 hash.Hash
153
        serverMD5  hash.Hash
154
        serverSHA1 hash.Hash
155
        version    uint16
156
}
157
 
158
func (h finishedHash) Write(msg []byte) (n int, err error) {
159
        h.clientMD5.Write(msg)
160
        h.clientSHA1.Write(msg)
161
        h.serverMD5.Write(msg)
162
        h.serverSHA1.Write(msg)
163
        return len(msg), nil
164
}
165
 
166
// finishedSum10 calculates the contents of the verify_data member of a TLSv1
167
// Finished message given the MD5 and SHA1 hashes of a set of handshake
168
// messages.
169
func finishedSum10(md5, sha1, label, masterSecret []byte) []byte {
170
        seed := make([]byte, len(md5)+len(sha1))
171
        copy(seed, md5)
172
        copy(seed[len(md5):], sha1)
173
        out := make([]byte, finishedVerifyLength)
174
        pRF10(out, masterSecret, label, seed)
175
        return out
176
}
177
 
178
// finishedSum30 calculates the contents of the verify_data member of a SSLv3
179
// Finished message given the MD5 and SHA1 hashes of a set of handshake
180
// messages.
181
func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte {
182
        md5.Write(magic[:])
183
        md5.Write(masterSecret)
184
        md5.Write(ssl30Pad1[:])
185
        md5Digest := md5.Sum(nil)
186
 
187
        md5.Reset()
188
        md5.Write(masterSecret)
189
        md5.Write(ssl30Pad2[:])
190
        md5.Write(md5Digest)
191
        md5Digest = md5.Sum(nil)
192
 
193
        sha1.Write(magic[:])
194
        sha1.Write(masterSecret)
195
        sha1.Write(ssl30Pad1[:40])
196
        sha1Digest := sha1.Sum(nil)
197
 
198
        sha1.Reset()
199
        sha1.Write(masterSecret)
200
        sha1.Write(ssl30Pad2[:40])
201
        sha1.Write(sha1Digest)
202
        sha1Digest = sha1.Sum(nil)
203
 
204
        ret := make([]byte, len(md5Digest)+len(sha1Digest))
205
        copy(ret, md5Digest)
206
        copy(ret[len(md5Digest):], sha1Digest)
207
        return ret
208
}
209
 
210
var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54}
211
var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52}
212
 
213
// clientSum returns the contents of the verify_data member of a client's
214
// Finished message.
215
func (h finishedHash) clientSum(masterSecret []byte) []byte {
216
        if h.version == versionSSL30 {
217
                return finishedSum30(h.clientMD5, h.clientSHA1, masterSecret, ssl3ClientFinishedMagic)
218
        }
219
 
220
        md5 := h.clientMD5.Sum(nil)
221
        sha1 := h.clientSHA1.Sum(nil)
222
        return finishedSum10(md5, sha1, clientFinishedLabel, masterSecret)
223
}
224
 
225
// serverSum returns the contents of the verify_data member of a server's
226
// Finished message.
227
func (h finishedHash) serverSum(masterSecret []byte) []byte {
228
        if h.version == versionSSL30 {
229
                return finishedSum30(h.serverMD5, h.serverSHA1, masterSecret, ssl3ServerFinishedMagic)
230
        }
231
 
232
        md5 := h.serverMD5.Sum(nil)
233
        sha1 := h.serverSHA1.Sum(nil)
234
        return finishedSum10(md5, sha1, serverFinishedLabel, masterSecret)
235
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.