xref: /dragonfly/crypto/libressl/ssl/tls12_lib.c (revision 6f5ec8b5)
1 /*	$OpenBSD: tls12_lib.c,v 1.5 2022/06/07 17:19:09 tb Exp $ */
2 /*
3  * Copyright (c) 2021 Joel Sing <jsing@openbsd.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include "ssl_locl.h"
19 
20 static int
21 tls12_finished_verify_data(SSL *s, const char *finished_label,
22     size_t finished_label_len, uint8_t *verify_data, size_t verify_data_len,
23     size_t *out_len)
24 {
25 	uint8_t transcript_hash[EVP_MAX_MD_SIZE];
26 	size_t transcript_hash_len;
27 
28 	*out_len = 0;
29 
30 	if (s->session->master_key_length == 0)
31 		return 0;
32 
33 	if (verify_data_len < TLS1_FINISH_MAC_LENGTH)
34 		return 0;
35 
36 	if (!tls1_transcript_hash_value(s, transcript_hash,
37 	    sizeof(transcript_hash), &transcript_hash_len))
38 		return 0;
39 
40 	if (!tls1_PRF(s, s->session->master_key, s->session->master_key_length,
41 	    finished_label, finished_label_len, transcript_hash,
42 	    transcript_hash_len, NULL, 0, NULL, 0, NULL, 0, verify_data,
43 	    TLS1_FINISH_MAC_LENGTH))
44 		return 0;
45 
46 	*out_len = TLS1_FINISH_MAC_LENGTH;
47 
48 	return 1;
49 }
50 
51 static int
52 tls12_client_finished_verify_data(SSL *s, uint8_t *verify_data,
53     size_t verify_data_len, size_t *out_len)
54 {
55 	return tls12_finished_verify_data(s, TLS_MD_CLIENT_FINISH_CONST,
56 	    TLS_MD_CLIENT_FINISH_CONST_SIZE, verify_data, verify_data_len,
57 	    out_len);
58 }
59 
60 static int
61 tls12_server_finished_verify_data(SSL *s, uint8_t *verify_data,
62     size_t verify_data_len, size_t *out_len)
63 {
64 	return tls12_finished_verify_data(s, TLS_MD_SERVER_FINISH_CONST,
65 	    TLS_MD_SERVER_FINISH_CONST_SIZE, verify_data, verify_data_len,
66 	    out_len);
67 }
68 
69 int
70 tls12_derive_finished(SSL *s)
71 {
72 	if (!s->server) {
73 		return tls12_client_finished_verify_data(s,
74 		    s->s3->hs.finished, sizeof(s->s3->hs.finished),
75 		    &s->s3->hs.finished_len);
76 	} else {
77 		return tls12_server_finished_verify_data(s,
78 		    s->s3->hs.finished, sizeof(s->s3->hs.finished),
79 		    &s->s3->hs.finished_len);
80 	}
81 }
82 
83 int
84 tls12_derive_peer_finished(SSL *s)
85 {
86 	if (s->server) {
87 		return tls12_client_finished_verify_data(s,
88 		    s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished),
89 		    &s->s3->hs.peer_finished_len);
90 	} else {
91 		return tls12_server_finished_verify_data(s,
92 		    s->s3->hs.peer_finished, sizeof(s->s3->hs.peer_finished),
93 		    &s->s3->hs.peer_finished_len);
94 	}
95 }
96 
97 int
98 tls12_derive_master_secret(SSL *s, uint8_t *premaster_secret,
99     size_t premaster_secret_len)
100 {
101 	s->session->master_key_length = 0;
102 
103 	if (premaster_secret_len == 0)
104 		return 0;
105 
106 	CTASSERT(sizeof(s->session->master_key) == SSL_MAX_MASTER_KEY_LENGTH);
107 
108 	if (!tls1_PRF(s, premaster_secret, premaster_secret_len,
109 	    TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE,
110 	    s->s3->client_random, SSL3_RANDOM_SIZE, NULL, 0,
111 	    s->s3->server_random, SSL3_RANDOM_SIZE, NULL, 0,
112 	    s->session->master_key, sizeof(s->session->master_key)))
113 		return 0;
114 
115 	s->session->master_key_length = SSL_MAX_MASTER_KEY_LENGTH;
116 
117 	return 1;
118 }
119