@@ -16,7 +16,10 @@ func SupportsTLS1PRF() bool {
16
16
(vMajor >= 1 && vMinor >= 1 )
17
17
}
18
18
19
- func TLS1PRF (secret , label , seed []byte , keyLen int , h func () hash.Hash ) ([]byte , error ) {
19
+ // TLS1PRF implements the TLS 1.0/1.1 pseudo-random function if h is nil,
20
+ // else it implements the TLS 1.2 pseudo-random function.
21
+ // The pseudo-random number will be written to result and will be of length len(result).
22
+ func TLS1PRF (result , secret , label , seed []byte , h func () hash.Hash ) error {
20
23
var md C.GO_EVP_MD_PTR
21
24
if h == nil {
22
25
// TLS 1.0/1.1 PRF doesn't allow to specify the hash function,
@@ -29,70 +32,73 @@ func TLS1PRF(secret, label, seed []byte, keyLen int, h func() hash.Hash) ([]byte
29
32
md = hashToMD (h ())
30
33
}
31
34
if md == nil {
32
- return nil , errors .New ("unsupported hash function" )
35
+ return errors .New ("unsupported hash function" )
33
36
}
34
37
35
38
ctx := C .go_openssl_EVP_PKEY_CTX_new_id (C .GO_EVP_PKEY_TLS1_PRF , nil )
36
39
if ctx == nil {
37
- return nil , newOpenSSLError ("EVP_PKEY_CTX_new_id" )
40
+ return newOpenSSLError ("EVP_PKEY_CTX_new_id" )
38
41
}
39
42
defer func () {
40
43
C .go_openssl_EVP_PKEY_CTX_free (ctx )
41
44
}()
42
45
43
46
if C .go_openssl_EVP_PKEY_derive_init (ctx ) != 1 {
44
- return nil , newOpenSSLError ("EVP_PKEY_derive_init" )
47
+ return newOpenSSLError ("EVP_PKEY_derive_init" )
45
48
}
46
49
switch vMajor {
47
50
case 3 :
48
51
if C .go_openssl_EVP_PKEY_CTX_set_tls1_prf_md (ctx , md ) != 1 {
49
- return nil , newOpenSSLError ("EVP_PKEY_CTX_set_tls1_prf_md" )
52
+ return newOpenSSLError ("EVP_PKEY_CTX_set_tls1_prf_md" )
50
53
}
51
54
if C .go_openssl_EVP_PKEY_CTX_set1_tls1_prf_secret (ctx ,
52
55
base (secret ), C .int (len (secret ))) != 1 {
53
- return nil , newOpenSSLError ("EVP_PKEY_CTX_set1_tls1_prf_secret" )
56
+ return newOpenSSLError ("EVP_PKEY_CTX_set1_tls1_prf_secret" )
54
57
}
55
58
if C .go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed (ctx ,
56
59
base (label ), C .int (len (label ))) != 1 {
57
- return nil , newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
60
+ return newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
58
61
}
59
62
if C .go_openssl_EVP_PKEY_CTX_add1_tls1_prf_seed (ctx ,
60
63
base (seed ), C .int (len (seed ))) != 1 {
61
- return nil , newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
64
+ return newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
62
65
}
63
66
case 1 :
64
67
if C .go_openssl_EVP_PKEY_CTX_ctrl (ctx , - 1 ,
65
68
C .GO1_EVP_PKEY_OP_DERIVE ,
66
69
C .GO_EVP_PKEY_CTRL_TLS_MD ,
67
70
0 , unsafe .Pointer (md )) != 1 {
68
- return nil , newOpenSSLError ("EVP_PKEY_CTX_set_tls1_prf_md" )
71
+ return newOpenSSLError ("EVP_PKEY_CTX_set_tls1_prf_md" )
69
72
}
70
73
if C .go_openssl_EVP_PKEY_CTX_ctrl (ctx , - 1 ,
71
74
C .GO1_EVP_PKEY_OP_DERIVE ,
72
75
C .GO_EVP_PKEY_CTRL_TLS_SECRET ,
73
76
C .int (len (secret )), unsafe .Pointer (base (secret ))) != 1 {
74
- return nil , newOpenSSLError ("EVP_PKEY_CTX_set1_tls1_prf_secret" )
77
+ return newOpenSSLError ("EVP_PKEY_CTX_set1_tls1_prf_secret" )
75
78
}
76
79
if C .go_openssl_EVP_PKEY_CTX_ctrl (ctx , - 1 ,
77
80
C .GO1_EVP_PKEY_OP_DERIVE ,
78
81
C .GO_EVP_PKEY_CTRL_TLS_SEED ,
79
82
C .int (len (label )), unsafe .Pointer (base (label ))) != 1 {
80
- return nil , newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
83
+ return newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
81
84
}
82
85
if C .go_openssl_EVP_PKEY_CTX_ctrl (ctx , - 1 ,
83
86
C .GO1_EVP_PKEY_OP_DERIVE ,
84
87
C .GO_EVP_PKEY_CTRL_TLS_SEED ,
85
88
C .int (len (seed )), unsafe .Pointer (base (seed ))) != 1 {
86
- return nil , newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
89
+ return newOpenSSLError ("EVP_PKEY_CTX_add1_tls1_prf_seed" )
87
90
}
88
91
}
89
- outLen := C .size_t (keyLen )
90
- out := make ([]byte , outLen )
91
- if C .go_openssl_EVP_PKEY_derive (ctx , base (out ), & outLen ) != 1 {
92
- return nil , newOpenSSLError ("EVP_PKEY_derive" )
92
+ outLen := C .size_t (len (result ))
93
+ if C .go_openssl_EVP_PKEY_derive (ctx , base (result ), & outLen ) != 1 {
94
+ return newOpenSSLError ("EVP_PKEY_derive" )
93
95
}
94
- if outLen != C .size_t (keyLen ) {
95
- return nil , errors .New ("tls1-prf: entropy limit reached" )
96
+ // The Go standard library expects TLS1PRF to return the requested number of bytes,
97
+ // fail if it doesn't. While there is no known situation where this will happen,
98
+ // EVP_PKEY_derive handles multiple algorithms and there could be a subtle mismatch
99
+ // after more code changes in the future.
100
+ if outLen != C .size_t (len (result )) {
101
+ return errors .New ("tls1-prf: derived less bytes than requested" )
96
102
}
97
- return out [: outLen ], nil
103
+ return nil
98
104
}
0 commit comments