diff options
Diffstat (limited to 'kexc25519.c')
-rw-r--r-- | kexc25519.c | 122 |
1 files changed, 112 insertions, 10 deletions
diff --git a/kexc25519.c b/kexc25519.c index 3911baf14..a06c6e44b 100644 --- a/kexc25519.c +++ b/kexc25519.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* $OpenBSD: kexc25519.c,v 1.13 2019/01/21 10:20:12 djm Exp $ */ | 1 | /* $OpenBSD: kexc25519.c,v 1.14 2019/01/21 10:24:09 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2019 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2010 Damien Miller. All rights reserved. | 4 | * Copyright (c) 2010 Damien Miller. All rights reserved. |
5 | * Copyright (c) 2013 Aris Adamantiadis. All rights reserved. | 5 | * Copyright (c) 2013 Aris Adamantiadis. All rights reserved. |
6 | * | 6 | * |
@@ -29,20 +29,16 @@ | |||
29 | 29 | ||
30 | #include <sys/types.h> | 30 | #include <sys/types.h> |
31 | 31 | ||
32 | #include <signal.h> | 32 | #include <stdio.h> |
33 | #include <string.h> | 33 | #include <string.h> |
34 | #include <signal.h> | ||
34 | 35 | ||
35 | #include <openssl/bn.h> | ||
36 | #include <openssl/evp.h> | ||
37 | |||
38 | #include "sshbuf.h" | ||
39 | #include "ssh2.h" | ||
40 | #include "sshkey.h" | 36 | #include "sshkey.h" |
41 | #include "cipher.h" | ||
42 | #include "kex.h" | 37 | #include "kex.h" |
43 | #include "log.h" | 38 | #include "sshbuf.h" |
44 | #include "digest.h" | 39 | #include "digest.h" |
45 | #include "ssherr.h" | 40 | #include "ssherr.h" |
41 | #include "ssh2.h" | ||
46 | 42 | ||
47 | extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], | 43 | extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], |
48 | const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) | 44 | const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) |
@@ -142,3 +138,109 @@ kex_c25519_hash( | |||
142 | #endif | 138 | #endif |
143 | return 0; | 139 | return 0; |
144 | } | 140 | } |
141 | |||
142 | int | ||
143 | kex_c25519_keypair(struct kex *kex) | ||
144 | { | ||
145 | struct sshbuf *buf = NULL; | ||
146 | u_char *cp = NULL; | ||
147 | int r; | ||
148 | |||
149 | if ((buf = sshbuf_new()) == NULL) | ||
150 | return SSH_ERR_ALLOC_FAIL; | ||
151 | if ((r = sshbuf_reserve(buf, CURVE25519_SIZE, &cp)) != 0) | ||
152 | goto out; | ||
153 | kexc25519_keygen(kex->c25519_client_key, cp); | ||
154 | #ifdef DEBUG_KEXECDH | ||
155 | dump_digest("client public key c25519:", cp, CURVE25519_SIZE); | ||
156 | #endif | ||
157 | kex->kem_client_pub = buf; | ||
158 | buf = NULL; | ||
159 | out: | ||
160 | sshbuf_free(buf); | ||
161 | return r; | ||
162 | } | ||
163 | |||
164 | int | ||
165 | kex_c25519_enc(struct kex *kex, const u_char *pkblob, | ||
166 | size_t pklen, struct sshbuf **server_blobp, struct sshbuf **shared_secretp) | ||
167 | { | ||
168 | struct sshbuf *server_blob = NULL; | ||
169 | struct sshbuf *buf = NULL; | ||
170 | u_char *server_pub; | ||
171 | u_char server_key[CURVE25519_SIZE]; | ||
172 | int r; | ||
173 | |||
174 | *server_blobp = NULL; | ||
175 | *shared_secretp = NULL; | ||
176 | |||
177 | if (pklen != CURVE25519_SIZE) { | ||
178 | r = SSH_ERR_SIGNATURE_INVALID; | ||
179 | goto out; | ||
180 | } | ||
181 | #ifdef DEBUG_KEXECDH | ||
182 | dump_digest("client public key 25519:", pkblob, CURVE25519_SIZE); | ||
183 | #endif | ||
184 | /* allocate space for encrypted KEM key and ECDH pub key */ | ||
185 | if ((server_blob = sshbuf_new()) == NULL) { | ||
186 | r = SSH_ERR_ALLOC_FAIL; | ||
187 | goto out; | ||
188 | } | ||
189 | if ((r = sshbuf_reserve(server_blob, CURVE25519_SIZE, &server_pub)) != 0) | ||
190 | goto out; | ||
191 | kexc25519_keygen(server_key, server_pub); | ||
192 | /* allocate shared secret */ | ||
193 | if ((buf = sshbuf_new()) == NULL) { | ||
194 | r = SSH_ERR_ALLOC_FAIL; | ||
195 | goto out; | ||
196 | } | ||
197 | if ((r = kexc25519_shared_key_ext(server_key, pkblob, buf, 0)) < 0) | ||
198 | goto out; | ||
199 | #ifdef DEBUG_KEXECDH | ||
200 | dump_digest("server public key 25519:", server_pub, CURVE25519_SIZE); | ||
201 | dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf)); | ||
202 | #endif | ||
203 | *server_blobp = server_blob; | ||
204 | *shared_secretp = buf; | ||
205 | server_blob = NULL; | ||
206 | buf = NULL; | ||
207 | out: | ||
208 | explicit_bzero(server_key, sizeof(server_key)); | ||
209 | sshbuf_free(server_blob); | ||
210 | sshbuf_free(buf); | ||
211 | return r; | ||
212 | } | ||
213 | |||
214 | int | ||
215 | kex_c25519_dec(struct kex *kex, const u_char *pkblob, | ||
216 | size_t pklen, struct sshbuf **shared_secretp) | ||
217 | { | ||
218 | struct sshbuf *buf = NULL; | ||
219 | int r; | ||
220 | |||
221 | *shared_secretp = NULL; | ||
222 | |||
223 | if (pklen != CURVE25519_SIZE) { | ||
224 | r = SSH_ERR_SIGNATURE_INVALID; | ||
225 | goto out; | ||
226 | } | ||
227 | #ifdef DEBUG_KEXECDH | ||
228 | dump_digest("server public key c25519:", pkblob, CURVE25519_SIZE); | ||
229 | #endif | ||
230 | /* shared secret */ | ||
231 | if ((buf = sshbuf_new()) == NULL) { | ||
232 | r = SSH_ERR_ALLOC_FAIL; | ||
233 | goto out; | ||
234 | } | ||
235 | if ((r = kexc25519_shared_key_ext(kex->c25519_client_key, pkblob, | ||
236 | buf, 0)) < 0) | ||
237 | goto out; | ||
238 | #ifdef DEBUG_KEXECDH | ||
239 | dump_digest("encoded shared secret:", sshbuf_ptr(buf), sshbuf_len(buf)); | ||
240 | #endif | ||
241 | *shared_secretp = buf; | ||
242 | buf = NULL; | ||
243 | out: | ||
244 | sshbuf_free(buf); | ||
245 | return r; | ||
246 | } | ||