1 /* $OpenBSD: kexc25519s.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */
2 /*
3  * Copyright (c) 2001 Markus Friedl.  All rights reserved.
4  * Copyright (c) 2010 Damien Miller.  All rights reserved.
5  * Copyright (c) 2013 Aris Adamantiadis.  All rights reserved.
6  *
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 #include "includes.h"
28 
29 #include <sys/types.h>
30 #include <string.h>
31 #include <signal.h>
32 
33 #include "xmalloc.h"
34 #include "buffer.h"
35 #include "key.h"
36 #include "cipher.h"
37 #include "kex.h"
38 #include "log.h"
39 #include "packet.h"
40 #include "ssh2.h"
41 
42 void
kexc25519_server(Kex * kex)43 kexc25519_server(Kex *kex)
44 {
45 	Key *server_host_private, *server_host_public;
46 	u_char *server_host_key_blob = NULL, *signature = NULL;
47 	u_char server_key[CURVE25519_SIZE];
48 	u_char *client_pubkey = NULL;
49 	u_char server_pubkey[CURVE25519_SIZE];
50 	u_char *hash;
51 	u_int slen, sbloblen, hashlen;
52 	Buffer shared_secret;
53 
54 	/* generate private key */
55 	kexc25519_keygen(server_key, server_pubkey);
56 #ifdef DEBUG_KEXECDH
57 	dump_digest("server private key:", server_key, sizeof(server_key));
58 #endif
59 
60 	if (kex->load_host_public_key == NULL ||
61 	    kex->load_host_private_key == NULL)
62 		fatal("Cannot load hostkey");
63 	server_host_public = kex->load_host_public_key(kex->hostkey_type);
64 	if (server_host_public == NULL)
65 		fatal("Unsupported hostkey type %d", kex->hostkey_type);
66 	server_host_private = kex->load_host_private_key(kex->hostkey_type);
67 
68 	debug("expecting SSH2_MSG_KEX_ECDH_INIT");
69 	packet_read_expect(SSH2_MSG_KEX_ECDH_INIT);
70 	client_pubkey = packet_get_string(&slen);
71 	if (slen != CURVE25519_SIZE)
72 		fatal("Incorrect size for server Curve25519 pubkey: %d", slen);
73 	packet_check_eom();
74 
75 #ifdef DEBUG_KEXECDH
76 	dump_digest("client public key:", client_pubkey, CURVE25519_SIZE);
77 #endif
78 
79 	buffer_init(&shared_secret);
80 	kexc25519_shared_key(server_key, client_pubkey, &shared_secret);
81 
82 	/* calc H */
83 	key_to_blob(server_host_public, &server_host_key_blob, &sbloblen);
84 	kex_c25519_hash(
85 	    kex->hash_alg,
86 	    kex->client_version_string,
87 	    kex->server_version_string,
88 	    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
89 	    buffer_ptr(&kex->my), buffer_len(&kex->my),
90 	    server_host_key_blob, sbloblen,
91 	    client_pubkey,
92 	    server_pubkey,
93 	    buffer_ptr(&shared_secret), buffer_len(&shared_secret),
94 	    &hash, &hashlen
95 	);
96 
97 	/* save session id := H */
98 	if (kex->session_id == NULL) {
99 		kex->session_id_len = hashlen;
100 		kex->session_id = xmalloc(kex->session_id_len);
101 		memcpy(kex->session_id, hash, kex->session_id_len);
102 	}
103 
104 	/* sign H */
105 	kex->sign(server_host_private, server_host_public, &signature, &slen,
106 	    hash, hashlen);
107 
108 	/* destroy_sensitive_data(); */
109 
110 	/* send server hostkey, ECDH pubkey 'Q_S' and signed H */
111 	packet_start(SSH2_MSG_KEX_ECDH_REPLY);
112 	packet_put_string(server_host_key_blob, sbloblen);
113 	packet_put_string(server_pubkey, sizeof(server_pubkey));
114 	packet_put_string(signature, slen);
115 	packet_send();
116 
117 	free(signature);
118 	free(server_host_key_blob);
119 	/* have keys, free server key */
120 	free(client_pubkey);
121 
122 	kex_derive_keys(kex, hash, hashlen,
123 	    buffer_ptr(&shared_secret), buffer_len(&shared_secret));
124 	buffer_free(&shared_secret);
125 	kex_finish(kex);
126 }
127