summaryrefslogtreecommitdiff
path: root/kexc25519.c
diff options
context:
space:
mode:
Diffstat (limited to 'kexc25519.c')
-rw-r--r--kexc25519.c122
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
47extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], 43extern 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
142int
143kex_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
164int
165kex_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
214int
215kex_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}