Blame src/dh.c

Packit Service 31306d
/*
Packit Service 31306d
 * dh.c - Diffie-Helman algorithm code against SSH 2
Packit Service 31306d
 *
Packit Service 31306d
 * This file is part of the SSH Library
Packit Service 31306d
 *
Packit Service 31306d
 * Copyright (c) 2003-2018 by Aris Adamantiadis
Packit Service 31306d
 * Copyright (c) 2009-2013 by Andreas Schneider <asn@cryptomilk.org>
Packit Service 31306d
 * Copyright (c) 2012      by Dmitriy Kuznetsov <dk@yandex.ru>
Packit Service 31306d
 *
Packit Service 31306d
 * The SSH Library is free software; you can redistribute it and/or modify
Packit Service 31306d
 * it under the terms of the GNU Lesser General Public License as published by
Packit Service 31306d
 * the Free Software Foundation; either version 2.1 of the License, or (at your
Packit Service 31306d
 * option) any later version.
Packit Service 31306d
 *
Packit Service 31306d
 * The SSH Library is distributed in the hope that it will be useful, but
Packit Service 31306d
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
Packit Service 31306d
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
Packit Service 31306d
 * License for more details.
Packit Service 31306d
 *
Packit Service 31306d
 * You should have received a copy of the GNU Lesser General Public License
Packit Service 31306d
 * along with the SSH Library; see the file COPYING.  If not, write to
Packit Service 31306d
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
Packit Service 31306d
 * MA 02111-1307, USA.
Packit Service 31306d
 */
