diff options
author | jsing <> | 2020-01-30 16:25:09 +0000 |
---|---|---|
committer | jsing <> | 2020-01-30 16:25:09 +0000 |
commit | 1f07a6fc3b3b9d44b731e6cf17fd00b540758db8 (patch) | |
tree | c2c8df4a9c431efa5cc0db8ff09bf1be05c80c4e /src/lib/libssl/ssl_kex.c | |
parent | 668fa98385559e6ca53555e32da8e7eb618f0d80 (diff) | |
download | openbsd-1f07a6fc3b3b9d44b731e6cf17fd00b540758db8.tar.gz openbsd-1f07a6fc3b3b9d44b731e6cf17fd00b540758db8.tar.bz2 openbsd-1f07a6fc3b3b9d44b731e6cf17fd00b540758db8.zip |
Factor out/rewrite the ECDHE EC point key exchange code.
This reduces replication between the existing TLS client/server and allows
the code to soon be reused for TLSv1.3.
With feedback from inoguchi@ and tb@
ok inoguchi@ tb@
Diffstat (limited to 'src/lib/libssl/ssl_kex.c')
-rw-r--r-- | src/lib/libssl/ssl_kex.c | 141 |
1 files changed, 141 insertions, 0 deletions
diff --git a/src/lib/libssl/ssl_kex.c b/src/lib/libssl/ssl_kex.c new file mode 100644 index 0000000000..439c1702b3 --- /dev/null +++ b/src/lib/libssl/ssl_kex.c | |||
@@ -0,0 +1,141 @@ | |||
1 | /* $OpenBSD: ssl_kex.c,v 1.1 2020/01/30 16:25:09 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/ec.h> | ||
21 | #include <openssl/ecdh.h> | ||
22 | |||
23 | #include "bytestring.h" | ||
24 | |||
25 | int | ||
26 | ssl_kex_generate_ecdhe_ecp(EC_KEY *ecdh, int nid) | ||
27 | { | ||
28 | EC_GROUP *group; | ||
29 | int ret = 0; | ||
30 | |||
31 | if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) | ||
32 | goto err; | ||
33 | |||
34 | if (!EC_KEY_set_group(ecdh, group)) | ||
35 | goto err; | ||
36 | if (!EC_KEY_generate_key(ecdh)) | ||
37 | goto err; | ||
38 | |||
39 | ret = 1; | ||
40 | |||
41 | err: | ||
42 | EC_GROUP_free(group); | ||
43 | |||
44 | return ret; | ||
45 | } | ||
46 | |||
47 | int | ||
48 | ssl_kex_public_ecdhe_ecp(EC_KEY *ecdh, CBB *cbb) | ||
49 | { | ||
50 | const EC_GROUP *group; | ||
51 | const EC_POINT *point; | ||
52 | uint8_t *ecp; | ||
53 | size_t ecp_len; | ||
54 | int ret = 0; | ||
55 | |||
56 | if ((group = EC_KEY_get0_group(ecdh)) == NULL) | ||
57 | goto err; | ||
58 | if ((point = EC_KEY_get0_public_key(ecdh)) == NULL) | ||
59 | goto err; | ||
60 | |||
61 | if ((ecp_len = EC_POINT_point2oct(group, point, | ||
62 | POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL)) == 0) | ||
63 | goto err; | ||
64 | if (!CBB_add_space(cbb, &ecp, ecp_len)) | ||
65 | goto err; | ||
66 | if ((EC_POINT_point2oct(group, point, POINT_CONVERSION_UNCOMPRESSED, | ||
67 | ecp, ecp_len, NULL)) == 0) | ||
68 | goto err; | ||
69 | |||
70 | ret = 1; | ||
71 | |||
72 | err: | ||
73 | return ret; | ||
74 | } | ||
75 | |||
76 | int | ||
77 | ssl_kex_peer_public_ecdhe_ecp(EC_KEY *ecdh, int nid, CBS *cbs) | ||
78 | { | ||
79 | EC_GROUP *group = NULL; | ||
80 | EC_POINT *point = NULL; | ||
81 | int ret = 0; | ||
82 | |||
83 | if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) | ||
84 | goto err; | ||
85 | |||
86 | if (!EC_KEY_set_group(ecdh, group)) | ||
87 | goto err; | ||
88 | |||
89 | if ((point = EC_POINT_new(group)) == NULL) | ||
90 | goto err; | ||
91 | if (EC_POINT_oct2point(group, point, CBS_data(cbs), CBS_len(cbs), | ||
92 | NULL) == 0) | ||
93 | goto err; | ||
94 | if (!EC_KEY_set_public_key(ecdh, point)) | ||
95 | goto err; | ||
96 | |||
97 | ret = 1; | ||
98 | |||
99 | err: | ||
100 | EC_GROUP_free(group); | ||
101 | EC_POINT_free(point); | ||
102 | |||
103 | return ret; | ||
104 | } | ||
105 | |||
106 | int | ||
107 | ssl_kex_derive_ecdhe_ecp(EC_KEY *ecdh, EC_KEY *ecdh_peer, | ||
108 | uint8_t **shared_key, size_t *shared_key_len) | ||
109 | { | ||
110 | const EC_POINT *point; | ||
111 | uint8_t *sk = NULL; | ||
112 | int sk_len = 0; | ||
113 | int ret = 0; | ||
114 | |||
115 | if (!EC_GROUP_check(EC_KEY_get0_group(ecdh), NULL)) | ||
116 | goto err; | ||
117 | if (!EC_GROUP_check(EC_KEY_get0_group(ecdh_peer), NULL)) | ||
118 | goto err; | ||
119 | |||
120 | if ((point = EC_KEY_get0_public_key(ecdh_peer)) == NULL) | ||
121 | goto err; | ||
122 | |||
123 | if ((sk_len = ECDH_size(ecdh)) <= 0) | ||
124 | goto err; | ||
125 | if ((sk = calloc(1, sk_len)) == NULL) | ||
126 | goto err; | ||
127 | |||
128 | if (ECDH_compute_key(sk, sk_len, point, ecdh, NULL) <= 0) | ||
129 | goto err; | ||
130 | |||
131 | *shared_key = sk; | ||
132 | *shared_key_len = sk_len; | ||
133 | sk = NULL; | ||
134 | |||
135 | ret = 1; | ||
136 | |||
137 | err: | ||
138 | freezero(sk, sk_len); | ||
139 | |||
140 | return ret; | ||
141 | } | ||