drm/i915: Reduce differences with Linux in i915_gem_fault()
[dragonfly.git] / crypto / openssh / kexc25519s.c
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
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 }