4 * Copyright (c) 2002-2004 Matt Johnston
5 * Portions Copyright (c) 2004 by Mihnea Stoenescu
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
38 #include "crypto_desc.h"
40 /* diffie-hellman-group1-sha1 value for p */
41 const unsigned char dh_p_1
[DH_P_1_LEN
] = {
42 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
43 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
44 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
45 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
46 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
47 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
48 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
49 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
50 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
51 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
52 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
54 /* diffie-hellman-group14-sha1 value for p */
55 const unsigned char dh_p_14
[DH_P_14_LEN
] = {
56 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
57 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
58 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
59 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
60 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
61 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
62 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
63 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
64 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
65 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
66 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
67 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
68 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
69 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
70 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
71 0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
72 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
73 0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
74 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
75 0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
76 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
77 0xFF, 0xFF, 0xFF, 0xFF};
79 /* Same for group1 and group14 */
80 static const int DH_G_VAL
= 2;
82 static void kexinitialise();
83 static void gen_new_keys();
85 static void gen_new_zstream_recv();
86 static void gen_new_zstream_trans();
88 static void read_kex_algos();
89 /* helper function for gen_new_keys */
90 static void hashkeys(unsigned char *out
, unsigned int outlen
,
91 const hash_state
* hs
, const unsigned char X
);
92 static void finish_kexhashbuf(void);
95 /* Send our list of algorithms we can use */
96 void send_msg_kexinit() {
99 buf_putbyte(ses
.writepayload
, SSH_MSG_KEXINIT
);
102 genrandom(buf_getwriteptr(ses
.writepayload
, 16), 16);
103 buf_incrwritepos(ses
.writepayload
, 16);
106 buf_put_algolist(ses
.writepayload
, sshkex
);
108 /* server_host_key_algorithms */
109 buf_put_algolist(ses
.writepayload
, sshhostkey
);
111 /* encryption_algorithms_client_to_server */
112 buf_put_algolist(ses
.writepayload
, sshciphers
);
114 /* encryption_algorithms_server_to_client */
115 buf_put_algolist(ses
.writepayload
, sshciphers
);
117 /* mac_algorithms_client_to_server */
118 buf_put_algolist(ses
.writepayload
, sshhashes
);
120 /* mac_algorithms_server_to_client */
121 buf_put_algolist(ses
.writepayload
, sshhashes
);
124 /* compression_algorithms_client_to_server */
125 buf_put_algolist(ses
.writepayload
, ses
.compress_algos
);
127 /* compression_algorithms_server_to_client */
128 buf_put_algolist(ses
.writepayload
, ses
.compress_algos
);
130 /* languages_client_to_server */
131 buf_putstring(ses
.writepayload
, "", 0);
133 /* languages_server_to_client */
134 buf_putstring(ses
.writepayload
, "", 0);
136 /* first_kex_packet_follows */
137 buf_putbyte(ses
.writepayload
, (ses
.send_kex_first_guess
!= NULL
));
139 /* reserved unit32 */
140 buf_putint(ses
.writepayload
, 0);
142 /* set up transmitted kex packet buffer for hashing.
143 * This is freed after the end of the kex */
144 ses
.transkexinit
= buf_newcopy(ses
.writepayload
);
147 ses
.dataallowed
= 0; /* don't send other packets during kex */
149 ses
.kexstate
.sentkexinit
= 1;
151 ses
.newkeys
= (struct key_context
*)m_malloc(sizeof(struct key_context
));
153 if (ses
.send_kex_first_guess
) {
154 ses
.newkeys
->algo_kex
= sshkex
[0].data
;
155 ses
.newkeys
->algo_hostkey
= sshhostkey
[0].val
;
156 ses
.send_kex_first_guess();
159 TRACE(("DATAALLOWED=0"))
160 TRACE(("-> KEXINIT"))
164 static void switch_keys() {
165 TRACE2(("enter switch_keys"))
166 if (!(ses
.kexstate
.sentkexinit
&& ses
.kexstate
.recvkexinit
)) {
167 dropbear_exit("Unexpected newkeys message");
171 ses
.keys
= m_malloc(sizeof(*ses
.newkeys
));
173 if (ses
.kexstate
.recvnewkeys
&& ses
.newkeys
->recv
.valid
) {
174 TRACE(("switch_keys recv"))
176 gen_new_zstream_recv();
178 ses
.keys
->recv
= ses
.newkeys
->recv
;
179 m_burn(&ses
.newkeys
->recv
, sizeof(ses
.newkeys
->recv
));
180 ses
.newkeys
->recv
.valid
= 0;
182 if (ses
.kexstate
.sentnewkeys
&& ses
.newkeys
->trans
.valid
) {
183 TRACE(("switch_keys trans"))
185 gen_new_zstream_trans();
187 ses
.keys
->trans
= ses
.newkeys
->trans
;
188 m_burn(&ses
.newkeys
->trans
, sizeof(ses
.newkeys
->trans
));
189 ses
.newkeys
->trans
.valid
= 0;
191 if (ses
.kexstate
.sentnewkeys
&& ses
.kexstate
.recvnewkeys
)
193 TRACE(("switch_keys done"))
194 ses
.keys
->algo_kex
= ses
.newkeys
->algo_kex
;
195 ses
.keys
->algo_hostkey
= ses
.newkeys
->algo_hostkey
;
196 ses
.keys
->allow_compress
= 0;
201 TRACE2(("leave switch_keys"))
204 /* Bring new keys into use after a key exchange, and let the client know*/
205 void send_msg_newkeys() {
207 TRACE(("enter send_msg_newkeys"))
209 /* generate the kexinit request */
211 buf_putbyte(ses
.writepayload
, SSH_MSG_NEWKEYS
);
215 /* set up our state */
216 ses
.kexstate
.sentnewkeys
= 1;
217 ses
.kexstate
.donefirstkex
= 1;
218 ses
.dataallowed
= 1; /* we can send other packets again now */
222 TRACE(("leave send_msg_newkeys"))
225 /* Bring the new keys into use after a key exchange */
226 void recv_msg_newkeys() {
228 TRACE(("enter recv_msg_newkeys"))
230 ses
.kexstate
.recvnewkeys
= 1;
233 TRACE(("leave recv_msg_newkeys"))
237 /* Set up the kex for the first time */
238 void kexfirstinitialise() {
239 ses
.kexstate
.donefirstkex
= 0;
242 if (opts
.enable_compress
) {
243 ses
.compress_algos
= ssh_compress
;
247 ses
.compress_algos
= ssh_nocompress
;
252 /* Reset the kex state, ready for a new negotiation */
253 static void kexinitialise() {
255 TRACE(("kexinitialise()"))
257 /* sent/recv'd MSG_KEXINIT */
258 ses
.kexstate
.sentkexinit
= 0;
259 ses
.kexstate
.recvkexinit
= 0;
261 /* sent/recv'd MSG_NEWKEYS */
262 ses
.kexstate
.recvnewkeys
= 0;
263 ses
.kexstate
.sentnewkeys
= 0;
265 /* first_packet_follows */
266 ses
.kexstate
.them_firstfollows
= 0;
268 ses
.kexstate
.datatrans
= 0;
269 ses
.kexstate
.datarecv
= 0;
271 ses
.kexstate
.our_first_follows_matches
= 0;
273 ses
.kexstate
.lastkextime
= time(NULL
);
277 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the
278 * already initialised hash_state hs, which should already have processed
279 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
280 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
282 * See Section 7.2 of rfc4253 (ssh transport) for details */
283 static void hashkeys(unsigned char *out
, unsigned int outlen
,
284 const hash_state
* hs
, const unsigned char X
) {
286 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
289 unsigned char tmpout
[MAX_HASH_SIZE
];
291 memcpy(&hs2
, hs
, sizeof(hash_state
));
292 hash_desc
->process(&hs2
, &X
, 1);
293 hash_desc
->process(&hs2
, ses
.session_id
->data
, ses
.session_id
->len
);
294 hash_desc
->done(&hs2
, tmpout
);
295 memcpy(out
, tmpout
, MIN(hash_desc
->hashsize
, outlen
));
296 for (offset
= hash_desc
->hashsize
;
298 offset
+= hash_desc
->hashsize
)
301 memcpy(&hs2
, hs
, sizeof(hash_state
));
302 hash_desc
->process(&hs2
, out
, offset
);
303 hash_desc
->done(&hs2
, tmpout
);
304 memcpy(&out
[offset
], tmpout
, MIN(outlen
- offset
, hash_desc
->hashsize
));
309 /* Generate the actual encryption/integrity keys, using the results of the
310 * key exchange, as specified in section 7.2 of the transport rfc 4253.
311 * This occurs after the DH key-exchange.
313 * ses.newkeys is the new set of keys which are generated, these are only
314 * taken into use after both sides have sent a newkeys message */
316 static void gen_new_keys() {
318 unsigned char C2S_IV
[MAX_IV_LEN
];
319 unsigned char C2S_key
[MAX_KEY_LEN
];
320 unsigned char S2C_IV
[MAX_IV_LEN
];
321 unsigned char S2C_key
[MAX_KEY_LEN
];
322 /* unsigned char key[MAX_KEY_LEN]; */
323 unsigned char *trans_IV
, *trans_key
, *recv_IV
, *recv_key
;
326 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
327 char mactransletter
, macrecvletter
; /* Client or server specific */
329 TRACE(("enter gen_new_keys"))
330 /* the dh_K and hash are the start of all hashes, we make use of that */
332 hash_desc
->init(&hs
);
333 hash_process_mp(hash_desc
, &hs
, ses
.dh_K
);
336 hash_desc
->process(&hs
, ses
.hash
->data
, ses
.hash
->len
);
341 if (IS_DROPBEAR_CLIENT
) {
346 mactransletter
= 'E';
353 mactransletter
= 'F';
357 hashkeys(C2S_IV
, sizeof(C2S_IV
), &hs
, 'A');
358 hashkeys(S2C_IV
, sizeof(S2C_IV
), &hs
, 'B');
359 hashkeys(C2S_key
, sizeof(C2S_key
), &hs
, 'C');
360 hashkeys(S2C_key
, sizeof(S2C_key
), &hs
, 'D');
362 if (ses
.newkeys
->recv
.algo_crypt
->cipherdesc
!= NULL
) {
363 int recv_cipher
= find_cipher(ses
.newkeys
->recv
.algo_crypt
->cipherdesc
->name
);
365 dropbear_exit("Crypto error");
366 if (ses
.newkeys
->recv
.crypt_mode
->start(recv_cipher
,
368 ses
.newkeys
->recv
.algo_crypt
->keysize
, 0,
369 &ses
.newkeys
->recv
.cipher_state
) != CRYPT_OK
) {
370 dropbear_exit("Crypto error");
374 if (ses
.newkeys
->trans
.algo_crypt
->cipherdesc
!= NULL
) {
375 int trans_cipher
= find_cipher(ses
.newkeys
->trans
.algo_crypt
->cipherdesc
->name
);
376 if (trans_cipher
< 0)
377 dropbear_exit("Crypto error");
378 if (ses
.newkeys
->trans
.crypt_mode
->start(trans_cipher
,
380 ses
.newkeys
->trans
.algo_crypt
->keysize
, 0,
381 &ses
.newkeys
->trans
.cipher_state
) != CRYPT_OK
) {
382 dropbear_exit("Crypto error");
386 if (ses
.newkeys
->trans
.algo_mac
->hash_desc
!= NULL
) {
387 hashkeys(ses
.newkeys
->trans
.mackey
,
388 ses
.newkeys
->trans
.algo_mac
->keysize
, &hs
, mactransletter
);
389 ses
.newkeys
->trans
.hash_index
= find_hash(ses
.newkeys
->trans
.algo_mac
->hash_desc
->name
);
392 if (ses
.newkeys
->recv
.algo_mac
->hash_desc
!= NULL
) {
393 hashkeys(ses
.newkeys
->recv
.mackey
,
394 ses
.newkeys
->recv
.algo_mac
->keysize
, &hs
, macrecvletter
);
395 ses
.newkeys
->recv
.hash_index
= find_hash(ses
.newkeys
->recv
.algo_mac
->hash_desc
->name
);
398 /* Ready to switch over */
399 ses
.newkeys
->trans
.valid
= 1;
400 ses
.newkeys
->recv
.valid
= 1;
402 m_burn(C2S_IV
, sizeof(C2S_IV
));
403 m_burn(C2S_key
, sizeof(C2S_key
));
404 m_burn(S2C_IV
, sizeof(S2C_IV
));
405 m_burn(S2C_key
, sizeof(S2C_key
));
407 TRACE(("leave gen_new_keys"))
412 int is_compress_trans() {
413 return ses
.keys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB
414 || (ses
.authstate
.authdone
415 && ses
.keys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
);
418 int is_compress_recv() {
419 return ses
.keys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB
420 || (ses
.authstate
.authdone
421 && ses
.keys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
);
424 /* Set up new zlib compression streams, close the old ones. Only
425 * called from gen_new_keys() */
426 static void gen_new_zstream_recv() {
428 /* create new zstreams */
429 if (ses
.newkeys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB
430 || ses
.newkeys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
) {
431 ses
.newkeys
->recv
.zstream
= (z_streamp
)m_malloc(sizeof(z_stream
));
432 ses
.newkeys
->recv
.zstream
->zalloc
= Z_NULL
;
433 ses
.newkeys
->recv
.zstream
->zfree
= Z_NULL
;
435 if (inflateInit(ses
.newkeys
->recv
.zstream
) != Z_OK
) {
436 dropbear_exit("zlib error");
439 ses
.newkeys
->recv
.zstream
= NULL
;
441 /* clean up old keys */
442 if (ses
.keys
->recv
.zstream
!= NULL
) {
443 if (inflateEnd(ses
.keys
->recv
.zstream
) == Z_STREAM_ERROR
) {
444 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
445 dropbear_exit("Crypto error");
447 m_free(ses
.keys
->recv
.zstream
);
451 static void gen_new_zstream_trans() {
453 if (ses
.newkeys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB
454 || ses
.newkeys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
) {
455 ses
.newkeys
->trans
.zstream
= (z_streamp
)m_malloc(sizeof(z_stream
));
456 ses
.newkeys
->trans
.zstream
->zalloc
= Z_NULL
;
457 ses
.newkeys
->trans
.zstream
->zfree
= Z_NULL
;
459 if (deflateInit2(ses
.newkeys
->trans
.zstream
, Z_DEFAULT_COMPRESSION
,
460 Z_DEFLATED
, DROPBEAR_ZLIB_WINDOW_BITS
,
461 DROPBEAR_ZLIB_MEM_LEVEL
, Z_DEFAULT_STRATEGY
)
463 dropbear_exit("zlib error");
466 ses
.newkeys
->trans
.zstream
= NULL
;
469 if (ses
.keys
->trans
.zstream
!= NULL
) {
470 if (deflateEnd(ses
.keys
->trans
.zstream
) == Z_STREAM_ERROR
) {
471 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
472 dropbear_exit("Crypto error");
474 m_free(ses
.keys
->trans
.zstream
);
477 #endif /* DISABLE_ZLIB */
480 /* Executed upon receiving a kexinit message from the client to initiate
481 * key exchange. If we haven't already done so, we send the list of our
482 * preferred algorithms. The client's requested algorithms are processed,
483 * and we calculate the first portion of the key-exchange-hash for used
484 * later in the key exchange. No response is sent, as the client should
485 * initiate the diffie-hellman key exchange */
487 /* Originally from kex.c, generalized for cli/svr mode --mihnea */
488 /* Belongs in common_kex.c where it should be moved after review */
489 void recv_msg_kexinit() {
491 unsigned int kexhashbuf_len
= 0;
492 unsigned int remote_ident_len
= 0;
493 unsigned int local_ident_len
= 0;
495 TRACE(("<- KEXINIT"))
496 TRACE(("enter recv_msg_kexinit"))
498 if (!ses
.kexstate
.sentkexinit
) {
499 /* we need to send a kex packet */
501 TRACE(("continue recv_msg_kexinit: sent kexinit"))
504 /* start the kex hash */
505 local_ident_len
= strlen(LOCAL_IDENT
);
506 remote_ident_len
= strlen((char*)ses
.remoteident
);
508 kexhashbuf_len
= local_ident_len
+ remote_ident_len
509 + ses
.transkexinit
->len
+ ses
.payload
->len
510 + KEXHASHBUF_MAX_INTS
;
512 ses
.kexhashbuf
= buf_new(kexhashbuf_len
);
514 if (IS_DROPBEAR_CLIENT
) {
516 /* read the peer's choice of algos */
519 /* V_C, the client's version string (CR and NL excluded) */
520 buf_putstring(ses
.kexhashbuf
,
521 (unsigned char*)LOCAL_IDENT
, local_ident_len
);
522 /* V_S, the server's version string (CR and NL excluded) */
523 buf_putstring(ses
.kexhashbuf
, ses
.remoteident
, remote_ident_len
);
525 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
526 buf_putstring(ses
.kexhashbuf
,
527 ses
.transkexinit
->data
, ses
.transkexinit
->len
);
528 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
529 buf_setpos(ses
.payload
, 0);
530 buf_putstring(ses
.kexhashbuf
, ses
.payload
->data
, ses
.payload
->len
);
535 /* read the peer's choice of algos */
537 /* V_C, the client's version string (CR and NL excluded) */
538 buf_putstring(ses
.kexhashbuf
, ses
.remoteident
, remote_ident_len
);
539 /* V_S, the server's version string (CR and NL excluded) */
540 buf_putstring(ses
.kexhashbuf
,
541 (unsigned char*)LOCAL_IDENT
, local_ident_len
);
543 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
544 buf_setpos(ses
.payload
, 0);
545 buf_putstring(ses
.kexhashbuf
, ses
.payload
->data
, ses
.payload
->len
);
547 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
548 buf_putstring(ses
.kexhashbuf
,
549 ses
.transkexinit
->data
, ses
.transkexinit
->len
);
551 ses
.requirenext
[0] = SSH_MSG_KEXDH_INIT
;
554 buf_free(ses
.transkexinit
);
555 ses
.transkexinit
= NULL
;
556 /* the rest of ses.kexhashbuf will be done after DH exchange */
558 ses
.kexstate
.recvkexinit
= 1;
560 TRACE(("leave recv_msg_kexinit"))
563 static void load_dh_p(mp_int
* dh_p
)
565 bytes_to_mp(dh_p
, ses
.newkeys
->algo_kex
->dh_p_bytes
,
566 ses
.newkeys
->algo_kex
->dh_p_len
);
569 /* Initialises and generate one side of the diffie-hellman key exchange values.
570 * See the transport rfc 4253 section 8 for details */
571 /* dh_pub and dh_priv MUST be already initialised */
572 struct kex_dh_param
*gen_kexdh_param() {
573 struct kex_dh_param
*param
= NULL
;
579 TRACE(("enter gen_kexdh_vals"))
581 param
= m_malloc(sizeof(*param
));
582 m_mp_init_multi(¶m
->pub
, ¶m
->priv
, &dh_g
, &dh_p
, &dh_q
, NULL
);
584 /* read the prime and generator*/
587 if (mp_set_int(&dh_g
, DH_G_VAL
) != MP_OKAY
) {
588 dropbear_exit("Diffie-Hellman error");
591 /* calculate q = (p-1)/2 */
592 /* dh_priv is just a temp var here */
593 if (mp_sub_d(&dh_p
, 1, ¶m
->priv
) != MP_OKAY
) {
594 dropbear_exit("Diffie-Hellman error");
596 if (mp_div_2(¶m
->priv
, &dh_q
) != MP_OKAY
) {
597 dropbear_exit("Diffie-Hellman error");
600 /* Generate a private portion 0 < dh_priv < dh_q */
601 gen_random_mpint(&dh_q
, ¶m
->priv
);
604 if (mp_exptmod(&dh_g
, ¶m
->priv
, &dh_p
, ¶m
->pub
) != MP_OKAY
) {
605 dropbear_exit("Diffie-Hellman error");
607 mp_clear_multi(&dh_g
, &dh_p
, &dh_q
, NULL
);
611 void free_kexdh_param(struct kex_dh_param
*param
)
613 mp_clear_multi(¶m
->pub
, ¶m
->priv
, NULL
);
617 /* This function is fairly common between client/server, with some substitution
618 * of dh_e/dh_f etc. Hence these arguments:
619 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is
620 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */
621 void kexdh_comb_key(struct kex_dh_param
*param
, mp_int
*dh_pub_them
,
625 mp_int
*dh_e
= NULL
, *dh_f
= NULL
;
627 /* read the prime and generator*/
631 /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */
632 if (mp_cmp(dh_pub_them
, &dh_p
) != MP_LT
633 || mp_cmp_d(dh_pub_them
, 0) != MP_GT
) {
634 dropbear_exit("Diffie-Hellman error");
637 /* K = e^y mod p = f^x mod p */
638 m_mp_alloc_init_multi(&ses
.dh_K
, NULL
);
639 if (mp_exptmod(dh_pub_them
, ¶m
->priv
, &dh_p
, ses
.dh_K
) != MP_OKAY
) {
640 dropbear_exit("Diffie-Hellman error");
643 /* clear no longer needed vars */
644 mp_clear_multi(&dh_p
, NULL
);
646 /* From here on, the code needs to work with the _same_ vars on each side,
647 * not vice-versaing for client/server */
648 if (IS_DROPBEAR_CLIENT
) {
656 /* Create the remainder of the hash buffer, to generate the exchange hash */
657 /* K_S, the host key */
658 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
659 /* e, exchange value sent by the client */
660 buf_putmpint(ses
.kexhashbuf
, dh_e
);
661 /* f, exchange value sent by the server */
662 buf_putmpint(ses
.kexhashbuf
, dh_f
);
663 /* K, the shared secret */
664 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
666 /* calculate the hash H to sign */
671 struct kex_ecdh_param
*gen_kexecdh_param() {
672 struct kex_ecdh_param
*param
= m_malloc(sizeof(*param
));
673 if (ecc_make_key_ex(NULL
, dropbear_ltc_prng
,
674 ¶m
->key
, ses
.newkeys
->algo_kex
->ecc_curve
->dp
) != CRYPT_OK
) {
675 dropbear_exit("ECC error");
680 void free_kexecdh_param(struct kex_ecdh_param
*param
) {
681 ecc_free(¶m
->key
);
685 void kexecdh_comb_key(struct kex_ecdh_param
*param
, buffer
*pub_them
,
687 const struct dropbear_kex
*algo_kex
= ses
.newkeys
->algo_kex
;
688 /* public keys from client and server */
689 ecc_key
*Q_C
, *Q_S
, *Q_them
;
691 Q_them
= buf_get_ecc_raw_pubkey(pub_them
, algo_kex
->ecc_curve
);
693 ses
.dh_K
= dropbear_ecc_shared_secret(Q_them
, ¶m
->key
);
695 /* Create the remainder of the hash buffer, to generate the exchange hash
696 See RFC5656 section 4 page 7 */
697 if (IS_DROPBEAR_CLIENT
) {
705 /* K_S, the host key */
706 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
707 /* Q_C, client's ephemeral public key octet string */
708 buf_put_ecc_raw_pubkey_string(ses
.kexhashbuf
, Q_C
);
709 /* Q_S, server's ephemeral public key octet string */
710 buf_put_ecc_raw_pubkey_string(ses
.kexhashbuf
, Q_S
);
711 /* K, the shared secret */
712 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
714 /* calculate the hash H to sign */
717 #endif /* DROPBEAR_ECDH */
719 #ifdef DROPBEAR_CURVE25519
720 struct kex_curve25519_param
*gen_kexcurve25519_param () {
721 /* Per http://cr.yp.to/ecdh.html */
722 struct kex_curve25519_param
*param
= m_malloc(sizeof(*param
));
723 const unsigned char basepoint
[32] = {9};
725 genrandom(param
->priv
, CURVE25519_LEN
);
726 param
->priv
[0] &= 248;
727 param
->priv
[31] &= 127;
728 param
->priv
[31] |= 64;
730 curve25519_donna(param
->pub
, param
->priv
, basepoint
);
735 void free_kexcurve25519_param(struct kex_curve25519_param
*param
)
737 m_burn(param
->priv
, CURVE25519_LEN
);
741 void kexcurve25519_comb_key(struct kex_curve25519_param
*param
, buffer
*buf_pub_them
,
743 unsigned char out
[CURVE25519_LEN
];
744 const unsigned char* Q_C
= NULL
;
745 const unsigned char* Q_S
= NULL
;
747 if (buf_pub_them
->len
!= CURVE25519_LEN
)
749 dropbear_exit("Bad curve25519");
752 curve25519_donna(out
, param
->priv
, buf_pub_them
->data
);
753 m_mp_alloc_init_multi(&ses
.dh_K
, NULL
);
754 bytes_to_mp(ses
.dh_K
, out
, CURVE25519_LEN
);
755 m_burn(out
, sizeof(out
));
757 /* Create the remainder of the hash buffer, to generate the exchange hash.
758 See RFC5656 section 4 page 7 */
759 if (IS_DROPBEAR_CLIENT
) {
761 Q_S
= buf_pub_them
->data
;
764 Q_C
= buf_pub_them
->data
;
767 /* K_S, the host key */
768 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
769 /* Q_C, client's ephemeral public key octet string */
770 buf_putstring(ses
.kexhashbuf
, Q_C
, CURVE25519_LEN
);
771 /* Q_S, server's ephemeral public key octet string */
772 buf_putstring(ses
.kexhashbuf
, Q_S
, CURVE25519_LEN
);
773 /* K, the shared secret */
774 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
776 /* calculate the hash H to sign */
779 #endif /* DROPBEAR_CURVE25519 */
783 static void finish_kexhashbuf(void) {
785 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
787 hash_desc
->init(&hs
);
788 buf_setpos(ses
.kexhashbuf
, 0);
789 hash_desc
->process(&hs
, buf_getptr(ses
.kexhashbuf
, ses
.kexhashbuf
->len
),
790 ses
.kexhashbuf
->len
);
791 ses
.hash
= buf_new(hash_desc
->hashsize
);
792 hash_desc
->done(&hs
, buf_getwriteptr(ses
.hash
, hash_desc
->hashsize
));
793 buf_setlen(ses
.hash
, hash_desc
->hashsize
);
795 buf_burn(ses
.kexhashbuf
);
796 buf_free(ses
.kexhashbuf
);
797 ses
.kexhashbuf
= NULL
;
799 /* first time around, we set the session_id to H */
800 if (ses
.session_id
== NULL
) {
801 /* create the session_id, this never needs freeing */
802 ses
.session_id
= buf_newcopy(ses
.hash
);
807 /* read the other side's algo list. buf_match_algo is a callback to match
808 * algos for the client or server. */
809 static void read_kex_algos() {
812 algo_type
* c2s_hash_algo
= NULL
;
813 algo_type
* s2c_hash_algo
= NULL
;
814 algo_type
* c2s_cipher_algo
= NULL
;
815 algo_type
* s2c_cipher_algo
= NULL
;
816 algo_type
* c2s_comp_algo
= NULL
;
817 algo_type
* s2c_comp_algo
= NULL
;
818 /* the generic one */
819 algo_type
* algo
= NULL
;
821 /* which algo couldn't match */
822 char * erralgo
= NULL
;
825 int allgood
= 1; /* we AND this with each goodguess and see if its still
829 enum kexguess2_used kexguess2
= KEXGUESS2_LOOK
;
831 enum kexguess2_used kexguess2
= KEXGUESS2_NO
;
834 buf_incrpos(ses
.payload
, 16); /* start after the cookie */
836 memset(ses
.newkeys
, 0x0, sizeof(*ses
.newkeys
));
839 algo
= buf_match_algo(ses
.payload
, sshkex
, &kexguess2
, &goodguess
);
840 allgood
&= goodguess
;
841 if (algo
== NULL
|| algo
->val
== KEXGUESS2_ALGO_ID
) {
845 TRACE(("kexguess2 %d", kexguess2
))
846 TRACE(("kex algo %s", algo
->name
))
847 ses
.newkeys
->algo_kex
= algo
->data
;
849 /* server_host_key_algorithms */
850 algo
= buf_match_algo(ses
.payload
, sshhostkey
, &kexguess2
, &goodguess
);
851 allgood
&= goodguess
;
856 TRACE(("hostkey algo %s", algo
->name
))
857 ses
.newkeys
->algo_hostkey
= algo
->val
;
859 /* encryption_algorithms_client_to_server */
860 c2s_cipher_algo
= buf_match_algo(ses
.payload
, sshciphers
, NULL
, NULL
);
861 if (c2s_cipher_algo
== NULL
) {
862 erralgo
= "enc c->s";
865 TRACE(("enc c2s is %s", c2s_cipher_algo
->name
))
867 /* encryption_algorithms_server_to_client */
868 s2c_cipher_algo
= buf_match_algo(ses
.payload
, sshciphers
, NULL
, NULL
);
869 if (s2c_cipher_algo
== NULL
) {
870 erralgo
= "enc s->c";
873 TRACE(("enc s2c is %s", s2c_cipher_algo
->name
))
875 /* mac_algorithms_client_to_server */
876 c2s_hash_algo
= buf_match_algo(ses
.payload
, sshhashes
, NULL
, NULL
);
877 if (c2s_hash_algo
== NULL
) {
878 erralgo
= "mac c->s";
881 TRACE(("hash c2s is %s", c2s_hash_algo
->name
))
883 /* mac_algorithms_server_to_client */
884 s2c_hash_algo
= buf_match_algo(ses
.payload
, sshhashes
, NULL
, NULL
);
885 if (s2c_hash_algo
== NULL
) {
886 erralgo
= "mac s->c";
889 TRACE(("hash s2c is %s", s2c_hash_algo
->name
))
891 /* compression_algorithms_client_to_server */
892 c2s_comp_algo
= buf_match_algo(ses
.payload
, ses
.compress_algos
, NULL
, NULL
);
893 if (c2s_comp_algo
== NULL
) {
894 erralgo
= "comp c->s";
897 TRACE(("hash c2s is %s", c2s_comp_algo
->name
))
899 /* compression_algorithms_server_to_client */
900 s2c_comp_algo
= buf_match_algo(ses
.payload
, ses
.compress_algos
, NULL
, NULL
);
901 if (s2c_comp_algo
== NULL
) {
902 erralgo
= "comp s->c";
905 TRACE(("hash s2c is %s", s2c_comp_algo
->name
))
907 /* languages_client_to_server */
908 buf_eatstring(ses
.payload
);
910 /* languages_server_to_client */
911 buf_eatstring(ses
.payload
);
913 /* their first_kex_packet_follows */
914 if (buf_getbool(ses
.payload
)) {
915 TRACE(("them kex firstfollows. allgood %d", allgood
))
916 ses
.kexstate
.them_firstfollows
= 1;
917 /* if the guess wasn't good, we ignore the packet sent */
923 /* Handle the asymmetry */
924 if (IS_DROPBEAR_CLIENT
) {
925 ses
.newkeys
->recv
.algo_crypt
=
926 (struct dropbear_cipher
*)s2c_cipher_algo
->data
;
927 ses
.newkeys
->trans
.algo_crypt
=
928 (struct dropbear_cipher
*)c2s_cipher_algo
->data
;
929 ses
.newkeys
->recv
.crypt_mode
=
930 (struct dropbear_cipher_mode
*)s2c_cipher_algo
->mode
;
931 ses
.newkeys
->trans
.crypt_mode
=
932 (struct dropbear_cipher_mode
*)c2s_cipher_algo
->mode
;
933 ses
.newkeys
->recv
.algo_mac
=
934 (struct dropbear_hash
*)s2c_hash_algo
->data
;
935 ses
.newkeys
->trans
.algo_mac
=
936 (struct dropbear_hash
*)c2s_hash_algo
->data
;
937 ses
.newkeys
->recv
.algo_comp
= s2c_comp_algo
->val
;
938 ses
.newkeys
->trans
.algo_comp
= c2s_comp_algo
->val
;
941 ses
.newkeys
->recv
.algo_crypt
=
942 (struct dropbear_cipher
*)c2s_cipher_algo
->data
;
943 ses
.newkeys
->trans
.algo_crypt
=
944 (struct dropbear_cipher
*)s2c_cipher_algo
->data
;
945 ses
.newkeys
->recv
.crypt_mode
=
946 (struct dropbear_cipher_mode
*)c2s_cipher_algo
->mode
;
947 ses
.newkeys
->trans
.crypt_mode
=
948 (struct dropbear_cipher_mode
*)s2c_cipher_algo
->mode
;
949 ses
.newkeys
->recv
.algo_mac
=
950 (struct dropbear_hash
*)c2s_hash_algo
->data
;
951 ses
.newkeys
->trans
.algo_mac
=
952 (struct dropbear_hash
*)s2c_hash_algo
->data
;
953 ses
.newkeys
->recv
.algo_comp
= c2s_comp_algo
->val
;
954 ses
.newkeys
->trans
.algo_comp
= s2c_comp_algo
->val
;
957 /* reserved for future extensions */
958 buf_getint(ses
.payload
);
960 if (ses
.send_kex_first_guess
&& allgood
) {
961 TRACE(("our_first_follows_matches 1"))
962 ses
.kexstate
.our_first_follows_matches
= 1;
967 dropbear_exit("No matching algo %s", erralgo
);