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