1f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/*
2f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Dropbear SSH
3f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
4f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Copyright (c) 2002-2004 Matt Johnston
5f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Portions Copyright (c) 2004 by Mihnea Stoenescu
6f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * All rights reserved.
7f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
8f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Permission is hereby granted, free of charge, to any person obtaining a copy
9f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * of this software and associated documentation files (the "Software"), to deal
10f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * in the Software without restriction, including without limitation the rights
11f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * copies of the Software, and to permit persons to whom the Software is
13f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * furnished to do so, subject to the following conditions:
14f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
15f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The above copyright notice and this permission notice shall be included in
16f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * all copies or substantial portions of the Software.
17f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
18f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * SOFTWARE. */
25f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
26f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "includes.h"
27f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "dbutil.h"
28f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "algo.h"
29f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "buffer.h"
30f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "session.h"
31f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "kex.h"
32f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "ssh.h"
33f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "packet.h"
34f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "bignum.h"
35f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#include "random.h"
36f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
37f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* diffie-hellman-group1-sha1 value for p */
38f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic const unsigned char dh_p_val[] = {
39f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
40f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
41f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
42f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
43f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
44f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
45f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
46f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
47f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
48f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
49f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
50f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#define DH_P_LEN sizeof(dh_p_val)
51f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
52f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic const int DH_G_VAL = 2;
53f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
54f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void kexinitialise();
55f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid gen_new_keys();
56f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef DISABLE_ZLIB
57f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void gen_new_zstreams();
58f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
59f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void read_kex_algos();
60f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* helper function for gen_new_keys */
61f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void hashkeys(unsigned char *out, int outlen,
62f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		const hash_state * hs, unsigned const char X);
63f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
64f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
65f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Send our list of algorithms we can use */
66f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid send_msg_kexinit() {
67f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
68f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	CHECKCLEARTOWRITE();
69f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT);
70f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
71f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* cookie */
72f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	genrandom(buf_getwriteptr(ses.writepayload, 16), 16);
73f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_incrwritepos(ses.writepayload, 16);
74f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
75f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* kex algos */
76f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshkex);
77f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
78f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* server_host_key_algorithms */
79f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshhostkey);
80f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
81f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* encryption_algorithms_client_to_server */
82f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshciphers);
83f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
84f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* encryption_algorithms_server_to_client */
85f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshciphers);
86f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
87f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* mac_algorithms_client_to_server */
88f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshhashes);
89f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
90f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* mac_algorithms_server_to_client */
91f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshhashes);
92f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
93f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* compression_algorithms_client_to_server */
94f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshcompress);
95f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
96f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* compression_algorithms_server_to_client */
97f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_algolist(ses.writepayload, sshcompress);
98f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
99f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* languages_client_to_server */
100f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putstring(ses.writepayload, "", 0);
101f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
102f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* languages_server_to_client */
103f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putstring(ses.writepayload, "", 0);
104f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
105f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* first_kex_packet_follows - unimplemented for now */
106f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putbyte(ses.writepayload, 0x00);
107f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
108f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* reserved unit32 */
109f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putint(ses.writepayload, 0);
110f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
111f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* set up transmitted kex packet buffer for hashing.
112f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * This is freed after the end of the kex */
113f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.transkexinit = buf_newcopy(ses.writepayload);
114f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
115f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	encrypt_packet();
116f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.dataallowed = 0; /* don't send other packets during kex */
117f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
118f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("DATAALLOWED=0"))
119f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("-> KEXINIT"))
120f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.sentkexinit = 1;
121f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
122f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
123f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* *** NOTE regarding (send|recv)_msg_newkeys ***
124f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * Changed by mihnea from the original kex.c to set dataallowed after a
125f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * completed key exchange, no matter the order in which it was performed.
126f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * This enables client mode without affecting server functionality.
127f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project */
128f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
129f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Bring new keys into use after a key exchange, and let the client know*/
130f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid send_msg_newkeys() {
131f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
132f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("enter send_msg_newkeys"))
133f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
134f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* generate the kexinit request */
135f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	CHECKCLEARTOWRITE();
136f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS);
137f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	encrypt_packet();
138f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
139f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
140f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* set up our state */
141f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ses.kexstate.recvnewkeys) {
142f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		TRACE(("while RECVNEWKEYS=1"))
143f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		gen_new_keys();
144f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		kexinitialise(); /* we've finished with this kex */
145f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		TRACE((" -> DATAALLOWED=1"))
146f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.dataallowed = 1; /* we can send other packets again now */
147f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.kexstate.donefirstkex = 1;
148f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
149f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.kexstate.sentnewkeys = 1;
150f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		TRACE(("SENTNEWKEYS=1"))
151f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
152f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
153f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("-> MSG_NEWKEYS"))
154f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("leave send_msg_newkeys"))
155f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
156f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
157f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Bring the new keys into use after a key exchange */
158f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid recv_msg_newkeys() {
159f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
160f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("<- MSG_NEWKEYS"))
161f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("enter recv_msg_newkeys"))
162f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
163f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* simply check if we've sent SSH_MSG_NEWKEYS, and if so,
164f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * switch to the new keys */
165f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ses.kexstate.sentnewkeys) {
166f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		TRACE(("while SENTNEWKEYS=1"))
167f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		gen_new_keys();
168f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		kexinitialise(); /* we've finished with this kex */
169f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    TRACE((" -> DATAALLOWED=1"))
170f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    ses.dataallowed = 1; /* we can send other packets again now */
171f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.kexstate.donefirstkex = 1;
172f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
173f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		TRACE(("RECVNEWKEYS=1"))
174f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.kexstate.recvnewkeys = 1;
175f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
176f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
177f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("leave recv_msg_newkeys"))
178f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
179f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
180f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
181f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Set up the kex for the first time */
182f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid kexfirstinitialise() {
183f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
184f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.donefirstkex = 0;
185f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	kexinitialise();
186f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
187f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
188f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Reset the kex state, ready for a new negotiation */
189f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void kexinitialise() {
190f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
191f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	struct timeval tv;
192f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
193f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("kexinitialise()"))
194f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
195f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* sent/recv'd MSG_KEXINIT */
196f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.sentkexinit = 0;
197f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.recvkexinit = 0;
198f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
199f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* sent/recv'd MSG_NEWKEYS */
200f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.recvnewkeys = 0;
201f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.sentnewkeys = 0;
202f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
203f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* first_packet_follows */
204f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.firstfollows = 0;
205f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
206f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.datatrans = 0;
207f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.datarecv = 0;
208f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
209f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (gettimeofday(&tv, 0) < 0) {
210f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("Error getting time");
211f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
212f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.lastkextime = tv.tv_sec;
213f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
214f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
215f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
216f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Helper function for gen_new_keys, creates a hash. It makes a copy of the
217f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * already initialised hash_state hs, which should already have processed
218f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
219f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
220f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * The output will only be expanded once, as we are assured that
221f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * outlen <= 2*SHA1_HASH_SIZE for all known hashes.
222f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
223f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * See Section 7.2 of rfc4253 (ssh transport) for details */
224f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void hashkeys(unsigned char *out, int outlen,
225f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		const hash_state * hs, const unsigned char X) {
226f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
227f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hash_state hs2;
228f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */
229f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
230f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	memcpy(&hs2, hs, sizeof(hash_state));
231f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_process(&hs2, &X, 1);
232f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE);
233f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_done(&hs2, out);
234f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (SHA1_HASH_SIZE < outlen) {
235f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* need to extend */
236f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		memcpy(&hs2, hs, sizeof(hash_state));
237f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		sha1_process(&hs2, out, SHA1_HASH_SIZE);
238f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		sha1_done(&hs2, k2);
239f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		memcpy(&out[SHA1_HASH_SIZE], k2, outlen - SHA1_HASH_SIZE);
240f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
241f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
242f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
243f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Generate the actual encryption/integrity keys, using the results of the
244f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * key exchange, as specified in section 5.2 of the IETF secsh-transport
245f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * draft. This occurs after the DH key-exchange.
246f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project *
247f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * ses.newkeys is the new set of keys which are generated, these are only
248f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * taken into use after both sides have sent a newkeys message */
249f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
250f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Originally from kex.c, generalized for cli/svr mode --mihnea */
251f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid gen_new_keys() {
252f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
253f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned char C2S_IV[MAX_IV_LEN];
254f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned char C2S_key[MAX_KEY_LEN];
255f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned char S2C_IV[MAX_IV_LEN];
256f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned char S2C_key[MAX_KEY_LEN];
257f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* unsigned char key[MAX_KEY_LEN]; */
258f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key;
259f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
260f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hash_state hs;
261f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned int C2S_keysize, S2C_keysize;
262f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	char mactransletter, macrecvletter; /* Client or server specific */
263f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int recv_cipher = 0, trans_cipher = 0;
264f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
265f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("enter gen_new_keys"))
266f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* the dh_K and hash are the start of all hashes, we make use of that */
267f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
268f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_init(&hs);
269f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_process_mp(&hs, ses.dh_K);
270f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	mp_clear(ses.dh_K);
271f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	m_free(ses.dh_K);
272f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_process(&hs, ses.hash, SHA1_HASH_SIZE);
273f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	m_burn(ses.hash, SHA1_HASH_SIZE);
274f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
275f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (IS_DROPBEAR_CLIENT) {
276f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    trans_IV	= C2S_IV;
277f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    recv_IV		= S2C_IV;
278f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    trans_key	= C2S_key;
279f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    recv_key	= S2C_key;
280f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    C2S_keysize = ses.newkeys->trans_algo_crypt->keysize;
281f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    S2C_keysize = ses.newkeys->recv_algo_crypt->keysize;
282f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		mactransletter = 'E';
283f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		macrecvletter = 'F';
284f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
285f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    trans_IV	= S2C_IV;
286f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    recv_IV		= C2S_IV;
287f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    trans_key	= S2C_key;
288f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    recv_key	= C2S_key;
289f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    C2S_keysize = ses.newkeys->recv_algo_crypt->keysize;
290f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    S2C_keysize = ses.newkeys->trans_algo_crypt->keysize;
291f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		mactransletter = 'F';
292f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		macrecvletter = 'E';
293f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
294f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
295f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A');
296f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B');
297f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hashkeys(C2S_key, C2S_keysize, &hs, 'C');
298f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hashkeys(S2C_key, S2C_keysize, &hs, 'D');
299f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
300f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	recv_cipher = find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name);
301f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (recv_cipher < 0)
302f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    dropbear_exit("crypto error");
303f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
304f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (cbc_start(recv_cipher, recv_IV, recv_key,
305f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.newkeys->recv_algo_crypt->keysize, 0,
306f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			&ses.newkeys->recv_symmetric_struct) != CRYPT_OK) {
307f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("crypto error");
308f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
309f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	trans_cipher = find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name);
310f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (trans_cipher < 0)
311f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    dropbear_exit("crypto error");
312f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
313f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (cbc_start(trans_cipher, trans_IV, trans_key,
314f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.newkeys->trans_algo_crypt->keysize, 0,
315f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			&ses.newkeys->trans_symmetric_struct) != CRYPT_OK) {
316f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("crypto error");
317f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
318f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
319f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* MAC keys */
320f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hashkeys(ses.newkeys->transmackey,
321f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.newkeys->trans_algo_mac->keysize, &hs, mactransletter);
322f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hashkeys(ses.newkeys->recvmackey,
323f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.newkeys->recv_algo_mac->keysize, &hs, macrecvletter);
324f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
325f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef DISABLE_ZLIB
326f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	gen_new_zstreams();
327f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
328f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
329f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Switch over to the new keys */
330f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	m_burn(ses.keys, sizeof(struct key_context));
331f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	m_free(ses.keys);
332f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.keys = ses.newkeys;
333f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.newkeys = NULL;
334f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
335f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("leave gen_new_keys"))
336f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
337f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
338f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#ifndef DISABLE_ZLIB
339f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Set up new zlib compression streams, close the old ones. Only
340f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * called from gen_new_keys() */
341f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void gen_new_zstreams() {
342f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
343f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* create new zstreams */
344f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB) {
345f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream));
346f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_zstream->zalloc = Z_NULL;
347f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_zstream->zfree = Z_NULL;
348f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
349f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) {
350f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			dropbear_exit("zlib error");
351f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
352f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
353f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_zstream = NULL;
354f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
355f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
356f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB) {
357f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream));
358f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_zstream->zalloc = Z_NULL;
359f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_zstream->zfree = Z_NULL;
360f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
361f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION)
362f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				!= Z_OK) {
363f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			dropbear_exit("zlib error");
364f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
365f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
366f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_zstream = NULL;
367f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
368f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
369f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* clean up old keys */
370f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ses.keys->recv_zstream != NULL) {
371f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) {
372f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
373f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			dropbear_exit("crypto error");
374f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
375f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		m_free(ses.keys->recv_zstream);
376f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
377f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ses.keys->trans_zstream != NULL) {
378f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (deflateEnd(ses.keys->trans_zstream) == Z_STREAM_ERROR) {
379f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			/* Z_DATA_ERROR is ok, just means that stream isn't ended */
380f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			dropbear_exit("crypto error");
381f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
382f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		m_free(ses.keys->trans_zstream);
383f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
384f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
385f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project#endif
386f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
387f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
388f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Executed upon receiving a kexinit message from the client to initiate
389f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * key exchange. If we haven't already done so, we send the list of our
390f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * preferred algorithms. The client's requested algorithms are processed,
391f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * and we calculate the first portion of the key-exchange-hash for used
392f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * later in the key exchange. No response is sent, as the client should
393f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * initiate the diffie-hellman key exchange */
394f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
395f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Originally from kex.c, generalized for cli/svr mode --mihnea  */
396f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Belongs in common_kex.c where it should be moved after review */
397f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid recv_msg_kexinit() {
398f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
399f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned int kexhashbuf_len = 0;
400f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned int remote_ident_len = 0;
401f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	unsigned int local_ident_len = 0;
402f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
403f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("<- KEXINIT"))
404f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("enter recv_msg_kexinit"))
405f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
406f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (!ses.kexstate.sentkexinit) {
407f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* we need to send a kex packet */
408f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		send_msg_kexinit();
409f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		TRACE(("continue recv_msg_kexinit: sent kexinit"))
410f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
411f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
412f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* start the kex hash */
413f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	local_ident_len = strlen(LOCAL_IDENT);
414f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	remote_ident_len = strlen((char*)ses.remoteident);
415f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
416f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	kexhashbuf_len = local_ident_len + remote_ident_len
417f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		+ ses.transkexinit->len + ses.payload->len
418f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		+ KEXHASHBUF_MAX_INTS;
419f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
420f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexhashbuf = buf_new(kexhashbuf_len);
421f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
422f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (IS_DROPBEAR_CLIENT) {
423f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
424f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* read the peer's choice of algos */
425f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		read_kex_algos();
426f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
427f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* V_C, the client's version string (CR and NL excluded) */
428f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf,
429f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(unsigned char*)LOCAL_IDENT, local_ident_len);
430f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* V_S, the server's version string (CR and NL excluded) */
431f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
432f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
433f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
434f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf,
435f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.transkexinit->data, ses.transkexinit->len);
436f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
437f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_setpos(ses.payload, 0);
438f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
439f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
440f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
441f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* SERVER */
442f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
443f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* read the peer's choice of algos */
444f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		read_kex_algos();
445f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* V_C, the client's version string (CR and NL excluded) */
446f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len);
447f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* V_S, the server's version string (CR and NL excluded) */
448f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf,
449f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project				(unsigned char*)LOCAL_IDENT, local_ident_len);
450f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
451f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* I_C, the payload of the client's SSH_MSG_KEXINIT */
452f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_setpos(ses.payload, 0);
453f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len);
454f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
455f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* I_S, the payload of the server's SSH_MSG_KEXINIT */
456f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	    buf_putstring(ses.kexhashbuf,
457f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.transkexinit->data, ses.transkexinit->len);
458f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
459f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.requirenext = SSH_MSG_KEXDH_INIT;
460f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
461f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
462f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_free(ses.transkexinit);
463f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.transkexinit = NULL;
464f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* the rest of ses.kexhashbuf will be done after DH exchange */
465f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
466f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexstate.recvkexinit = 1;
467f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
468f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("leave recv_msg_kexinit"))
469f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
470f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
471f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* Initialises and generate one side of the diffie-hellman key exchange values.
472f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * See the ietf-secsh-transport draft, section 6, for details */
473f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* dh_pub and dh_priv MUST be already initialised */
474f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) {
475f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
476f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	DEF_MP_INT(dh_p);
477f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	DEF_MP_INT(dh_q);
478f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	DEF_MP_INT(dh_g);
479f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
480f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("enter send_msg_kexdh_reply"))
481f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
482f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL);
483f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
484f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* read the prime and generator*/
485f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	bytes_to_mp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN);
486f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
487f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) {
488f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("Diffie-Hellman error");
489f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
490f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
491f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* calculate q = (p-1)/2 */
492f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* dh_priv is just a temp var here */
493f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (mp_sub_d(&dh_p, 1, dh_priv) != MP_OKAY) {
494f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("Diffie-Hellman error");
495f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
496f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (mp_div_2(dh_priv, &dh_q) != MP_OKAY) {
497f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("Diffie-Hellman error");
498f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
499f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
500f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Generate a private portion 0 < dh_priv < dh_q */
501f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	gen_random_mpint(&dh_q, dh_priv);
502f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
503f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* f = g^y mod p */
504f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) {
505f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("Diffie-Hellman error");
506f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
507f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL);
508f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
509f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
510f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* This function is fairly common between client/server, with some substitution
511f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * of dh_e/dh_f etc. Hence these arguments:
512f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is
513f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */
514f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectvoid kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them,
515f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		sign_key *hostkey) {
516f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
517f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	mp_int dh_p;
518f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	mp_int *dh_e = NULL, *dh_f = NULL;
519f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	hash_state hs;
520f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
521f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* read the prime and generator*/
522f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	m_mp_init(&dh_p);
523f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN);
524f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
525f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */
526f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (mp_cmp(dh_pub_them, &dh_p) != MP_LT
527f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			|| mp_cmp_d(dh_pub_them, 0) != MP_GT) {
528f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("Diffie-Hellman error");
529f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
530f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
531f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* K = e^y mod p = f^x mod p */
532f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int));
533f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	m_mp_init(ses.dh_K);
534f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (mp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != MP_OKAY) {
535f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dropbear_exit("Diffie-Hellman error");
536f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
537f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
538f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* clear no longer needed vars */
539f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	mp_clear_multi(&dh_p, NULL);
540f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
541f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* From here on, the code needs to work with the _same_ vars on each side,
542f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	 * not vice-versaing for client/server */
543f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (IS_DROPBEAR_CLIENT) {
544f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dh_e = dh_pub_us;
545f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dh_f = dh_pub_them;
546f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
547f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dh_e = dh_pub_them;
548f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		dh_f = dh_pub_us;
549f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
550f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
551f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Create the remainder of the hash buffer, to generate the exchange hash */
552f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* K_S, the host key */
553f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey);
554f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* e, exchange value sent by the client */
555f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putmpint(ses.kexhashbuf, dh_e);
556f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* f, exchange value sent by the server */
557f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putmpint(ses.kexhashbuf, dh_f);
558f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* K, the shared secret */
559f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_putmpint(ses.kexhashbuf, ses.dh_K);
560f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
561f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* calculate the hash H to sign */
562f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_init(&hs);
563f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_setpos(ses.kexhashbuf, 0);
564f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len),
565f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.kexhashbuf->len);
566f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	sha1_done(&hs, ses.hash);
567f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
568f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_burn(ses.kexhashbuf);
569f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_free(ses.kexhashbuf);
570f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.kexhashbuf = NULL;
571f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
572f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* first time around, we set the session_id to H */
573f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (ses.session_id == NULL) {
574f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* create the session_id, this never needs freeing */
575f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE);
576f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE);
577f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
578f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
579f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
580f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project/* read the other side's algo list. buf_match_algo is a callback to match
581f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project * algos for the client or server. */
582f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projectstatic void read_kex_algos() {
583f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
584f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* for asymmetry */
585f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo_type * c2s_hash_algo = NULL;
586f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo_type * s2c_hash_algo = NULL;
587f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo_type * c2s_cipher_algo = NULL;
588f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo_type * s2c_cipher_algo = NULL;
589f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo_type * c2s_comp_algo = NULL;
590f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo_type * s2c_comp_algo = NULL;
591f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* the generic one */
592f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo_type * algo = NULL;
593f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
594f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* which algo couldn't match */
595f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	char * erralgo = NULL;
596f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
597f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int goodguess = 0;
598f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	int allgood = 1; /* we AND this with each goodguess and see if its still
599f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project						true after */
600f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
601f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_incrpos(ses.payload, 16); /* start after the cookie */
602f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
603f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context));
604f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
605f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* kex_algorithms */
606f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo = ses.buf_match_algo(ses.payload, sshkex, &goodguess);
607f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	allgood &= goodguess;
608f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (algo == NULL) {
609f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "kex";
610f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
611f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
612f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("kex algo %s", algo->name))
613f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.newkeys->algo_kex = algo->val;
614f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
615f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* server_host_key_algorithms */
616f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	algo = ses.buf_match_algo(ses.payload, sshhostkey, &goodguess);
617f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	allgood &= goodguess;
618f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (algo == NULL) {
619f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "hostkey";
620f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
621f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
622f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("hostkey algo %s", algo->name))
623f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	ses.newkeys->algo_hostkey = algo->val;
624f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
625f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* encryption_algorithms_client_to_server */
626f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess);
627f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (c2s_cipher_algo == NULL) {
628f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "enc c->s";
629f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
630f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
631f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("enc c2s is  %s", c2s_cipher_algo->name))
632f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
633f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* encryption_algorithms_server_to_client */
634f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess);
635f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (s2c_cipher_algo == NULL) {
636f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "enc s->c";
637f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
638f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
639f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("enc s2c is  %s", s2c_cipher_algo->name))
640f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
641f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* mac_algorithms_client_to_server */
642f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
643f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (c2s_hash_algo == NULL) {
644f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "mac c->s";
645f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
646f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
647f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("hash c2s is  %s", c2s_hash_algo->name))
648f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
649f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* mac_algorithms_server_to_client */
650f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess);
651f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (s2c_hash_algo == NULL) {
652f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "mac s->c";
653f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
654f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
655f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("hash s2c is  %s", s2c_hash_algo->name))
656f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
657f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* compression_algorithms_client_to_server */
658f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
659f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (c2s_comp_algo == NULL) {
660f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "comp c->s";
661f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
662f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
663f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("hash c2s is  %s", c2s_comp_algo->name))
664f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
665f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* compression_algorithms_server_to_client */
666f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess);
667f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (s2c_comp_algo == NULL) {
668f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		erralgo = "comp s->c";
669f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		goto error;
670f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
671f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	TRACE(("hash s2c is  %s", s2c_comp_algo->name))
672f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
673f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* languages_client_to_server */
674f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_eatstring(ses.payload);
675f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
676f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* languages_server_to_client */
677f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_eatstring(ses.payload);
678f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
679f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* first_kex_packet_follows */
680f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (buf_getbool(ses.payload)) {
681f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.kexstate.firstfollows = 1;
682f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* if the guess wasn't good, we ignore the packet sent */
683f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		if (!allgood) {
684f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			ses.ignorenext = 1;
685f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		}
686f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
687f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
688f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* Handle the asymmetry */
689f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	if (IS_DROPBEAR_CLIENT) {
690f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_algo_crypt =
691f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_cipher*)s2c_cipher_algo->data;
692f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_algo_crypt =
693f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_cipher*)c2s_cipher_algo->data;
694f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_algo_mac =
695f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_hash*)s2c_hash_algo->data;
696f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_algo_mac =
697f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_hash*)c2s_hash_algo->data;
698f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_algo_comp = s2c_comp_algo->val;
699f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_algo_comp = c2s_comp_algo->val;
700f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	} else {
701f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		/* SERVER */
702f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_algo_crypt =
703f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_cipher*)c2s_cipher_algo->data;
704f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_algo_crypt =
705f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_cipher*)s2c_cipher_algo->data;
706f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_algo_mac =
707f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_hash*)c2s_hash_algo->data;
708f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_algo_mac =
709f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project			(struct dropbear_hash*)s2c_hash_algo->data;
710f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->recv_algo_comp = c2s_comp_algo->val;
711f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project		ses.newkeys->trans_algo_comp = s2c_comp_algo->val;
712f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	}
713f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
714f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	/* reserved for future extensions */
715f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	buf_getint(ses.payload);
716f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	return;
717f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project
718f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Projecterror:
719f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project	dropbear_exit("no matching algo %s", erralgo);
720f7fc46c63fdc8f39234fea409b8dbe116d73ebf8The Android Open Source Project}
721