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 ses
.compress_algos
= ssh_nocompress
;
244 switch (opts
.compress_mode
)
246 case DROPBEAR_COMPRESS_DELAYED
:
247 ses
.compress_algos
= ssh_delaycompress
;
250 case DROPBEAR_COMPRESS_ON
:
251 ses
.compress_algos
= ssh_compress
;
254 case DROPBEAR_COMPRESS_OFF
:
255 ses
.compress_algos
= ssh_nocompress
;
262 /* Reset the kex state, ready for a new negotiation */
263 static void kexinitialise() {
265 TRACE(("kexinitialise()"))
267 /* sent/recv'd MSG_KEXINIT */
268 ses
.kexstate
.sentkexinit
= 0;
269 ses
.kexstate
.recvkexinit
= 0;
271 /* sent/recv'd MSG_NEWKEYS */
272 ses
.kexstate
.recvnewkeys
= 0;
273 ses
.kexstate
.sentnewkeys
= 0;
275 /* first_packet_follows */
276 ses
.kexstate
.them_firstfollows
= 0;
278 ses
.kexstate
.datatrans
= 0;
279 ses
.kexstate
.datarecv
= 0;
281 ses
.kexstate
.our_first_follows_matches
= 0;
283 ses
.kexstate
.lastkextime
= monotonic_now();
287 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the
288 * already initialised hash_state hs, which should already have processed
289 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc.
290 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated.
292 * See Section 7.2 of rfc4253 (ssh transport) for details */
293 static void hashkeys(unsigned char *out
, unsigned int outlen
,
294 const hash_state
* hs
, const unsigned char X
) {
296 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
299 unsigned char tmpout
[MAX_HASH_SIZE
];
301 memcpy(&hs2
, hs
, sizeof(hash_state
));
302 hash_desc
->process(&hs2
, &X
, 1);
303 hash_desc
->process(&hs2
, ses
.session_id
->data
, ses
.session_id
->len
);
304 hash_desc
->done(&hs2
, tmpout
);
305 memcpy(out
, tmpout
, MIN(hash_desc
->hashsize
, outlen
));
306 for (offset
= hash_desc
->hashsize
;
308 offset
+= hash_desc
->hashsize
)
311 memcpy(&hs2
, hs
, sizeof(hash_state
));
312 hash_desc
->process(&hs2
, out
, offset
);
313 hash_desc
->done(&hs2
, tmpout
);
314 memcpy(&out
[offset
], tmpout
, MIN(outlen
- offset
, hash_desc
->hashsize
));
316 m_burn(&hs2
, sizeof(hash_state
));
319 /* Generate the actual encryption/integrity keys, using the results of the
320 * key exchange, as specified in section 7.2 of the transport rfc 4253.
321 * This occurs after the DH key-exchange.
323 * ses.newkeys is the new set of keys which are generated, these are only
324 * taken into use after both sides have sent a newkeys message */
326 static void gen_new_keys() {
328 unsigned char C2S_IV
[MAX_IV_LEN
];
329 unsigned char C2S_key
[MAX_KEY_LEN
];
330 unsigned char S2C_IV
[MAX_IV_LEN
];
331 unsigned char S2C_key
[MAX_KEY_LEN
];
332 /* unsigned char key[MAX_KEY_LEN]; */
333 unsigned char *trans_IV
, *trans_key
, *recv_IV
, *recv_key
;
336 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
337 char mactransletter
, macrecvletter
; /* Client or server specific */
339 TRACE(("enter gen_new_keys"))
340 /* the dh_K and hash are the start of all hashes, we make use of that */
342 hash_desc
->init(&hs
);
343 hash_process_mp(hash_desc
, &hs
, ses
.dh_K
);
346 hash_desc
->process(&hs
, ses
.hash
->data
, ses
.hash
->len
);
351 if (IS_DROPBEAR_CLIENT
) {
356 mactransletter
= 'E';
363 mactransletter
= 'F';
367 hashkeys(C2S_IV
, sizeof(C2S_IV
), &hs
, 'A');
368 hashkeys(S2C_IV
, sizeof(S2C_IV
), &hs
, 'B');
369 hashkeys(C2S_key
, sizeof(C2S_key
), &hs
, 'C');
370 hashkeys(S2C_key
, sizeof(S2C_key
), &hs
, 'D');
372 if (ses
.newkeys
->recv
.algo_crypt
->cipherdesc
!= NULL
) {
373 int recv_cipher
= find_cipher(ses
.newkeys
->recv
.algo_crypt
->cipherdesc
->name
);
375 dropbear_exit("Crypto error");
376 if (ses
.newkeys
->recv
.crypt_mode
->start(recv_cipher
,
378 ses
.newkeys
->recv
.algo_crypt
->keysize
, 0,
379 &ses
.newkeys
->recv
.cipher_state
) != CRYPT_OK
) {
380 dropbear_exit("Crypto error");
384 if (ses
.newkeys
->trans
.algo_crypt
->cipherdesc
!= NULL
) {
385 int trans_cipher
= find_cipher(ses
.newkeys
->trans
.algo_crypt
->cipherdesc
->name
);
386 if (trans_cipher
< 0)
387 dropbear_exit("Crypto error");
388 if (ses
.newkeys
->trans
.crypt_mode
->start(trans_cipher
,
390 ses
.newkeys
->trans
.algo_crypt
->keysize
, 0,
391 &ses
.newkeys
->trans
.cipher_state
) != CRYPT_OK
) {
392 dropbear_exit("Crypto error");
396 if (ses
.newkeys
->trans
.algo_mac
->hash_desc
!= NULL
) {
397 hashkeys(ses
.newkeys
->trans
.mackey
,
398 ses
.newkeys
->trans
.algo_mac
->keysize
, &hs
, mactransletter
);
399 ses
.newkeys
->trans
.hash_index
= find_hash(ses
.newkeys
->trans
.algo_mac
->hash_desc
->name
);
402 if (ses
.newkeys
->recv
.algo_mac
->hash_desc
!= NULL
) {
403 hashkeys(ses
.newkeys
->recv
.mackey
,
404 ses
.newkeys
->recv
.algo_mac
->keysize
, &hs
, macrecvletter
);
405 ses
.newkeys
->recv
.hash_index
= find_hash(ses
.newkeys
->recv
.algo_mac
->hash_desc
->name
);
408 /* Ready to switch over */
409 ses
.newkeys
->trans
.valid
= 1;
410 ses
.newkeys
->recv
.valid
= 1;
412 m_burn(C2S_IV
, sizeof(C2S_IV
));
413 m_burn(C2S_key
, sizeof(C2S_key
));
414 m_burn(S2C_IV
, sizeof(S2C_IV
));
415 m_burn(S2C_key
, sizeof(S2C_key
));
416 m_burn(&hs
, sizeof(hash_state
));
418 TRACE(("leave gen_new_keys"))
423 int is_compress_trans() {
424 return ses
.keys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB
425 || (ses
.authstate
.authdone
426 && ses
.keys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
);
429 int is_compress_recv() {
430 return ses
.keys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB
431 || (ses
.authstate
.authdone
432 && ses
.keys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
);
435 /* Set up new zlib compression streams, close the old ones. Only
436 * called from gen_new_keys() */
437 static void gen_new_zstream_recv() {
439 /* create new zstreams */
440 if (ses
.newkeys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB
441 || ses
.newkeys
->recv
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
) {
442 ses
.newkeys
->recv
.zstream
= (z_streamp
)m_malloc(sizeof(z_stream
));
443 ses
.newkeys
->recv
.zstream
->zalloc
= Z_NULL
;
444 ses
.newkeys
->recv
.zstream
->zfree
= Z_NULL
;
446 if (inflateInit(ses
.newkeys
->recv
.zstream
) != Z_OK
) {
447 dropbear_exit("zlib error");
450 ses
.newkeys
->recv
.zstream
= NULL
;
452 /* clean up old keys */
453 if (ses
.keys
->recv
.zstream
!= NULL
) {
454 if (inflateEnd(ses
.keys
->recv
.zstream
) == Z_STREAM_ERROR
) {
455 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
456 dropbear_exit("Crypto error");
458 m_free(ses
.keys
->recv
.zstream
);
462 static void gen_new_zstream_trans() {
464 if (ses
.newkeys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB
465 || ses
.newkeys
->trans
.algo_comp
== DROPBEAR_COMP_ZLIB_DELAY
) {
466 ses
.newkeys
->trans
.zstream
= (z_streamp
)m_malloc(sizeof(z_stream
));
467 ses
.newkeys
->trans
.zstream
->zalloc
= Z_NULL
;
468 ses
.newkeys
->trans
.zstream
->zfree
= Z_NULL
;
470 if (deflateInit2(ses
.newkeys
->trans
.zstream
, Z_DEFAULT_COMPRESSION
,
471 Z_DEFLATED
, DROPBEAR_ZLIB_WINDOW_BITS
,
472 DROPBEAR_ZLIB_MEM_LEVEL
, Z_DEFAULT_STRATEGY
)
474 dropbear_exit("zlib error");
477 ses
.newkeys
->trans
.zstream
= NULL
;
480 if (ses
.keys
->trans
.zstream
!= NULL
) {
481 if (deflateEnd(ses
.keys
->trans
.zstream
) == Z_STREAM_ERROR
) {
482 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
483 dropbear_exit("Crypto error");
485 m_free(ses
.keys
->trans
.zstream
);
488 #endif /* DISABLE_ZLIB */
491 /* Executed upon receiving a kexinit message from the client to initiate
492 * key exchange. If we haven't already done so, we send the list of our
493 * preferred algorithms. The client's requested algorithms are processed,
494 * and we calculate the first portion of the key-exchange-hash for used
495 * later in the key exchange. No response is sent, as the client should
496 * initiate the diffie-hellman key exchange */
497 void recv_msg_kexinit() {
499 unsigned int kexhashbuf_len
= 0;
500 unsigned int remote_ident_len
= 0;
501 unsigned int local_ident_len
= 0;
503 TRACE(("<- KEXINIT"))
504 TRACE(("enter recv_msg_kexinit"))
506 if (!ses
.kexstate
.sentkexinit
) {
507 /* we need to send a kex packet */
509 TRACE(("continue recv_msg_kexinit: sent kexinit"))
512 /* start the kex hash */
513 local_ident_len
= strlen(LOCAL_IDENT
);
514 remote_ident_len
= strlen(ses
.remoteident
);
516 kexhashbuf_len
= local_ident_len
+ remote_ident_len
517 + ses
.transkexinit
->len
+ ses
.payload
->len
518 + KEXHASHBUF_MAX_INTS
;
520 ses
.kexhashbuf
= buf_new(kexhashbuf_len
);
522 if (IS_DROPBEAR_CLIENT
) {
524 /* read the peer's choice of algos */
527 /* V_C, the client's version string (CR and NL excluded) */
528 buf_putstring(ses
.kexhashbuf
, LOCAL_IDENT
, local_ident_len
);
529 /* V_S, the server's version string (CR and NL excluded) */
530 buf_putstring(ses
.kexhashbuf
, ses
.remoteident
, remote_ident_len
);
532 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
533 buf_putstring(ses
.kexhashbuf
,
534 (const char*)ses
.transkexinit
->data
, ses
.transkexinit
->len
);
535 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
536 buf_setpos(ses
.payload
, ses
.payload_beginning
);
537 buf_putstring(ses
.kexhashbuf
,
538 (const char*)buf_getptr(ses
.payload
, ses
.payload
->len
-ses
.payload
->pos
),
539 ses
.payload
->len
-ses
.payload
->pos
);
540 ses
.requirenext
= SSH_MSG_KEXDH_REPLY
;
544 /* read the peer's choice of algos */
546 /* V_C, the client's version string (CR and NL excluded) */
547 buf_putstring(ses
.kexhashbuf
, ses
.remoteident
, remote_ident_len
);
548 /* V_S, the server's version string (CR and NL excluded) */
549 buf_putstring(ses
.kexhashbuf
, LOCAL_IDENT
, local_ident_len
);
551 /* I_C, the payload of the client's SSH_MSG_KEXINIT */
552 buf_setpos(ses
.payload
, ses
.payload_beginning
);
553 buf_putstring(ses
.kexhashbuf
,
554 (const char*)buf_getptr(ses
.payload
, ses
.payload
->len
-ses
.payload
->pos
),
555 ses
.payload
->len
-ses
.payload
->pos
);
557 /* I_S, the payload of the server's SSH_MSG_KEXINIT */
558 buf_putstring(ses
.kexhashbuf
,
559 (const char*)ses
.transkexinit
->data
, ses
.transkexinit
->len
);
561 ses
.requirenext
= SSH_MSG_KEXDH_INIT
;
564 buf_free(ses
.transkexinit
);
565 ses
.transkexinit
= NULL
;
566 /* the rest of ses.kexhashbuf will be done after DH exchange */
568 ses
.kexstate
.recvkexinit
= 1;
570 TRACE(("leave recv_msg_kexinit"))
573 static void load_dh_p(mp_int
* dh_p
)
575 bytes_to_mp(dh_p
, ses
.newkeys
->algo_kex
->dh_p_bytes
,
576 ses
.newkeys
->algo_kex
->dh_p_len
);
579 /* Initialises and generate one side of the diffie-hellman key exchange values.
580 * See the transport rfc 4253 section 8 for details */
581 /* dh_pub and dh_priv MUST be already initialised */
582 struct kex_dh_param
*gen_kexdh_param() {
583 struct kex_dh_param
*param
= NULL
;
589 TRACE(("enter gen_kexdh_vals"))
591 param
= m_malloc(sizeof(*param
));
592 m_mp_init_multi(¶m
->pub
, ¶m
->priv
, &dh_g
, &dh_p
, &dh_q
, NULL
);
594 /* read the prime and generator*/
597 if (mp_set_int(&dh_g
, DH_G_VAL
) != MP_OKAY
) {
598 dropbear_exit("Diffie-Hellman error");
601 /* calculate q = (p-1)/2 */
602 /* dh_priv is just a temp var here */
603 if (mp_sub_d(&dh_p
, 1, ¶m
->priv
) != MP_OKAY
) {
604 dropbear_exit("Diffie-Hellman error");
606 if (mp_div_2(¶m
->priv
, &dh_q
) != MP_OKAY
) {
607 dropbear_exit("Diffie-Hellman error");
610 /* Generate a private portion 0 < dh_priv < dh_q */
611 gen_random_mpint(&dh_q
, ¶m
->priv
);
614 if (mp_exptmod(&dh_g
, ¶m
->priv
, &dh_p
, ¶m
->pub
) != MP_OKAY
) {
615 dropbear_exit("Diffie-Hellman error");
617 mp_clear_multi(&dh_g
, &dh_p
, &dh_q
, NULL
);
621 void free_kexdh_param(struct kex_dh_param
*param
)
623 mp_clear_multi(¶m
->pub
, ¶m
->priv
, NULL
);
627 /* This function is fairly common between client/server, with some substitution
628 * of dh_e/dh_f etc. Hence these arguments:
629 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is
630 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */
631 void kexdh_comb_key(struct kex_dh_param
*param
, mp_int
*dh_pub_them
,
635 DEF_MP_INT(dh_p_min1
);
636 mp_int
*dh_e
= NULL
, *dh_f
= NULL
;
638 m_mp_init_multi(&dh_p
, &dh_p_min1
, NULL
);
641 if (mp_sub_d(&dh_p
, 1, &dh_p_min1
) != MP_OKAY
) {
642 dropbear_exit("Diffie-Hellman error");
645 /* Check that dh_pub_them (dh_e or dh_f) is in the range [2, p-2] */
646 if (mp_cmp(dh_pub_them
, &dh_p_min1
) != MP_LT
647 || mp_cmp_d(dh_pub_them
, 1) != MP_GT
) {
648 dropbear_exit("Diffie-Hellman error");
651 /* K = e^y mod p = f^x mod p */
652 m_mp_alloc_init_multi(&ses
.dh_K
, NULL
);
653 if (mp_exptmod(dh_pub_them
, ¶m
->priv
, &dh_p
, ses
.dh_K
) != MP_OKAY
) {
654 dropbear_exit("Diffie-Hellman error");
657 /* clear no longer needed vars */
658 mp_clear_multi(&dh_p
, &dh_p_min1
, NULL
);
660 /* From here on, the code needs to work with the _same_ vars on each side,
661 * not vice-versaing for client/server */
662 if (IS_DROPBEAR_CLIENT
) {
670 /* Create the remainder of the hash buffer, to generate the exchange hash */
671 /* K_S, the host key */
672 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
673 /* e, exchange value sent by the client */
674 buf_putmpint(ses
.kexhashbuf
, dh_e
);
675 /* f, exchange value sent by the server */
676 buf_putmpint(ses
.kexhashbuf
, dh_f
);
677 /* K, the shared secret */
678 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
680 /* calculate the hash H to sign */
685 struct kex_ecdh_param
*gen_kexecdh_param() {
686 struct kex_ecdh_param
*param
= m_malloc(sizeof(*param
));
687 if (ecc_make_key_ex(NULL
, dropbear_ltc_prng
,
688 ¶m
->key
, ses
.newkeys
->algo_kex
->ecc_curve
->dp
) != CRYPT_OK
) {
689 dropbear_exit("ECC error");
694 void free_kexecdh_param(struct kex_ecdh_param
*param
) {
695 ecc_free(¶m
->key
);
699 void kexecdh_comb_key(struct kex_ecdh_param
*param
, buffer
*pub_them
,
701 const struct dropbear_kex
*algo_kex
= ses
.newkeys
->algo_kex
;
702 /* public keys from client and server */
703 ecc_key
*Q_C
, *Q_S
, *Q_them
;
705 Q_them
= buf_get_ecc_raw_pubkey(pub_them
, algo_kex
->ecc_curve
);
706 if (Q_them
== NULL
) {
707 dropbear_exit("ECC error");
710 ses
.dh_K
= dropbear_ecc_shared_secret(Q_them
, ¶m
->key
);
712 /* Create the remainder of the hash buffer, to generate the exchange hash
713 See RFC5656 section 4 page 7 */
714 if (IS_DROPBEAR_CLIENT
) {
722 /* K_S, the host key */
723 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
724 /* Q_C, client's ephemeral public key octet string */
725 buf_put_ecc_raw_pubkey_string(ses
.kexhashbuf
, Q_C
);
726 /* Q_S, server's ephemeral public key octet string */
727 buf_put_ecc_raw_pubkey_string(ses
.kexhashbuf
, Q_S
);
728 /* K, the shared secret */
729 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
731 /* calculate the hash H to sign */
734 #endif /* DROPBEAR_ECDH */
736 #ifdef DROPBEAR_CURVE25519
737 struct kex_curve25519_param
*gen_kexcurve25519_param () {
738 /* Per http://cr.yp.to/ecdh.html */
739 struct kex_curve25519_param
*param
= m_malloc(sizeof(*param
));
740 const unsigned char basepoint
[32] = {9};
742 genrandom(param
->priv
, CURVE25519_LEN
);
743 param
->priv
[0] &= 248;
744 param
->priv
[31] &= 127;
745 param
->priv
[31] |= 64;
747 curve25519_donna(param
->pub
, param
->priv
, basepoint
);
752 void free_kexcurve25519_param(struct kex_curve25519_param
*param
)
754 m_burn(param
->priv
, CURVE25519_LEN
);
758 void kexcurve25519_comb_key(struct kex_curve25519_param
*param
, buffer
*buf_pub_them
,
760 unsigned char out
[CURVE25519_LEN
];
761 const unsigned char* Q_C
= NULL
;
762 const unsigned char* Q_S
= NULL
;
763 char zeroes
[CURVE25519_LEN
] = {0};
765 if (buf_pub_them
->len
!= CURVE25519_LEN
)
767 dropbear_exit("Bad curve25519");
770 curve25519_donna(out
, param
->priv
, buf_pub_them
->data
);
772 if (constant_time_memcmp(zeroes
, out
, CURVE25519_LEN
) == 0) {
773 dropbear_exit("Bad curve25519");
776 m_mp_alloc_init_multi(&ses
.dh_K
, NULL
);
777 bytes_to_mp(ses
.dh_K
, out
, CURVE25519_LEN
);
778 m_burn(out
, sizeof(out
));
780 /* Create the remainder of the hash buffer, to generate the exchange hash.
781 See RFC5656 section 4 page 7 */
782 if (IS_DROPBEAR_CLIENT
) {
784 Q_S
= buf_pub_them
->data
;
787 Q_C
= buf_pub_them
->data
;
790 /* K_S, the host key */
791 buf_put_pub_key(ses
.kexhashbuf
, hostkey
, ses
.newkeys
->algo_hostkey
);
792 /* Q_C, client's ephemeral public key octet string */
793 buf_putstring(ses
.kexhashbuf
, (const char*)Q_C
, CURVE25519_LEN
);
794 /* Q_S, server's ephemeral public key octet string */
795 buf_putstring(ses
.kexhashbuf
, (const char*)Q_S
, CURVE25519_LEN
);
796 /* K, the shared secret */
797 buf_putmpint(ses
.kexhashbuf
, ses
.dh_K
);
799 /* calculate the hash H to sign */
802 #endif /* DROPBEAR_CURVE25519 */
806 static void finish_kexhashbuf(void) {
808 const struct ltc_hash_descriptor
*hash_desc
= ses
.newkeys
->algo_kex
->hash_desc
;
810 hash_desc
->init(&hs
);
811 buf_setpos(ses
.kexhashbuf
, 0);
812 hash_desc
->process(&hs
, buf_getptr(ses
.kexhashbuf
, ses
.kexhashbuf
->len
),
813 ses
.kexhashbuf
->len
);
814 ses
.hash
= buf_new(hash_desc
->hashsize
);
815 hash_desc
->done(&hs
, buf_getwriteptr(ses
.hash
, hash_desc
->hashsize
));
816 buf_setlen(ses
.hash
, hash_desc
->hashsize
);
818 #if defined(DEBUG_KEXHASH) && defined(DEBUG_TRACE)
820 printhex("kexhashbuf", ses
.kexhashbuf
->data
, ses
.kexhashbuf
->len
);
821 printhex("kexhash", ses
.hash
->data
, ses
.hash
->len
);
825 buf_burn(ses
.kexhashbuf
);
826 buf_free(ses
.kexhashbuf
);
827 m_burn(&hs
, sizeof(hash_state
));
828 ses
.kexhashbuf
= NULL
;
830 /* first time around, we set the session_id to H */
831 if (ses
.session_id
== NULL
) {
832 /* create the session_id, this never needs freeing */
833 ses
.session_id
= buf_newcopy(ses
.hash
);
837 /* read the other side's algo list. buf_match_algo is a callback to match
838 * algos for the client or server. */
839 static void read_kex_algos() {
842 algo_type
* c2s_hash_algo
= NULL
;
843 algo_type
* s2c_hash_algo
= NULL
;
844 algo_type
* c2s_cipher_algo
= NULL
;
845 algo_type
* s2c_cipher_algo
= NULL
;
846 algo_type
* c2s_comp_algo
= NULL
;
847 algo_type
* s2c_comp_algo
= NULL
;
848 /* the generic one */
849 algo_type
* algo
= NULL
;
851 /* which algo couldn't match */
852 char * erralgo
= NULL
;
855 int allgood
= 1; /* we AND this with each goodguess and see if its still
859 enum kexguess2_used kexguess2
= KEXGUESS2_LOOK
;
861 enum kexguess2_used kexguess2
= KEXGUESS2_NO
;
864 buf_incrpos(ses
.payload
, 16); /* start after the cookie */
866 memset(ses
.newkeys
, 0x0, sizeof(*ses
.newkeys
));
869 algo
= buf_match_algo(ses
.payload
, sshkex
, &kexguess2
, &goodguess
);
870 allgood
&= goodguess
;
871 if (algo
== NULL
|| algo
->val
== KEXGUESS2_ALGO_ID
) {
875 TRACE(("kexguess2 %d", kexguess2
))
876 TRACE(("kex algo %s", algo
->name
))
877 ses
.newkeys
->algo_kex
= algo
->data
;
879 /* server_host_key_algorithms */
880 algo
= buf_match_algo(ses
.payload
, sshhostkey
, &kexguess2
, &goodguess
);
881 allgood
&= goodguess
;
886 TRACE(("hostkey algo %s", algo
->name
))
887 ses
.newkeys
->algo_hostkey
= algo
->val
;
889 /* encryption_algorithms_client_to_server */
890 c2s_cipher_algo
= buf_match_algo(ses
.payload
, sshciphers
, NULL
, NULL
);
891 if (c2s_cipher_algo
== NULL
) {
892 erralgo
= "enc c->s";
895 TRACE(("enc c2s is %s", c2s_cipher_algo
->name
))
897 /* encryption_algorithms_server_to_client */
898 s2c_cipher_algo
= buf_match_algo(ses
.payload
, sshciphers
, NULL
, NULL
);
899 if (s2c_cipher_algo
== NULL
) {
900 erralgo
= "enc s->c";
903 TRACE(("enc s2c is %s", s2c_cipher_algo
->name
))
905 /* mac_algorithms_client_to_server */
906 c2s_hash_algo
= buf_match_algo(ses
.payload
, sshhashes
, NULL
, NULL
);
907 if (c2s_hash_algo
== NULL
) {
908 erralgo
= "mac c->s";
911 TRACE(("hash c2s is %s", c2s_hash_algo
->name
))
913 /* mac_algorithms_server_to_client */
914 s2c_hash_algo
= buf_match_algo(ses
.payload
, sshhashes
, NULL
, NULL
);
915 if (s2c_hash_algo
== NULL
) {
916 erralgo
= "mac s->c";
919 TRACE(("hash s2c is %s", s2c_hash_algo
->name
))
921 /* compression_algorithms_client_to_server */
922 c2s_comp_algo
= buf_match_algo(ses
.payload
, ses
.compress_algos
, NULL
, NULL
);
923 if (c2s_comp_algo
== NULL
) {
924 erralgo
= "comp c->s";
927 TRACE(("hash c2s is %s", c2s_comp_algo
->name
))
929 /* compression_algorithms_server_to_client */
930 s2c_comp_algo
= buf_match_algo(ses
.payload
, ses
.compress_algos
, NULL
, NULL
);
931 if (s2c_comp_algo
== NULL
) {
932 erralgo
= "comp s->c";
935 TRACE(("hash s2c is %s", s2c_comp_algo
->name
))
937 /* languages_client_to_server */
938 buf_eatstring(ses
.payload
);
940 /* languages_server_to_client */
941 buf_eatstring(ses
.payload
);
943 /* their first_kex_packet_follows */
944 if (buf_getbool(ses
.payload
)) {
945 TRACE(("them kex firstfollows. allgood %d", allgood
))
946 ses
.kexstate
.them_firstfollows
= 1;
947 /* if the guess wasn't good, we ignore the packet sent */
953 /* Handle the asymmetry */
954 if (IS_DROPBEAR_CLIENT
) {
955 ses
.newkeys
->recv
.algo_crypt
=
956 (struct dropbear_cipher
*)s2c_cipher_algo
->data
;
957 ses
.newkeys
->trans
.algo_crypt
=
958 (struct dropbear_cipher
*)c2s_cipher_algo
->data
;
959 ses
.newkeys
->recv
.crypt_mode
=
960 (struct dropbear_cipher_mode
*)s2c_cipher_algo
->mode
;
961 ses
.newkeys
->trans
.crypt_mode
=
962 (struct dropbear_cipher_mode
*)c2s_cipher_algo
->mode
;
963 ses
.newkeys
->recv
.algo_mac
=
964 (struct dropbear_hash
*)s2c_hash_algo
->data
;
965 ses
.newkeys
->trans
.algo_mac
=
966 (struct dropbear_hash
*)c2s_hash_algo
->data
;
967 ses
.newkeys
->recv
.algo_comp
= s2c_comp_algo
->val
;
968 ses
.newkeys
->trans
.algo_comp
= c2s_comp_algo
->val
;
971 ses
.newkeys
->recv
.algo_crypt
=
972 (struct dropbear_cipher
*)c2s_cipher_algo
->data
;
973 ses
.newkeys
->trans
.algo_crypt
=
974 (struct dropbear_cipher
*)s2c_cipher_algo
->data
;
975 ses
.newkeys
->recv
.crypt_mode
=
976 (struct dropbear_cipher_mode
*)c2s_cipher_algo
->mode
;
977 ses
.newkeys
->trans
.crypt_mode
=
978 (struct dropbear_cipher_mode
*)s2c_cipher_algo
->mode
;
979 ses
.newkeys
->recv
.algo_mac
=
980 (struct dropbear_hash
*)c2s_hash_algo
->data
;
981 ses
.newkeys
->trans
.algo_mac
=
982 (struct dropbear_hash
*)s2c_hash_algo
->data
;
983 ses
.newkeys
->recv
.algo_comp
= c2s_comp_algo
->val
;
984 ses
.newkeys
->trans
.algo_comp
= s2c_comp_algo
->val
;
987 /* reserved for future extensions */
988 buf_getint(ses
.payload
);
990 if (ses
.send_kex_first_guess
&& allgood
) {
991 TRACE(("our_first_follows_matches 1"))
992 ses
.kexstate
.our_first_follows_matches
= 1;
997 dropbear_exit("No matching algo %s", erralgo
);