Packit Service 31306d
Packit Service 31306d
#include "config.h"
Packit Service 31306d
Packit Service 31306d
#include "libssh/priv.h"
Packit Service 31306d
#include "libssh/crypto.h"
Packit Service 31306d
#include "libssh/buffer.h"
Packit Service 31306d
#include "libssh/session.h"
Packit Service 31306d
#include "libssh/misc.h"
Packit Service 31306d
#include "libssh/dh.h"
Packit Service 31306d
#include "libssh/ssh2.h"
Packit Service 31306d
#include "libssh/pki.h"
Packit Service 31306d
#include "libssh/bignum.h"
Packit Service 31306d
Packit Service 31306d
static unsigned char p_group1_value[] = {
Packit Service 31306d
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit Service 31306d
        0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit Service 31306d
        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit Service 31306d
        0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit Service 31306d
        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit Service 31306d
        0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit Service 31306d
        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit Service 31306d
        0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit Service 31306d
        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit Service 31306d
        0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81,
Packit Service 31306d
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
Packit Service 31306d
#define P_GROUP1_LEN 128	/* Size in bytes of the p number */
Packit Service 31306d
Packit Service 31306d
static unsigned char p_group14_value[] = {
Packit Service 31306d
        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit Service 31306d
        0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit Service 31306d
        0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit Service 31306d
        0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit Service 31306d
        0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit Service 31306d
        0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit Service 31306d
        0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit Service 31306d
        0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit Service 31306d
        0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit Service 31306d
        0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
Packit Service 31306d
        0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
Packit Service 31306d
        0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
Packit Service 31306d
        0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
Packit Service 31306d
        0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
Packit Service 31306d
        0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
Packit Service 31306d
        0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
Packit Service 31306d
        0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
Packit Service 31306d
        0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
Packit Service 31306d
        0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
Packit Service 31306d
        0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
Packit Service 31306d
        0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, 0xFF, 0xFF, 0xFF, 0xFF,
Packit Service 31306d
        0xFF, 0xFF, 0xFF, 0xFF};
Packit Service 31306d
Packit Service 31306d
#define P_GROUP14_LEN 256 /* Size in bytes of the p number for group 14 */
Packit Service 31306d
Packit Service 31306d
static unsigned char p_group16_value[] = {
Packit Service 31306d
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit Service 31306d
    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit Service 31306d
    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit Service 31306d
    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit Service 31306d
    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit Service 31306d
    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit Service 31306d
    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit Service 31306d
    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit Service 31306d
    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit Service 31306d
    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
Packit Service 31306d
    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
Packit Service 31306d
    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
Packit Service 31306d
    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
Packit Service 31306d
    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
Packit Service 31306d
    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
Packit Service 31306d
    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
Packit Service 31306d
    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
Packit Service 31306d
    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
Packit Service 31306d
    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
Packit Service 31306d
    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
Packit Service 31306d
    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
Packit Service 31306d
    0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
Packit Service 31306d
    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
Packit Service 31306d
    0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
Packit Service 31306d
    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
Packit Service 31306d
    0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
Packit Service 31306d
    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
Packit Service 31306d
    0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
Packit Service 31306d
    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
Packit Service 31306d
    0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
Packit Service 31306d
    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
Packit Service 31306d
    0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
Packit Service 31306d
    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
Packit Service 31306d
    0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
Packit Service 31306d
    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
Packit Service 31306d
    0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
Packit Service 31306d
    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
Packit Service 31306d
    0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
Packit Service 31306d
    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
Packit Service 31306d
    0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
Packit Service 31306d
    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
Packit Service 31306d
    0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99,
Packit Service 31306d
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
Packit Service 31306d
Packit Service 31306d
#define P_GROUP16_LEN 512 /* Size in bytes of the p number for group 16 */
Packit Service 31306d
Packit Service 31306d
static unsigned char p_group18_value[] = {
Packit Service 31306d
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2,
Packit Service 31306d
    0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1,
Packit Service 31306d
    0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6,
Packit Service 31306d
    0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD,
Packit Service 31306d
    0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D,
Packit Service 31306d
    0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45,
Packit Service 31306d
    0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9,
Packit Service 31306d
    0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED,
Packit Service 31306d
    0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11,
Packit Service 31306d
    0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D,
Packit Service 31306d
    0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36,
Packit Service 31306d
    0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F,
Packit Service 31306d
    0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56,
Packit Service 31306d
    0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D,
Packit Service 31306d
    0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08,
Packit Service 31306d
    0xCA, 0x18, 0x21, 0x7C, 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B,
Packit Service 31306d
    0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, 0x9B, 0x27, 0x83, 0xA2,
Packit Service 31306d
    0xEC, 0x07, 0xA2, 0x8F, 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9,
Packit Service 31306d
    0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, 0x39, 0x95, 0x49, 0x7C,
Packit Service 31306d
    0xEA, 0x95, 0x6A, 0xE5, 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10,
Packit Service 31306d
    0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, 0xAD, 0x33, 0x17, 0x0D,
Packit Service 31306d
    0x04, 0x50, 0x7A, 0x33, 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64,
Packit Service 31306d
    0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, 0x8A, 0xEA, 0x71, 0x57,
Packit Service 31306d
    0x5D, 0x06, 0x0C, 0x7D, 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7,
Packit Service 31306d
    0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, 0x1E, 0x8C, 0x94, 0xE0,
Packit Service 31306d
    0x4A, 0x25, 0x61, 0x9D, 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B,
Packit Service 31306d
    0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, 0xD8, 0x76, 0x02, 0x73,
Packit Service 31306d
    0x3E, 0xC8, 0x6A, 0x64, 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C,
Packit Service 31306d
    0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, 0x77, 0x09, 0x88, 0xC0,
Packit Service 31306d
    0xBA, 0xD9, 0x46, 0xE2, 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31,
Packit Service 31306d
    0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, 0x4B, 0x82, 0xD1, 0x20,
Packit Service 31306d
    0xA9, 0x21, 0x08, 0x01, 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7,
Packit Service 31306d
    0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, 0x99, 0xC3, 0x27, 0x18,
Packit Service 31306d
    0x6A, 0xF4, 0xE2, 0x3C, 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA,
Packit Service 31306d
    0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, 0xDB, 0xBB, 0xC2, 0xDB,
Packit Service 31306d
    0x04, 0xDE, 0x8E, 0xF9, 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6,
Packit Service 31306d
    0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, 0x99, 0xB2, 0x96, 0x4F,
Packit Service 31306d
    0xA0, 0x90, 0xC3, 0xA2, 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED,
Packit Service 31306d
    0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, 0xB8, 0x1B, 0xDD, 0x76,
Packit Service 31306d
    0x21, 0x70, 0x48, 0x1C, 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9,
Packit Service 31306d
    0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, 0x86, 0xFF, 0xB7, 0xDC,
Packit Service 31306d
    0x90, 0xA6, 0xC0, 0x8F, 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92,
Packit Service 31306d
    0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, 0xC1, 0xD4, 0xDC, 0xB2,
Packit Service 31306d
    0x60, 0x26, 0x46, 0xDE, 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD,
Packit Service 31306d
    0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, 0xE5, 0xDB, 0x38, 0x2F,
Packit Service 31306d
    0x41, 0x30, 0x01, 0xAE, 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31,
Packit Service 31306d
    0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, 0xDA, 0x3E, 0xDB, 0xEB,
Packit Service 31306d
    0xCF, 0x9B, 0x14, 0xED, 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B,
Packit Service 31306d
    0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, 0x33, 0x20, 0x51, 0x51,
Packit Service 31306d
    0x2B, 0xD7, 0xAF, 0x42, 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF,
Packit Service 31306d
    0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, 0xF0, 0x32, 0xEA, 0x15,
Packit Service 31306d
    0xD1, 0x72, 0x1D, 0x03, 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6,
Packit Service 31306d
    0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, 0xB5, 0xA8, 0x40, 0x31,
Packit Service 31306d
    0x90, 0x0B, 0x1C, 0x9E, 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3,
Packit Service 31306d
    0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, 0x0F, 0x1D, 0x45, 0xB7,
Packit Service 31306d
    0xFF, 0x58, 0x5A, 0xC5, 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA,
Packit Service 31306d
    0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, 0x14, 0xCC, 0x5E, 0xD2,
Packit Service 31306d
    0x0F, 0x80, 0x37, 0xE0, 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28,
Packit Service 31306d
    0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, 0xF5, 0x50, 0xAA, 0x3D,
Packit Service 31306d
    0x8A, 0x1F, 0xBF, 0xF0, 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C,
Packit Service 31306d
    0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, 0x38, 0x7F, 0xE8, 0xD7,
Packit Service 31306d
    0x6E, 0x3C, 0x04, 0x68, 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE,
Packit Service 31306d
    0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, 0xE6, 0x94, 0xF9, 0x1E,
Packit Service 31306d
    0x6D, 0xBE, 0x11, 0x59, 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4,
Packit Service 31306d
    0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, 0xD8, 0xBE, 0xC4, 0xD0,
Packit Service 31306d
    0x73, 0xB9, 0x31, 0xBA, 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00,
Packit Service 31306d
    0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, 0x25, 0x76, 0xF6, 0x93,
Packit Service 31306d
    0x6B, 0xA4, 0x24, 0x66, 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68,
Packit Service 31306d
    0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, 0x23, 0x8F, 0x16, 0xCB,
Packit Service 31306d
    0xE3, 0x9D, 0x65, 0x2D, 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9,
Packit Service 31306d
    0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, 0x13, 0xEB, 0x57, 0xA8,
Packit Service 31306d
    0x1A, 0x23, 0xF0, 0xC7, 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B,
Packit Service 31306d
    0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, 0xFA, 0x9D, 0x4B, 0x7F,
Packit Service 31306d
    0xA2, 0xC0, 0x87, 0xE8, 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A,
Packit Service 31306d
    0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, 0x6D, 0x2A, 0x13, 0xF8,
Packit Service 31306d
    0x3F, 0x44, 0xF8, 0x2D, 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36,
Packit Service 31306d
    0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, 0x64, 0xF3, 0x1C, 0xC5,
Packit Service 31306d
    0x08, 0x46, 0x85, 0x1D, 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1,
Packit Service 31306d
    0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, 0xFA, 0xF3, 0x6B, 0xC3,
Packit Service 31306d
    0x1E, 0xCF, 0xA2, 0x68, 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92,
Packit Service 31306d
    0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, 0x88, 0x9A, 0x00, 0x2E,
Packit Service 31306d
    0xD5, 0xEE, 0x38, 0x2B, 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47,
Packit Service 31306d
    0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, 0x9E, 0x30, 0x50, 0xE2,
Packit Service 31306d
    0x76, 0x56, 0x94, 0xDF, 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71,
Packit Service 31306d
    0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF,
Packit Service 31306d
    0xFF, 0xFF, 0xFF, 0xFF};
Packit Service 31306d
Packit Service 31306d
#define P_GROUP18_LEN 1024 /* Size in bytes of the p number for group 18 */
Packit Service 31306d
Packit Service 31306d
bignum ssh_dh_generator;
Packit Service 31306d
bignum ssh_dh_group1;
Packit Service 31306d
bignum ssh_dh_group14;
Packit Service 31306d
bignum ssh_dh_group16;
Packit Service 31306d
bignum ssh_dh_group18;
Packit Service 31306d
static int dh_crypto_initialized;
Packit Service 31306d
Packit Service 31306d
/**
Packit Service 31306d
 * @internal
Packit Service 31306d
 * @brief Initialize global constants used in DH key agreement
Packit Service 31306d
 * @return SSH_OK on success, SSH_ERROR otherwise.
Packit Service 31306d
 */
Packit Service 31306d
int ssh_dh_init(void)
Packit Service 31306d
{
Packit Service 31306d
    unsigned long g_int = 2 ;	/* G is defined as 2 by the ssh2 standards */
Packit Service 31306d
    int rc;
Packit Service 31306d
    if (dh_crypto_initialized) {
Packit Service 31306d
        return SSH_OK;
Packit Service 31306d
    }
Packit Service 31306d
    dh_crypto_initialized = 1;
Packit Service 31306d
Packit Service 31306d
    ssh_dh_generator = bignum_new();
Packit Service 31306d
    if (ssh_dh_generator == NULL) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    rc = bignum_set_word(ssh_dh_generator, g_int);
Packit Service 31306d
    if (rc != 1) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    bignum_bin2bn(p_group1_value, P_GROUP1_LEN, &ssh_dh_group1);
Packit Service 31306d
    if (ssh_dh_group1 == NULL) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    bignum_bin2bn(p_group14_value, P_GROUP14_LEN, &ssh_dh_group14);
Packit Service 31306d
    if (ssh_dh_group14 == NULL) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    bignum_bin2bn(p_group16_value, P_GROUP16_LEN, &ssh_dh_group16);
Packit Service 31306d
    if (ssh_dh_group16 == NULL) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    bignum_bin2bn(p_group18_value, P_GROUP18_LEN, &ssh_dh_group18);
Packit Service 31306d
    if (ssh_dh_group18 == NULL) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    return 0;
Packit Service 31306d
error:
Packit Service 31306d
    ssh_dh_finalize();
Packit Service 31306d
    return SSH_ERROR;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/**
Packit Service 31306d
 * @internal
Packit Service 31306d
 * @brief Finalize and free global constants used in DH key agreement
Packit Service 31306d
 */
Packit Service 31306d
void ssh_dh_finalize(void)
Packit Service 31306d
{
Packit Service 31306d
    if (!dh_crypto_initialized) {
Packit Service 31306d
        return;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    bignum_safe_free(ssh_dh_generator);
Packit Service 31306d
    bignum_safe_free(ssh_dh_group1);
Packit Service 31306d
    bignum_safe_free(ssh_dh_group14);
Packit Service 31306d
    bignum_safe_free(ssh_dh_group16);
Packit Service 31306d
    bignum_safe_free(ssh_dh_group18);
Packit Service 31306d
Packit Service 31306d
    dh_crypto_initialized = 0;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
int ssh_dh_import_next_pubkey_blob(ssh_session session, ssh_string pubkey_blob)
Packit Service 31306d
{
Packit Service 31306d
    return ssh_pki_import_pubkey_blob(pubkey_blob,
Packit Service 31306d
                                      &session->next_crypto->server_pubkey);
Packit Service 31306d
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
static SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply);
Packit Service 31306d
Packit Service 31306d
static ssh_packet_callback dh_client_callbacks[]= {
Packit Service 31306d
    ssh_packet_client_dh_reply
Packit Service 31306d
};
Packit Service 31306d
Packit Service 31306d
static struct ssh_packet_callbacks_struct ssh_dh_client_callbacks = {
Packit Service 31306d
    .start = SSH2_MSG_KEXDH_REPLY,
Packit Service 31306d
    .n_callbacks = 1,
Packit Service 31306d
    .callbacks = dh_client_callbacks,
Packit Service 31306d
    .user = NULL
Packit Service 31306d
};
Packit Service 31306d
Packit Service 31306d
/** @internal
Packit Service 31306d
 * @brief Starts diffie-hellman-group1 key exchange
Packit Service 31306d
 */
Packit Service 31306d
int ssh_client_dh_init(ssh_session session){
Packit Service 31306d
  struct ssh_crypto_struct *crypto = session->next_crypto;
Packit Service 31306d
  const_bignum pubkey;
Packit Service 31306d
  int rc;
Packit Service 31306d
Packit Service 31306d
  rc = ssh_dh_init_common(crypto);
Packit Service 31306d
  if (rc == SSH_ERROR) {
Packit Service 31306d
    goto error;
Packit Service 31306d
  }
Packit Service 31306d
Packit Service 31306d
  rc = ssh_dh_keypair_gen_keys(crypto->dh_ctx, DH_CLIENT_KEYPAIR);
Packit Service 31306d
  if (rc == SSH_ERROR){
Packit Service 31306d
      goto error;
Packit Service 31306d
  }
Packit Service 31306d
  rc = ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_CLIENT_KEYPAIR,
Packit Service 31306d
                               NULL, &pubkey);
Packit Service 31306d
  if (rc != SSH_OK) {
Packit Service 31306d
    goto error;
Packit Service 31306d
  }
Packit Service 31306d
  rc = ssh_buffer_pack(session->out_buffer, "bB", SSH2_MSG_KEXDH_INIT, pubkey);
Packit Service 31306d
  if (rc != SSH_OK) {
Packit Service 31306d
    goto error;
Packit Service 31306d
  }
Packit Service 31306d
Packit Service 31306d
  /* register the packet callbacks */
Packit Service 31306d
  ssh_packet_set_callbacks(session, &ssh_dh_client_callbacks);
Packit Service 31306d
  session->dh_handshake_state = DH_STATE_INIT_SENT;
Packit Service 31306d
Packit Service 31306d
  rc = ssh_packet_send(session);
Packit Service 31306d
  return rc;
Packit Service 31306d
error:
Packit Service 31306d
  ssh_dh_cleanup(crypto);
Packit Service 31306d
  return SSH_ERROR;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
SSH_PACKET_CALLBACK(ssh_packet_client_dh_reply){
Packit Service 31306d
  struct ssh_crypto_struct *crypto=session->next_crypto;
Packit Service 31306d
  ssh_string pubkey_blob = NULL;
Packit Service 31306d
  bignum server_pubkey;
Packit Service 31306d
  int rc;
Packit Service 31306d
Packit Service 31306d
  (void)type;
Packit Service 31306d
  (void)user;
Packit Service 31306d
Packit Service 31306d
  ssh_packet_remove_callbacks(session, &ssh_dh_client_callbacks);
Packit Service 31306d
Packit Service 31306d
  rc = ssh_buffer_unpack(packet, "SBS", &pubkey_blob, &server_pubkey,
Packit Service 31306d
          &crypto->dh_server_signature);
Packit Service 31306d
  if (rc == SSH_ERROR) {
Packit Service 31306d
      goto error;
Packit Service 31306d
  }
Packit Service 31306d
  rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
Packit Service 31306d
                               NULL, server_pubkey);
Packit Service 31306d
  if (rc != SSH_OK) {
Packit Service 31306d
      bignum_safe_free(server_pubkey);
Packit Service 31306d
      goto error;
Packit Service 31306d
  }
Packit Service 31306d
  rc = ssh_dh_import_next_pubkey_blob(session, pubkey_blob);
Packit Service 31306d
  SSH_STRING_FREE(pubkey_blob);
Packit Service 31306d
  if (rc != 0) {
Packit Service 31306d
      goto error;
Packit Service 31306d
  }
Packit Service 31306d
  
Packit Service 31306d
  rc = ssh_dh_compute_shared_secret(session->next_crypto->dh_ctx,
Packit Service 31306d
                                    DH_CLIENT_KEYPAIR, DH_SERVER_KEYPAIR,
Packit Service 31306d
                                    &session->next_crypto->shared_secret);
Packit Service 31306d
  ssh_dh_debug_crypto(session->next_crypto);
Packit Service 31306d
  if (rc == SSH_ERROR){
Packit Service 31306d
    ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
Packit Service 31306d
    goto error;
Packit Service 31306d
  }
Packit Service 31306d
Packit Service 31306d
  /* Send the MSG_NEWKEYS */
Packit Service 31306d
  if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
Packit Service 31306d
    goto error;
Packit Service 31306d
  }
Packit Service 31306d
Packit Service 31306d
  rc=ssh_packet_send(session);
Packit Service 31306d
  if (rc == SSH_ERROR) {
Packit Service 31306d
    goto error;
Packit Service 31306d
  }
Packit Service 31306d
Packit Service 31306d
  SSH_LOG(SSH_LOG_PROTOCOL, "SSH_MSG_NEWKEYS sent");
Packit Service 31306d
  session->dh_handshake_state = DH_STATE_NEWKEYS_SENT;
Packit Service 31306d
  return SSH_PACKET_USED;
Packit Service 31306d
error:
Packit Service 31306d
  ssh_dh_cleanup(session->next_crypto);
Packit Service 31306d
  session->session_state=SSH_SESSION_STATE_ERROR;
Packit Service 31306d
  return SSH_PACKET_USED;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
#ifdef WITH_SERVER
Packit Service 31306d
Packit Service 31306d
static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init);
Packit Service 31306d
Packit Service 31306d
static ssh_packet_callback dh_server_callbacks[] = {
Packit Service 31306d
    ssh_packet_server_dh_init,
Packit Service 31306d
};
Packit Service 31306d
Packit Service 31306d
static struct ssh_packet_callbacks_struct ssh_dh_server_callbacks = {
Packit Service 31306d
    .start = SSH2_MSG_KEXDH_INIT,
Packit Service 31306d
    .n_callbacks = 1,
Packit Service 31306d
    .callbacks = dh_server_callbacks,
Packit Service 31306d
    .user = NULL
Packit Service 31306d
};
Packit Service 31306d
Packit Service 31306d
/** @internal
Packit Service 31306d
 * @brief sets up the diffie-hellman-groupx kex callbacks
Packit Service 31306d
 */
Packit Service 31306d
void ssh_server_dh_init(ssh_session session){
Packit Service 31306d
    /* register the packet callbacks */
Packit Service 31306d
    ssh_packet_set_callbacks(session, &ssh_dh_server_callbacks);
Packit Service 31306d
Packit Service 31306d
    ssh_dh_init_common(session->next_crypto);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/** @internal
Packit Service 31306d
 * @brief processes a SSH_MSG_KEXDH_INIT or SSH_MSG_KEX_DH_GEX_INIT packet and sends
Packit Service 31306d
 * the appropriate SSH_MSG_KEXDH_REPLY or SSH_MSG_KEX_DH_GEX_REPLY
Packit Service 31306d
 */
Packit Service 31306d
int ssh_server_dh_process_init(ssh_session session, ssh_buffer packet)
Packit Service 31306d
{
Packit Service 31306d
    struct ssh_crypto_struct *crypto = session->next_crypto;
Packit Service 31306d
    ssh_key privkey = NULL;
Packit Service 31306d
    enum ssh_digest_e digest = SSH_DIGEST_AUTO;
Packit Service 31306d
    ssh_string sig_blob = NULL;
Packit Service 31306d
    ssh_string pubkey_blob = NULL;
Packit Service 31306d
    bignum client_pubkey;
Packit Service 31306d
    const_bignum server_pubkey;
Packit Service 31306d
    int packet_type;
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    rc = ssh_buffer_unpack(packet, "B", &client_pubkey);
Packit Service 31306d
    if (rc == SSH_ERROR) {
Packit Service 31306d
        ssh_set_error(session, SSH_FATAL, "No e number in client request");
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    rc = ssh_dh_keypair_set_keys(crypto->dh_ctx, DH_CLIENT_KEYPAIR,
Packit Service 31306d
                                 NULL, client_pubkey);
Packit Service 31306d
    if (rc != SSH_OK) {
Packit Service 31306d
        bignum_safe_free(client_pubkey);
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    rc = ssh_dh_keypair_gen_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR);
Packit Service 31306d
    if (rc == SSH_ERROR) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    rc = ssh_get_key_params(session, &privkey, &digest);
Packit Service 31306d
    if (rc != SSH_OK) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    rc = ssh_dh_compute_shared_secret(crypto->dh_ctx,
Packit Service 31306d
                                      DH_SERVER_KEYPAIR, DH_CLIENT_KEYPAIR,
Packit Service 31306d
                                      &crypto->shared_secret);
Packit Service 31306d
    ssh_dh_debug_crypto(crypto);
Packit Service 31306d
    if (rc == SSH_ERROR) {
Packit Service 31306d
        ssh_set_error(session, SSH_FATAL, "Could not generate shared secret");
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    rc = ssh_make_sessionid(session);
Packit Service 31306d
    if (rc != SSH_OK) {
Packit Service 31306d
        ssh_set_error(session, SSH_FATAL, "Could not create a session id");
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    sig_blob = ssh_srv_pki_do_sign_sessionid(session, privkey, digest);
Packit Service 31306d
    if (sig_blob == NULL) {
Packit Service 31306d
        ssh_set_error(session, SSH_FATAL, "Could not sign the session id");
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    switch (crypto->kex_type){
Packit Service 31306d
    case SSH_KEX_DH_GROUP1_SHA1:
Packit Service 31306d
    case SSH_KEX_DH_GROUP14_SHA1:
Packit Service 31306d
    case SSH_KEX_DH_GROUP14_SHA256:
Packit Service 31306d
    case SSH_KEX_DH_GROUP16_SHA512:
Packit Service 31306d
    case SSH_KEX_DH_GROUP18_SHA512:
Packit Service 31306d
        packet_type = SSH2_MSG_KEXDH_REPLY;
Packit Service 31306d
        break;
Packit Service 31306d
#ifdef WITH_GEX
Packit Service 31306d
    case SSH_KEX_DH_GEX_SHA1:
Packit Service 31306d
    case SSH_KEX_DH_GEX_SHA256:
Packit Service 31306d
        packet_type = SSH2_MSG_KEX_DH_GEX_REPLY;
Packit Service 31306d
        break;
Packit Service 31306d
#endif /* WITH_GEX */
Packit Service 31306d
    default:
Packit Service 31306d
        ssh_set_error(session, SSH_FATAL, "Invalid kex type");
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    rc = ssh_dh_keypair_get_keys(crypto->dh_ctx, DH_SERVER_KEYPAIR,
Packit Service 31306d
                                 NULL, &server_pubkey);
Packit Service 31306d
    if (rc != SSH_OK){
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
Packit Service 31306d
    if (rc != SSH_OK){
Packit Service 31306d
        ssh_set_error_oom(session);
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    rc = ssh_buffer_pack(session->out_buffer,
Packit Service 31306d
                         "bSBS",
Packit Service 31306d
                         packet_type,
Packit Service 31306d
                         pubkey_blob,
Packit Service 31306d
                         server_pubkey,
Packit Service 31306d
                         sig_blob);
Packit Service 31306d
    SSH_STRING_FREE(sig_blob);
Packit Service 31306d
    SSH_STRING_FREE(pubkey_blob);
Packit Service 31306d
    if(rc != SSH_OK) {
Packit Service 31306d
        ssh_set_error_oom(session);
Packit Service 31306d
        ssh_buffer_reinit(session->out_buffer);
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    rc = ssh_packet_send(session);
Packit Service 31306d
    if (rc == SSH_ERROR) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    SSH_LOG(SSH_LOG_DEBUG, "Sent KEX_DH_[GEX]_REPLY");
Packit Service 31306d
Packit Service 31306d
    if (ssh_buffer_add_u8(session->out_buffer, SSH2_MSG_NEWKEYS) < 0) {
Packit Service 31306d
        ssh_buffer_reinit(session->out_buffer);
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    session->dh_handshake_state=DH_STATE_NEWKEYS_SENT;
Packit Service 31306d
    if (ssh_packet_send(session) == SSH_ERROR) {
Packit Service 31306d
        goto error;
Packit Service 31306d
    }
Packit Service 31306d
    SSH_LOG(SSH_LOG_PACKET, "SSH_MSG_NEWKEYS sent");
Packit Service 31306d
Packit Service 31306d
    return SSH_OK;
Packit Service 31306d
error:
Packit Service 31306d
    SSH_STRING_FREE(sig_blob);
Packit Service 31306d
    SSH_STRING_FREE(pubkey_blob);
Packit Service 31306d
Packit Service 31306d
    session->session_state = SSH_SESSION_STATE_ERROR;
Packit Service 31306d
    ssh_dh_cleanup(session->next_crypto);
Packit Service 31306d
    return SSH_ERROR;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/** @internal
Packit Service 31306d
 * @brief parse an incoming SSH_MSG_KEXDH_INIT packet and complete
Packit Service 31306d
 *        Diffie-Hellman key exchange
Packit Service 31306d
 **/
Packit Service 31306d
static SSH_PACKET_CALLBACK(ssh_packet_server_dh_init){
Packit Service 31306d
    (void)type;
Packit Service 31306d
    (void)user;
Packit Service 31306d
    SSH_LOG(SSH_LOG_DEBUG, "Received SSH_MSG_KEXDH_INIT");
Packit Service 31306d
    ssh_packet_remove_callbacks(session, &ssh_dh_server_callbacks);
Packit Service 31306d
    ssh_server_dh_process_init(session, packet);
Packit Service 31306d
    return SSH_PACKET_USED;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/** @internal
Packit Service 31306d
 * @brief Choose a fallback group for the DH Group exchange if the
Packit Service 31306d
 * moduli file is not readable
Packit Service 31306d
 * @param[in] pmax maximum requestsd group size
Packit Service 31306d
 * @param[out] modulus
Packit Service 31306d
 * @param[out] generator
Packit Service 31306d
 * @returns SSH_OK on success, SSH_ERROR otherwise
Packit Service 31306d
 */
Packit Service 31306d
int ssh_fallback_group(uint32_t pmax,
Packit Service 31306d
                       bignum *modulus,
Packit Service 31306d
                       bignum *generator)
Packit Service 31306d
{
Packit Service 31306d
    *modulus = NULL;
Packit Service 31306d
    *generator = NULL;
Packit Service 31306d
Packit Service 31306d
    if (pmax < 3072) {
Packit Service 31306d
        bignum_dup(ssh_dh_group14, modulus);
Packit Service 31306d
    } else if (pmax < 6144) {
Packit Service 31306d
        bignum_dup(ssh_dh_group16, modulus);
Packit Service 31306d
    } else {
Packit Service 31306d
        bignum_dup(ssh_dh_group18, modulus);
Packit Service 31306d
    }
Packit Service 31306d
    if (*modulus == NULL) {
Packit Service 31306d
        return SSH_ERROR;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    bignum_dup(ssh_dh_generator, generator);
Packit Service 31306d
    if (*generator == NULL) {
Packit Service 31306d
        bignum_safe_free((*modulus));
Packit Service 31306d
        return SSH_ERROR;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    return SSH_OK;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
#endif /* WITH_SERVER */
Packit Service 31306d
Packit Service 31306d
/**
Packit Service 31306d
 * @addtogroup libssh_session
Packit Service 31306d
 *
Packit Service 31306d
 * @{
Packit Service 31306d
 */
Packit Service 31306d
Packit Service 31306d
bool ssh_dh_is_known_group(bignum modulus, bignum generator)
Packit Service 31306d
{
Packit Service 31306d
    int cmp, bits;
Packit Service 31306d
    bignum m = NULL;
Packit Service 31306d
Packit Service 31306d
    bits = bignum_num_bits(modulus);
Packit Service 31306d
    if (bits < 3072) {
Packit Service 31306d
        m = ssh_dh_group14;
Packit Service 31306d
    } else if (bits < 6144) {
Packit Service 31306d
        m = ssh_dh_group16;
Packit Service 31306d
    } else {
Packit Service 31306d
        m = ssh_dh_group18;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    cmp = bignum_cmp(m, modulus);
Packit Service 31306d
    if (cmp != 0) {
Packit Service 31306d
        return false;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    cmp = bignum_cmp(ssh_dh_generator, generator);
Packit Service 31306d
    if (cmp != 0) {
Packit Service 31306d
        return false;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    SSH_LOG(SSH_LOG_TRACE, "The received primes in FIPS are known");
Packit Service 31306d
    return true;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
ssh_key ssh_dh_get_current_server_publickey(ssh_session session)
Packit Service 31306d
{
Packit Service 31306d
    if (session->current_crypto == NULL) {
Packit Service 31306d
        return NULL;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    return session->current_crypto->server_pubkey;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/* Caller need to free the blob */
Packit Service 31306d
int ssh_dh_get_current_server_publickey_blob(ssh_session session,
Packit Service 31306d
                                     ssh_string *pubkey_blob)
Packit Service 31306d
{
Packit Service 31306d
    const ssh_key pubkey = ssh_dh_get_current_server_publickey(session);
Packit Service 31306d
Packit Service 31306d
    return ssh_pki_export_pubkey_blob(pubkey, pubkey_blob);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
ssh_key ssh_dh_get_next_server_publickey(ssh_session session)
Packit Service 31306d
{
Packit Service 31306d
    return session->next_crypto->server_pubkey;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/* Caller need to free the blob */
Packit Service 31306d
int ssh_dh_get_next_server_publickey_blob(ssh_session session,
Packit Service 31306d
                                          ssh_string *pubkey_blob)
Packit Service 31306d
{
Packit Service 31306d
    const ssh_key pubkey = ssh_dh_get_next_server_publickey(session);
Packit Service 31306d
Packit Service 31306d
    return ssh_pki_export_pubkey_blob(pubkey, pubkey_blob);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/**
Packit Service 31306d
 * @internal
Packit Service 31306d
 *
Packit Service 31306d
 * @brief Convert a buffer into an unpadded base64 string.
Packit Service 31306d
 * The caller has to free the memory.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  hash         What should be converted to a base64 string.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  len          Length of the buffer to convert.
Packit Service 31306d
 *
Packit Service 31306d
 * @return              The base64 string or NULL on error.
Packit Service 31306d
 *
Packit Service 31306d
 * @see ssh_string_free_char()
Packit Service 31306d
 */
Packit Service 31306d
static char *ssh_get_b64_unpadded(const unsigned char *hash, size_t len)
Packit Service 31306d
{
Packit Service 31306d
    char *b64_padded = NULL;
Packit Service 31306d
    char *b64_unpadded = NULL;
Packit Service 31306d
    size_t k;
Packit Service 31306d
Packit Service 31306d
    b64_padded = (char *)bin_to_base64(hash, (int)len);
Packit Service 31306d
    if (b64_padded == NULL) {
Packit Service 31306d
        return NULL;
Packit Service 31306d
    }
Packit Service 31306d
    for (k = strlen(b64_padded); k != 0 && b64_padded[k-1] == '='; k--);
Packit Service 31306d
Packit Service 31306d
    b64_unpadded = strndup(b64_padded, k);
Packit Service 31306d
    SAFE_FREE(b64_padded);
Packit Service 31306d
Packit Service 31306d
    return b64_unpadded;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/**
Packit Service 31306d
 * @brief Get a hash as a human-readable hex- or base64-string.
Packit Service 31306d
 *
Packit Service 31306d
 * This gets an allocated fingerprint hash.  If it is a SHA sum, it will
Packit Service 31306d
 * return an unpadded base64 strings.  If it is a MD5 sum, it will return hex
Packit Service 31306d
 * string. Either way, the output is prepended by the hash-type.
Packit Service 31306d
 *
Packit Service 31306d
 * @warning Do NOT use MD5 or SHA1! Those hash functions are being deprecated.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  type         Which sort of hash is given, use
Packit Service 31306d
 *                      SSH_PUBLICKEY_HASH_SHA256 or better.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  hash         The hash to be converted to fingerprint.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  len          Length of the buffer to convert.
Packit Service 31306d
 *
Packit Service 31306d
 * @return Returns the allocated fingerprint hash or NULL on error.
Packit Service 31306d
 *
Packit Service 31306d
 * @see ssh_string_free_char()
Packit Service 31306d
 */
Packit Service 31306d
char *ssh_get_fingerprint_hash(enum ssh_publickey_hash_type type,
Packit Service 31306d
                               unsigned char *hash,
Packit Service 31306d
                               size_t len)
Packit Service 31306d
{
Packit Service 31306d
    const char *prefix = "UNKNOWN";
Packit Service 31306d
    char *fingerprint = NULL;
Packit Service 31306d
    char *str = NULL;
Packit Service 31306d
    size_t str_len;
Packit Service 31306d
    int rc;
Packit Service 31306d
Packit Service 31306d
    switch (type) {
Packit Service 31306d
    case SSH_PUBLICKEY_HASH_SHA1:
Packit Service 31306d
    case SSH_PUBLICKEY_HASH_SHA256:
Packit Service 31306d
        fingerprint = ssh_get_b64_unpadded(hash, len);
Packit Service 31306d
        break;
Packit Service 31306d
    case SSH_PUBLICKEY_HASH_MD5:
Packit Service 31306d
        fingerprint = ssh_get_hexa(hash, len);
Packit Service 31306d
        break;
Packit Service 31306d
    }
Packit Service 31306d
    if (fingerprint == NULL) {
Packit Service 31306d
        return NULL;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    switch (type) {
Packit Service 31306d
    case SSH_PUBLICKEY_HASH_MD5:
Packit Service 31306d
        prefix = "MD5";
Packit Service 31306d
        break;
Packit Service 31306d
    case SSH_PUBLICKEY_HASH_SHA1:
Packit Service 31306d
        prefix = "SHA1";
Packit Service 31306d
        break;
Packit Service 31306d
    case SSH_PUBLICKEY_HASH_SHA256:
Packit Service 31306d
        prefix = "SHA256";
Packit Service 31306d
        break;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    str_len = strlen(prefix);
Packit Service 31306d
    if (str_len + 1 + strlen(fingerprint) + 1 < str_len) {
Packit Service 31306d
        SAFE_FREE(fingerprint);
Packit Service 31306d
        return NULL;
Packit Service 31306d
    }
Packit Service 31306d
    str_len += 1 + strlen(fingerprint) + 1;
Packit Service 31306d
Packit Service 31306d
    str = malloc(str_len);
Packit Service 31306d
    if (str == NULL) {
Packit Service 31306d
        SAFE_FREE(fingerprint);
Packit Service 31306d
        return NULL;
Packit Service 31306d
    }
Packit Service 31306d
    rc = snprintf(str, str_len, "%s:%s", prefix, fingerprint);
Packit Service 31306d
    SAFE_FREE(fingerprint);
Packit Service 31306d
    if (rc < 0 || rc < (int)(str_len - 1)) {
Packit Service 31306d
        SAFE_FREE(str);
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    return str;
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/**
Packit Service 31306d
 * @brief Print a hash as a human-readable hex- or base64-string.
Packit Service 31306d
 *
Packit Service 31306d
 * This prints an unpadded base64 strings for SHA sums and hex strings for MD5
Packit Service 31306d
 * sum.  Either way, the output is prepended by the hash-type.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  type         Which sort of hash is given. Use
Packit Service 31306d
 *                      SSH_PUBLICKEY_HASH_SHA256 or better.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  hash         The hash to be converted to fingerprint.
Packit Service 31306d
 *
Packit Service 31306d
 * @param  len          Length of the buffer to convert.
Packit Service 31306d
 *
Packit Service 31306d
 * @see ssh_get_publickey_hash()
Packit Service 31306d
 * @see ssh_get_fingerprint_hash()
Packit Service 31306d
 */
Packit Service 31306d
void ssh_print_hash(enum ssh_publickey_hash_type type,
Packit Service 31306d
                    unsigned char *hash,
Packit Service 31306d
                    size_t len)
Packit Service 31306d
{
Packit Service 31306d
    char *fingerprint = NULL;
Packit Service 31306d
Packit Service 31306d
    fingerprint = ssh_get_fingerprint_hash(type,
Packit Service 31306d
                                           hash,
Packit Service 31306d
                                           len);
Packit Service 31306d
    if (fingerprint == NULL) {
Packit Service 31306d
        return;
Packit Service 31306d
    }
Packit Service 31306d
Packit Service 31306d
    fprintf(stderr, "%s\n", fingerprint);
Packit Service 31306d
Packit Service 31306d
    SAFE_FREE(fingerprint);
Packit Service 31306d
}
Packit Service 31306d
Packit Service 31306d
/** @} */