summaryrefslogtreecommitdiff
path: root/src/lib/libssl/tls13_key_share.c
diff options
context:
space:
mode:
authorjsing <>2020-01-30 17:09:23 +0000
committerjsing <>2020-01-30 17:09:23 +0000
commitf0f131814afdbc818e8b7b88541fca62af421a5d (patch)
tree7eeb14d221177f2f4d5d5b5c1ba2452ace34da8e /src/lib/libssl/tls13_key_share.c
parent1f07a6fc3b3b9d44b731e6cf17fd00b540758db8 (diff)
downloadopenbsd-f0f131814afdbc818e8b7b88541fca62af421a5d.tar.gz
openbsd-f0f131814afdbc818e8b7b88541fca62af421a5d.tar.bz2
openbsd-f0f131814afdbc818e8b7b88541fca62af421a5d.zip
Provide struct/functions for handling TLSv1.3 key shares.
Pull out the key share handling code and provide a clean/self contained interface. This will make it easier to support groups other than X25519. ok beck@ inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/tls13_key_share.c')
-rw-r--r--src/lib/libssl/tls13_key_share.c224
1 files changed, 224 insertions, 0 deletions
diff --git a/src/lib/libssl/tls13_key_share.c b/src/lib/libssl/tls13_key_share.c
new file mode 100644
index 0000000000..9a83b9f9f7
--- /dev/null
+++ b/src/lib/libssl/tls13_key_share.c
@@ -0,0 +1,224 @@
1/* $OpenBSD: tls13_key_share.c,v 1.1 2020/01/30 17:09:23 jsing Exp $ */
2/*
3 * Copyright (c) 2020 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 <stdlib.h>
19
20#include <openssl/curve25519.h>
21
22#include "bytestring.h"
23#include "ssl_locl.h"
24#include "tls13_internal.h"
25
26struct tls13_key_share {
27 int nid;
28 uint16_t group_id;
29
30 uint8_t *x25519_public;
31 uint8_t *x25519_private;
32 uint8_t *x25519_peer_public;
33};
34
35struct tls13_key_share *
36tls13_key_share_new(int nid)
37{
38 struct tls13_key_share *ks;
39
40 if ((ks = calloc(1, sizeof(struct tls13_key_share))) == NULL)
41 goto err;
42
43 if ((ks->group_id = tls1_ec_nid2curve_id(nid)) == 0)
44 goto err;
45
46 ks->nid = nid;
47
48 return ks;
49
50 err:
51 tls13_key_share_free(ks);
52
53 return NULL;
54}
55
56void
57tls13_key_share_free(struct tls13_key_share *ks)
58{
59 if (ks == NULL)
60 return;
61
62 freezero(ks->x25519_public, X25519_KEY_LENGTH);
63 freezero(ks->x25519_private, X25519_KEY_LENGTH);
64 freezero(ks->x25519_peer_public, X25519_KEY_LENGTH);
65
66 freezero(ks, sizeof(*ks));
67}
68
69uint16_t
70tls13_key_share_group(struct tls13_key_share *ks)
71{
72 return ks->group_id;
73}
74
75static int
76tls13_key_share_generate_x25519(struct tls13_key_share *ks)
77{
78 uint8_t *public = NULL, *private = NULL;
79 int ret = 0;
80
81 if (ks->x25519_public != NULL || ks->x25519_private != NULL)
82 goto err;
83
84 if ((public = calloc(1, X25519_KEY_LENGTH)) == NULL)
85 goto err;
86 if ((private = calloc(1, X25519_KEY_LENGTH)) == NULL)
87 goto err;
88
89 X25519_keypair(public, private);
90
91 ks->x25519_public = public;
92 ks->x25519_private = private;
93 public = NULL;
94 private = NULL;
95
96 ret = 1;
97
98 err:
99 freezero(public, X25519_KEY_LENGTH);
100 freezero(private, X25519_KEY_LENGTH);
101
102 return ret;
103}
104
105int
106tls13_key_share_generate(struct tls13_key_share *ks)
107{
108 if (ks->nid == NID_X25519)
109 return tls13_key_share_generate_x25519(ks);
110
111 return 0;
112}
113
114static int
115tls13_key_share_public_x25519(struct tls13_key_share *ks, CBB *cbb)
116{
117 if (ks->x25519_public == NULL)
118 return 0;
119
120 return CBB_add_bytes(cbb, ks->x25519_public, X25519_KEY_LENGTH);
121}
122
123int
124tls13_key_share_public(struct tls13_key_share *ks, CBB *cbb)
125{
126 CBB key_exchange;
127
128 if (!CBB_add_u16(cbb, ks->group_id))
129 goto err;
130 if (!CBB_add_u16_length_prefixed(cbb, &key_exchange))
131 goto err;
132
133 if (ks->nid == NID_X25519) {
134 if (!tls13_key_share_public_x25519(ks, &key_exchange))
135 goto err;
136 } else {
137 goto err;
138 }
139
140 if (!CBB_flush(cbb))
141 goto err;
142
143 return 1;
144
145 err:
146 return 0;
147}
148
149static int
150tls13_key_share_peer_public_x25519(struct tls13_key_share *ks, CBS *cbs)
151{
152 size_t out_len;
153
154 if (CBS_len(cbs) != X25519_KEY_LENGTH)
155 return 0;
156
157 return CBS_stow(cbs, &ks->x25519_peer_public, &out_len);
158}
159
160int
161tls13_key_share_peer_public(struct tls13_key_share *ks, uint16_t group,
162 CBS *cbs)
163{
164 CBS key_exchange;
165
166 if (ks->group_id != group)
167 return 0;
168
169 if (!CBS_get_u16_length_prefixed(cbs, &key_exchange))
170 return 0;
171
172 if (ks->nid == NID_X25519) {
173 if (!tls13_key_share_peer_public_x25519(ks, &key_exchange))
174 return 0;
175 }
176
177 if (CBS_len(cbs) != 0)
178 return 0;
179
180 return 1;
181}
182
183static int
184tls13_key_share_derive_x25519(struct tls13_key_share *ks,
185 uint8_t **shared_key, size_t *shared_key_len)
186{
187 uint8_t *sk = NULL;
188 int ret = 0;
189
190 if (ks->x25519_private == NULL || ks->x25519_peer_public == NULL)
191 goto err;
192
193 if ((sk = calloc(1, X25519_KEY_LENGTH)) == NULL)
194 goto err;
195 if (!X25519(sk, ks->x25519_private, ks->x25519_peer_public))
196 goto err;
197
198 *shared_key = sk;
199 *shared_key_len = X25519_KEY_LENGTH;
200 sk = NULL;
201
202 ret = 1;
203
204 err:
205 freezero(sk, X25519_KEY_LENGTH);
206
207 return ret;
208}
209
210int
211tls13_key_share_derive(struct tls13_key_share *ks, uint8_t **shared_key,
212 size_t *shared_key_len)
213{
214 if (*shared_key != NULL)
215 return 0;
216
217 *shared_key_len = 0;
218
219 if (ks->nid == NID_X25519)
220 return tls13_key_share_derive_x25519(ks, shared_key,
221 shared_key_len);
222
223 return 0;
224}