1 /* $OpenBSD: tls12_lib.c,v 1.6 2022/11/26 16:08:56 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_local.h"
19
20 static int
tls12_finished_verify_data(SSL * s,const char * finished_label,size_t finished_label_len,uint8_t * verify_data,size_t verify_data_len,size_t * out_len)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
tls12_client_finished_verify_data(SSL * s,uint8_t * verify_data,size_t verify_data_len,size_t * out_len)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
tls12_server_finished_verify_data(SSL * s,uint8_t * verify_data,size_t verify_data_len,size_t * out_len)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
tls12_derive_finished(SSL * s)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
tls12_derive_peer_finished(SSL * s)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
tls12_derive_master_secret(SSL * s,uint8_t * premaster_secret,size_t premaster_secret_len)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