LCOV - code coverage report
Current view: top level - openssh-6.6p1 - kex.c (source / functions) Hit Total Coverage
Test: lcov_coverage_final.info Lines: 274 327 83.8 %
Date: 2014-08-01 Functions: 23 25 92.0 %
Branches: 127 188 67.6 %

           Branch data     Line data    Source code
       1                 :            : /* $OpenBSD: kex.c,v 1.98 2014/02/02 03:44:31 djm Exp $ */
       2                 :            : /*
       3                 :            :  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
       4                 :            :  *
       5                 :            :  * Redistribution and use in source and binary forms, with or without
       6                 :            :  * modification, are permitted provided that the following conditions
       7                 :            :  * are met:
       8                 :            :  * 1. Redistributions of source code must retain the above copyright
       9                 :            :  *    notice, this list of conditions and the following disclaimer.
      10                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      11                 :            :  *    notice, this list of conditions and the following disclaimer in the
      12                 :            :  *    documentation and/or other materials provided with the distribution.
      13                 :            :  *
      14                 :            :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
      15                 :            :  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
      16                 :            :  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
      17                 :            :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
      18                 :            :  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
      19                 :            :  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
      20                 :            :  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      21                 :            :  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
      22                 :            :  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
      23                 :            :  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      24                 :            :  */
      25                 :            : 
      26                 :            : #include "includes.h"
      27                 :            : 
      28                 :            : #include <sys/param.h>
      29                 :            : 
      30                 :            : #include <signal.h>
      31                 :            : #include <stdarg.h>
      32                 :            : #include <stdio.h>
      33                 :            : #include <stdlib.h>
      34                 :            : #include <string.h>
      35                 :            : 
      36                 :            : #include <openssl/crypto.h>
      37                 :            : 
      38                 :            : #include "xmalloc.h"
      39                 :            : #include "ssh2.h"
      40                 :            : #include "buffer.h"
      41                 :            : #include "packet.h"
      42                 :            : #include "compat.h"
      43                 :            : #include "cipher.h"
      44                 :            : #include "key.h"
      45                 :            : #include "kex.h"
      46                 :            : #include "log.h"
      47                 :            : #include "mac.h"
      48                 :            : #include "match.h"
      49                 :            : #include "dispatch.h"
      50                 :            : #include "monitor.h"
      51                 :            : #include "roaming.h"
      52                 :            : #include "digest.h"
      53                 :            : 
      54                 :            : #if OPENSSL_VERSION_NUMBER >= 0x00907000L
      55                 :            : # if defined(HAVE_EVP_SHA256)
      56                 :            : # define evp_ssh_sha256 EVP_sha256
      57                 :            : # else
      58                 :            : extern const EVP_MD *evp_ssh_sha256(void);
      59                 :            : # endif
      60                 :            : #endif
      61                 :            : 
      62                 :            : /* prototype */
      63                 :            : static void kex_kexinit_finish(Kex *);
      64                 :            : static void kex_choose_conf(Kex *);
      65                 :            : 
      66                 :            : struct kexalg {
      67                 :            :         char *name;
      68                 :            :         int type;
      69                 :            :         int ec_nid;
      70                 :            :         int hash_alg;
      71                 :            : };
      72                 :            : static const struct kexalg kexalgs[] = {
      73                 :            :         { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
      74                 :            :         { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
      75                 :            :         { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
      76                 :            : #ifdef HAVE_EVP_SHA256
      77                 :            :         { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
      78                 :            : #endif
      79                 :            : #ifdef OPENSSL_HAS_ECC
      80                 :            :         { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
      81                 :            :             NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
      82                 :            :         { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
      83                 :            :             SSH_DIGEST_SHA384 },
      84                 :            : # ifdef OPENSSL_HAS_NISTP521
      85                 :            :         { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
      86                 :            :             SSH_DIGEST_SHA512 },
      87                 :            : # endif
      88                 :            : #endif
      89                 :            :         { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
      90                 :            : #ifdef HAVE_EVP_SHA256
      91                 :            :         { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
      92                 :            : #endif
      93                 :            :         { NULL, -1, -1, -1},
      94                 :            : };
      95                 :            : 
      96                 :            : char *
      97                 :        147 : kex_alg_list(char sep)
      98                 :            : {
      99                 :        147 :         char *ret = NULL;
     100                 :        147 :         size_t nlen, rlen = 0;
     101                 :            :         const struct kexalg *k;
     102                 :            : 
     103         [ +  + ]:       1470 :         for (k = kexalgs; k->name != NULL; k++) {
     104         [ +  + ]:       1323 :                 if (ret != NULL)
     105                 :       1176 :                         ret[rlen++] = sep;
     106                 :       1323 :                 nlen = strlen(k->name);
     107                 :       1323 :                 ret = xrealloc(ret, 1, rlen + nlen + 2);
     108                 :       1323 :                 memcpy(ret + rlen, k->name, nlen + 1);
     109                 :       1323 :                 rlen += nlen;
     110                 :            :         }
     111                 :        147 :         return ret;
     112                 :            : }
     113                 :            : 
     114                 :            : static const struct kexalg *
     115                 :       2822 : kex_alg_by_name(const char *name)
     116                 :            : {
     117                 :            :         const struct kexalg *k;
     118                 :            : 
     119         [ +  - ]:      17089 :         for (k = kexalgs; k->name != NULL; k++) {
     120         [ +  + ]:      17089 :                 if (strcmp(k->name, name) == 0)
     121                 :            :                         return k;
     122                 :            :         }
     123                 :            :         return NULL;
     124                 :            : }
     125                 :            : 
     126                 :            : /* Validate KEX method name list */
     127                 :            : int
     128                 :        508 : kex_names_valid(const char *names)
     129                 :            : {
     130                 :            :         char *s, *cp, *p;
     131                 :            : 
     132 [ +  - ][ +  - ]:        508 :         if (names == NULL || strcmp(names, "") == 0)
     133                 :            :                 return 0;
     134                 :        508 :         s = cp = xstrdup(names);
     135 [ +  + ][ +  - ]:       1452 :         for ((p = strsep(&cp, ",")); p && *p != '\0';
     136                 :        944 :             (p = strsep(&cp, ","))) {
     137         [ -  + ]:        944 :                 if (kex_alg_by_name(p) == NULL) {
     138                 :          0 :                         error("Unsupported KEX algorithm \"%.100s\"", p);
     139                 :          0 :                         free(s);
     140                 :          0 :                         return 0;
     141                 :            :                 }
     142                 :            :         }
     143                 :        508 :         debug3("kex names ok: [%s]", names);
     144                 :        508 :         free(s);
     145                 :        508 :         return 1;
     146                 :            : }
     147                 :            : 
     148                 :            : /* put algorithm proposal into buffer */
     149                 :            : static void
     150                 :       1426 : kex_prop2buf(Buffer *b, char *proposal[PROPOSAL_MAX])
     151                 :            : {
     152                 :            :         u_int i;
     153                 :            : 
     154                 :       1426 :         buffer_clear(b);
     155                 :            :         /*
     156                 :            :          * add a dummy cookie, the cookie will be overwritten by
     157                 :            :          * kex_send_kexinit(), each time a kexinit is set
     158                 :            :          */
     159         [ +  + ]:      24242 :         for (i = 0; i < KEX_COOKIE_LEN; i++)
     160                 :      22816 :                 buffer_put_char(b, 0);
     161         [ +  + ]:      15686 :         for (i = 0; i < PROPOSAL_MAX; i++)
     162                 :      14260 :                 buffer_put_cstring(b, proposal[i]);
     163                 :       1426 :         buffer_put_char(b, 0);                  /* first_kex_packet_follows */
     164                 :       1426 :         buffer_put_int(b, 0);                   /* uint32 reserved */
     165                 :       1426 : }
     166                 :            : 
     167                 :            : /* parse buffer and return algorithm proposal */
     168                 :            : static char **
     169                 :       3756 : kex_buf2prop(Buffer *raw, int *first_kex_follows)
     170                 :            : {
     171                 :            :         Buffer b;
     172                 :            :         u_int i;
     173                 :            :         char **proposal;
     174                 :            : 
     175                 :       3756 :         proposal = xcalloc(PROPOSAL_MAX, sizeof(char *));
     176                 :            : 
     177                 :       3756 :         buffer_init(&b);
     178                 :       3756 :         buffer_append(&b, buffer_ptr(raw), buffer_len(raw));
     179                 :            :         /* skip cookie */
     180         [ +  + ]:      63852 :         for (i = 0; i < KEX_COOKIE_LEN; i++)
     181                 :      60096 :                 buffer_get_char(&b);
     182                 :            :         /* extract kex init proposal strings */
     183         [ +  + ]:      41316 :         for (i = 0; i < PROPOSAL_MAX; i++) {
     184                 :      37560 :                 proposal[i] = buffer_get_cstring(&b,NULL);
     185                 :      37560 :                 debug2("kex_parse_kexinit: %s", proposal[i]);
     186                 :            :         }
     187                 :            :         /* first kex follows / reserved */
     188                 :       3756 :         i = buffer_get_char(&b);
     189         [ +  + ]:       3756 :         if (first_kex_follows != NULL)
     190                 :       1878 :                 *first_kex_follows = i;
     191                 :       3756 :         debug2("kex_parse_kexinit: first_kex_follows %d ", i);
     192                 :       3756 :         i = buffer_get_int(&b);
     193                 :       3756 :         debug2("kex_parse_kexinit: reserved %u ", i);
     194                 :       3756 :         buffer_free(&b);
     195                 :       3756 :         return proposal;
     196                 :            : }
     197                 :            : 
     198                 :            : static void
     199                 :       3750 : kex_prop_free(char **proposal)
     200                 :            : {
     201                 :            :         u_int i;
     202                 :            : 
     203         [ +  + ]:      41250 :         for (i = 0; i < PROPOSAL_MAX; i++)
     204                 :      37500 :                 free(proposal[i]);
     205                 :       3750 :         free(proposal);
     206                 :       3750 : }
     207                 :            : 
     208                 :            : /* ARGSUSED */
     209                 :            : static void
     210                 :          0 : kex_protocol_error(int type, u_int32_t seq, void *ctxt)
     211                 :            : {
     212                 :          0 :         error("Hm, kex protocol error: type %d seq %u", type, seq);
     213                 :          0 : }
     214                 :            : 
     215                 :            : static void
     216                 :       3298 : kex_reset_dispatch(void)
     217                 :            : {
     218                 :       3298 :         dispatch_range(SSH2_MSG_TRANSPORT_MIN,
     219                 :            :             SSH2_MSG_TRANSPORT_MAX, &kex_protocol_error);
     220                 :       3298 :         dispatch_set(SSH2_MSG_KEXINIT, &kex_input_kexinit);
     221                 :       3298 : }
     222                 :            : 
     223                 :            : void
     224                 :       1872 : kex_finish(Kex *kex)
     225                 :            : {
     226                 :       1872 :         kex_reset_dispatch();
     227                 :            : 
     228                 :       1872 :         packet_start(SSH2_MSG_NEWKEYS);
     229                 :       1872 :         packet_send();
     230                 :            :         /* packet_write_wait(); */
     231                 :       1872 :         debug("SSH2_MSG_NEWKEYS sent");
     232                 :            : 
     233                 :       1872 :         debug("expecting SSH2_MSG_NEWKEYS");
     234                 :       1872 :         packet_read_expect(SSH2_MSG_NEWKEYS);
     235         [ -  + ]:       1872 :         packet_check_eom();
     236                 :       1872 :         debug("SSH2_MSG_NEWKEYS received");
     237                 :            : 
     238                 :       1872 :         kex->done = 1;
     239                 :       1872 :         buffer_clear(&kex->peer);
     240                 :            :         /* buffer_clear(&kex->my); */
     241                 :       1872 :         kex->flags &= ~KEX_INIT_SENT;
     242                 :       1872 :         free(kex->name);
     243                 :       1872 :         kex->name = NULL;
     244                 :       1872 : }
     245                 :            : 
     246                 :            : void
     247                 :       1879 : kex_send_kexinit(Kex *kex)
     248                 :            : {
     249                 :       1879 :         u_int32_t rnd = 0;
     250                 :            :         u_char *cookie;
     251                 :            :         u_int i;
     252                 :            : 
     253         [ -  + ]:       1879 :         if (kex == NULL) {
     254                 :          0 :                 error("kex_send_kexinit: no kex, cannot rekey");
     255                 :          0 :                 return;
     256                 :            :         }
     257         [ -  + ]:       1879 :         if (kex->flags & KEX_INIT_SENT) {
     258                 :          0 :                 debug("KEX_INIT_SENT");
     259                 :          0 :                 return;
     260                 :            :         }
     261                 :       1879 :         kex->done = 0;
     262                 :            : 
     263                 :            :         /* generate a random cookie */
     264         [ -  + ]:       1879 :         if (buffer_len(&kex->my) < KEX_COOKIE_LEN)
     265                 :          0 :                 fatal("kex_send_kexinit: kex proposal too short");
     266                 :       1879 :         cookie = buffer_ptr(&kex->my);
     267         [ +  + ]:      31943 :         for (i = 0; i < KEX_COOKIE_LEN; i++) {
     268         [ +  + ]:      30064 :                 if (i % 4 == 0)
     269                 :       7516 :                         rnd = arc4random();
     270                 :      30064 :                 cookie[i] = rnd;
     271                 :      30064 :                 rnd >>= 8;
     272                 :            :         }
     273                 :       1879 :         packet_start(SSH2_MSG_KEXINIT);
     274                 :       1879 :         packet_put_raw(buffer_ptr(&kex->my), buffer_len(&kex->my));
     275                 :       1879 :         packet_send();
     276                 :       1879 :         debug("SSH2_MSG_KEXINIT sent");
     277                 :       1879 :         kex->flags |= KEX_INIT_SENT;
     278                 :            : }
     279                 :            : 
     280                 :            : /* ARGSUSED */
     281                 :            : void
     282                 :       1878 : kex_input_kexinit(int type, u_int32_t seq, void *ctxt)
     283                 :            : {
     284                 :            :         char *ptr;
     285                 :            :         u_int i, dlen;
     286                 :       1878 :         Kex *kex = (Kex *)ctxt;
     287                 :            : 
     288                 :       1878 :         debug("SSH2_MSG_KEXINIT received");
     289         [ -  + ]:       1878 :         if (kex == NULL)
     290                 :          0 :                 fatal("kex_input_kexinit: no kex, cannot rekey");
     291                 :            : 
     292                 :       1878 :         ptr = packet_get_raw(&dlen);
     293                 :       1878 :         buffer_append(&kex->peer, ptr, dlen);
     294                 :            : 
     295                 :            :         /* discard packet */
     296         [ +  + ]:      31926 :         for (i = 0; i < KEX_COOKIE_LEN; i++)
     297                 :      30048 :                 packet_get_char();
     298         [ +  + ]:      20658 :         for (i = 0; i < PROPOSAL_MAX; i++)
     299                 :      18780 :                 free(packet_get_string(NULL));
     300                 :            :         /*
     301                 :            :          * XXX RFC4253 sec 7: "each side MAY guess" - currently no supported
     302                 :            :          * KEX method has the server move first, but a server might be using
     303                 :            :          * a custom method or one that we otherwise don't support. We should
     304                 :            :          * be prepared to remember first_kex_follows here so we can eat a
     305                 :            :          * packet later.
     306                 :            :          * XXX2 - RFC4253 is kind of ambiguous on what first_kex_follows means
     307                 :            :          * for cases where the server *doesn't* go first. I guess we should
     308                 :            :          * ignore it when it is set for these cases, which is what we do now.
     309                 :            :          */
     310                 :       1878 :         (void) packet_get_char();       /* first_kex_follows */
     311                 :       1878 :         (void) packet_get_int();        /* reserved */
     312         [ -  + ]:       1878 :         packet_check_eom();
     313                 :            : 
     314                 :       1878 :         kex_kexinit_finish(kex);
     315                 :       1872 : }
     316                 :            : 
     317                 :            : Kex *
     318                 :       1426 : kex_setup(char *proposal[PROPOSAL_MAX])
     319                 :            : {
     320                 :            :         Kex *kex;
     321                 :            : 
     322                 :       1426 :         kex = xcalloc(1, sizeof(*kex));
     323                 :       1426 :         buffer_init(&kex->peer);
     324                 :       1426 :         buffer_init(&kex->my);
     325                 :       1426 :         kex_prop2buf(&kex->my, proposal);
     326                 :       1426 :         kex->done = 0;
     327                 :            : 
     328                 :       1426 :         kex_send_kexinit(kex);                                  /* we start */
     329                 :       1426 :         kex_reset_dispatch();
     330                 :            : 
     331                 :       1426 :         return kex;
     332                 :            : }
     333                 :            : 
     334                 :            : static void
     335                 :       1878 : kex_kexinit_finish(Kex *kex)
     336                 :            : {
     337         [ +  + ]:       1878 :         if (!(kex->flags & KEX_INIT_SENT))
     338                 :          5 :                 kex_send_kexinit(kex);
     339                 :            : 
     340                 :       1878 :         kex_choose_conf(kex);
     341                 :            : 
     342 [ +  - ][ +  - ]:       1875 :         if (kex->kex_type >= 0 && kex->kex_type < KEX_MAX &&
     343                 :       1875 :             kex->kex[kex->kex_type] != NULL) {
     344                 :       1875 :                 (kex->kex[kex->kex_type])(kex);
     345                 :            :         } else {
     346                 :          0 :                 fatal("Unsupported key exchange %d", kex->kex_type);
     347                 :            :         }
     348                 :       1872 : }
     349                 :            : 
     350                 :            : static void
     351                 :       3756 : choose_enc(Enc *enc, char *client, char *server)
     352                 :            : {
     353                 :       3756 :         char *name = match_list(client, server, NULL);
     354         [ -  + ]:       3756 :         if (name == NULL)
     355                 :          0 :                 fatal("no matching cipher found: client %s server %s",
     356                 :            :                     client, server);
     357         [ -  + ]:       3756 :         if ((enc->cipher = cipher_by_name(name)) == NULL)
     358                 :          0 :                 fatal("matching cipher is not supported: %s", name);
     359                 :       3756 :         enc->name = name;
     360                 :       3756 :         enc->enabled = 0;
     361                 :       3756 :         enc->iv = NULL;
     362                 :       3756 :         enc->iv_len = cipher_ivlen(enc->cipher);
     363                 :       3756 :         enc->key = NULL;
     364                 :       3756 :         enc->key_len = cipher_keylen(enc->cipher);
     365                 :       3756 :         enc->block_size = cipher_blocksize(enc->cipher);
     366                 :       3756 : }
     367                 :            : 
     368                 :            : static void
     369                 :       3384 : choose_mac(Mac *mac, char *client, char *server)
     370                 :            : {
     371                 :       3384 :         char *name = match_list(client, server, NULL);
     372         [ -  + ]:       3384 :         if (name == NULL)
     373                 :          0 :                 fatal("no matching mac found: client %s server %s",
     374                 :            :                     client, server);
     375         [ -  + ]:       3384 :         if (mac_setup(mac, name) < 0)
     376                 :          0 :                 fatal("unsupported mac %s", name);
     377                 :            :         /* truncate the key */
     378         [ -  + ]:       3384 :         if (datafellows & SSH_BUG_HMAC)
     379                 :          0 :                 mac->key_len = 16;
     380                 :       3384 :         mac->name = name;
     381                 :       3384 :         mac->key = NULL;
     382                 :       3384 :         mac->enabled = 0;
     383                 :       3384 : }
     384                 :            : 
     385                 :            : static void
     386                 :       3756 : choose_comp(Comp *comp, char *client, char *server)
     387                 :            : {
     388                 :       3756 :         char *name = match_list(client, server, NULL);
     389         [ -  + ]:       3756 :         if (name == NULL)
     390                 :          0 :                 fatal("no matching comp found: client %s server %s", client, server);
     391         [ -  + ]:       3756 :         if (strcmp(name, "zlib@openssh.com") == 0) {
     392                 :          0 :                 comp->type = COMP_DELAYED;
     393         [ -  + ]:       3756 :         } else if (strcmp(name, "zlib") == 0) {
     394                 :          0 :                 comp->type = COMP_ZLIB;
     395         [ +  - ]:       3756 :         } else if (strcmp(name, "none") == 0) {
     396                 :       3756 :                 comp->type = COMP_NONE;
     397                 :            :         } else {
     398                 :          0 :                 fatal("unsupported comp %s", name);
     399                 :            :         }
     400                 :       3756 :         comp->name = name;
     401                 :       3756 : }
     402                 :            : 
     403                 :            : static void
     404                 :       1878 : choose_kex(Kex *k, char *client, char *server)
     405                 :            : {
     406                 :            :         const struct kexalg *kexalg;
     407                 :            : 
     408                 :       1878 :         k->name = match_list(client, server, NULL);
     409         [ -  + ]:       1878 :         if (k->name == NULL)
     410                 :          0 :                 fatal("Unable to negotiate a key exchange method");
     411         [ -  + ]:       1878 :         if ((kexalg = kex_alg_by_name(k->name)) == NULL)
     412                 :          0 :                 fatal("unsupported kex alg %s", k->name);
     413                 :       1878 :         k->kex_type = kexalg->type;
     414                 :       1878 :         k->hash_alg = kexalg->hash_alg;
     415                 :       1878 :         k->ec_nid = kexalg->ec_nid;
     416                 :       1878 : }
     417                 :            : 
     418                 :            : static void
     419                 :       3756 : choose_hostkeyalg(Kex *k, char *client, char *server)
     420                 :            : {
     421                 :       1878 :         char *hostkeyalg = match_list(client, server, NULL);
     422         [ +  + ]:       1878 :         if (hostkeyalg == NULL)
     423                 :          3 :                 fatal("no hostkey alg");
     424                 :       1875 :         k->hostkey_type = key_type_from_name(hostkeyalg);
     425         [ -  + ]:       1875 :         if (k->hostkey_type == KEY_UNSPEC)
     426                 :          0 :                 fatal("bad hostkey alg '%s'", hostkeyalg);
     427                 :       1875 :         free(hostkeyalg);
     428                 :       1875 : }
     429                 :            : 
     430                 :            : static int
     431                 :          0 : proposals_match(char *my[PROPOSAL_MAX], char *peer[PROPOSAL_MAX])
     432                 :            : {
     433                 :            :         static int check[] = {
     434                 :            :                 PROPOSAL_KEX_ALGS, PROPOSAL_SERVER_HOST_KEY_ALGS, -1
     435                 :            :         };
     436                 :            :         int *idx;
     437                 :            :         char *p;
     438                 :            : 
     439         [ #  # ]:          0 :         for (idx = &check[0]; *idx != -1; idx++) {
     440         [ #  # ]:          0 :                 if ((p = strchr(my[*idx], ',')) != NULL)
     441                 :          0 :                         *p = '\0';
     442         [ #  # ]:          0 :                 if ((p = strchr(peer[*idx], ',')) != NULL)
     443                 :          0 :                         *p = '\0';
     444         [ #  # ]:          0 :                 if (strcmp(my[*idx], peer[*idx]) != 0) {
     445                 :          0 :                         debug2("proposal mismatch: my %s peer %s",
     446                 :            :                             my[*idx], peer[*idx]);
     447                 :          0 :                         return (0);
     448                 :            :                 }
     449                 :            :         }
     450                 :          0 :         debug2("proposals match");
     451                 :          0 :         return (1);
     452                 :            : }
     453                 :            : 
     454                 :            : static void
     455                 :       1878 : kex_choose_conf(Kex *kex)
     456                 :            : {
     457                 :            :         Newkeys *newkeys;
     458                 :            :         char **my, **peer;
     459                 :            :         char **cprop, **sprop;
     460                 :            :         int nenc, nmac, ncomp;
     461                 :            :         u_int mode, ctos, need, dh_need, authlen;
     462                 :            :         int first_kex_follows, type;
     463                 :            : 
     464                 :       1878 :         my   = kex_buf2prop(&kex->my, NULL);
     465                 :       1878 :         peer = kex_buf2prop(&kex->peer, &first_kex_follows);
     466                 :            : 
     467         [ +  + ]:       1878 :         if (kex->server) {
     468                 :            :                 cprop=peer;
     469                 :            :                 sprop=my;
     470                 :            :         } else {
     471                 :       1144 :                 cprop=my;
     472                 :       1144 :                 sprop=peer;
     473                 :            :         }
     474                 :            : 
     475                 :            :         /* Check whether server offers roaming */
     476         [ +  + ]:       1878 :         if (!kex->server) {
     477                 :            :                 char *roaming;
     478                 :       1144 :                 roaming = match_list(KEX_RESUME, peer[PROPOSAL_KEX_ALGS], NULL);
     479         [ -  + ]:       1144 :                 if (roaming) {
     480                 :          0 :                         kex->roaming = 1;
     481                 :       1878 :                         free(roaming);
     482                 :            :                 }
     483                 :            :         }
     484                 :            : 
     485                 :            :         /* Algorithm Negotiation */
     486         [ +  + ]:       5634 :         for (mode = 0; mode < MODE_MAX; mode++) {
     487                 :       3756 :                 newkeys = xcalloc(1, sizeof(*newkeys));
     488                 :       3756 :                 kex->newkeys[mode] = newkeys;
     489 [ +  + ][ +  + ]:       3756 :                 ctos = (!kex->server && mode == MODE_OUT) ||
                 [ +  + ]
     490         [ +  + ]:       2612 :                     (kex->server && mode == MODE_IN);
     491         [ +  + ]:       3756 :                 nenc  = ctos ? PROPOSAL_ENC_ALGS_CTOS  : PROPOSAL_ENC_ALGS_STOC;
     492         [ +  + ]:       3756 :                 nmac  = ctos ? PROPOSAL_MAC_ALGS_CTOS  : PROPOSAL_MAC_ALGS_STOC;
     493         [ +  + ]:       3756 :                 ncomp = ctos ? PROPOSAL_COMP_ALGS_CTOS : PROPOSAL_COMP_ALGS_STOC;
     494                 :       3756 :                 choose_enc(&newkeys->enc, cprop[nenc], sprop[nenc]);
     495                 :            :                 /* ignore mac for authenticated encryption */
     496                 :       3756 :                 authlen = cipher_authlen(newkeys->enc.cipher);
     497         [ +  + ]:       3756 :                 if (authlen == 0)
     498                 :       3384 :                         choose_mac(&newkeys->mac, cprop[nmac], sprop[nmac]);
     499                 :       3756 :                 choose_comp(&newkeys->comp, cprop[ncomp], sprop[ncomp]);
     500 [ +  + ][ +  + ]:       3756 :                 debug("kex: %s %s %s %s",
     501                 :            :                     ctos ? "client->server" : "server->client",
     502                 :            :                     newkeys->enc.name,
     503                 :            :                     authlen == 0 ? newkeys->mac.name : "<implicit>",
     504                 :            :                     newkeys->comp.name);
     505                 :            :         }
     506                 :       1878 :         choose_kex(kex, cprop[PROPOSAL_KEX_ALGS], sprop[PROPOSAL_KEX_ALGS]);
     507                 :       1878 :         choose_hostkeyalg(kex, cprop[PROPOSAL_SERVER_HOST_KEY_ALGS],
     508                 :            :             sprop[PROPOSAL_SERVER_HOST_KEY_ALGS]);
     509                 :       1878 :         need = dh_need = 0;
     510         [ +  + ]:       5628 :         for (mode = 0; mode < MODE_MAX; mode++) {
     511                 :       3750 :                 newkeys = kex->newkeys[mode];
     512                 :       3750 :                 need = MAX(need, newkeys->enc.key_len);
     513                 :       3750 :                 need = MAX(need, newkeys->enc.block_size);
     514                 :       3750 :                 need = MAX(need, newkeys->enc.iv_len);
     515                 :       3750 :                 need = MAX(need, newkeys->mac.key_len);
     516         [ +  + ]:       3750 :                 dh_need = MAX(dh_need, cipher_seclen(newkeys->enc.cipher));
     517                 :       3750 :                 dh_need = MAX(dh_need, newkeys->enc.block_size);
     518                 :       3750 :                 dh_need = MAX(dh_need, newkeys->enc.iv_len);
     519                 :       3750 :                 dh_need = MAX(dh_need, newkeys->mac.key_len);
     520                 :            :         }
     521                 :            :         /* XXX need runden? */
     522                 :       1875 :         kex->we_need = need;
     523                 :       1875 :         kex->dh_need = dh_need;
     524                 :            : 
     525                 :            :         /* ignore the next message if the proposals do not match */
     526 [ -  + ][ #  # ]:       1875 :         if (first_kex_follows && !proposals_match(my, peer) &&
                 [ #  # ]
     527                 :          0 :             !(datafellows & SSH_BUG_FIRSTKEX)) {
     528                 :          0 :                 type = packet_read();
     529                 :          0 :                 debug2("skipping next packet (type %u)", type);
     530                 :            :         }
     531                 :            : 
     532                 :       1875 :         kex_prop_free(my);
     533                 :       1875 :         kex_prop_free(peer);
     534                 :       1875 : }
     535                 :            : 
     536                 :            : static u_char *
     537                 :      11232 : derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
     538                 :            :     const u_char *shared_secret, u_int slen)
     539                 :            : {
     540                 :            :         Buffer b;
     541                 :            :         struct ssh_digest_ctx *hashctx;
     542                 :      11232 :         char c = id;
     543                 :            :         u_int have;
     544                 :            :         size_t mdsz;
     545                 :            :         u_char *digest;
     546                 :            : 
     547         [ -  + ]:      11232 :         if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
     548                 :          0 :                 fatal("bad kex md size %zu", mdsz);
     549 [ -  + ][ #  # ]:      11232 :         digest = xmalloc(roundup(need, mdsz));
     550                 :            : 
     551                 :      11232 :         buffer_init(&b);
     552                 :      11232 :         buffer_append(&b, shared_secret, slen);
     553                 :            : 
     554                 :            :         /* K1 = HASH(K || H || "A" || session_id) */
     555         [ -  + ]:      11232 :         if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
     556                 :          0 :                 fatal("%s: ssh_digest_start failed", __func__);
     557   [ +  -  +  - ]:      22464 :         if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
     558         [ +  - ]:      22464 :             ssh_digest_update(hashctx, hash, hashlen) != 0 ||
     559         [ -  + ]:      22464 :             ssh_digest_update(hashctx, &c, 1) != 0 ||
     560                 :      11232 :             ssh_digest_update(hashctx, kex->session_id,
     561                 :      11232 :             kex->session_id_len) != 0)
     562                 :          0 :                 fatal("%s: ssh_digest_update failed", __func__);
     563         [ -  + ]:      11232 :         if (ssh_digest_final(hashctx, digest, mdsz) != 0)
     564                 :          0 :                 fatal("%s: ssh_digest_final failed", __func__);
     565                 :      11232 :         ssh_digest_free(hashctx);
     566                 :            : 
     567                 :            :         /*
     568                 :            :          * expand key:
     569                 :            :          * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
     570                 :            :          * Key = K1 || K2 || ... || Kn
     571                 :            :          */
     572         [ +  + ]:      12384 :         for (have = mdsz; need > have; have += mdsz) {
     573         [ -  + ]:       1152 :                 if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
     574                 :          0 :                         fatal("%s: ssh_digest_start failed", __func__);
     575   [ +  -  +  - ]:       2304 :                 if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
     576         [ -  + ]:       2304 :                     ssh_digest_update(hashctx, hash, hashlen) != 0 ||
     577                 :       1152 :                     ssh_digest_update(hashctx, digest, have) != 0)
     578                 :          0 :                         fatal("%s: ssh_digest_update failed", __func__);
     579         [ -  + ]:       1152 :                 if (ssh_digest_final(hashctx, digest + have, mdsz) != 0)
     580                 :          0 :                         fatal("%s: ssh_digest_final failed", __func__);
     581                 :       1152 :                 ssh_digest_free(hashctx);
     582                 :            :         }
     583                 :      11232 :         buffer_free(&b);
     584                 :            : #ifdef DEBUG_KEX
     585                 :            :         fprintf(stderr, "key '%c'== ", c);
     586                 :            :         dump_digest("key", digest, need);
     587                 :            : #endif
     588                 :      11232 :         return digest;
     589                 :            : }
     590                 :            : 
     591                 :            : Newkeys *current_keys[MODE_MAX];
     592                 :            : 
     593                 :            : #define NKEYS   6
     594                 :            : void
     595                 :       1872 : kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen,
     596                 :            :     const u_char *shared_secret, u_int slen)
     597                 :            : {
     598                 :            :         u_char *keys[NKEYS];
     599                 :            :         u_int i, mode, ctos;
     600                 :            : 
     601         [ +  + ]:      13104 :         for (i = 0; i < NKEYS; i++) {
     602                 :      11232 :                 keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
     603                 :            :                     shared_secret, slen);
     604                 :            :         }
     605                 :            : 
     606                 :       1872 :         debug2("kex_derive_keys");
     607         [ +  + ]:       5616 :         for (mode = 0; mode < MODE_MAX; mode++) {
     608                 :       3744 :                 current_keys[mode] = kex->newkeys[mode];
     609                 :       3744 :                 kex->newkeys[mode] = NULL;
     610 [ +  + ][ +  + ]:       3744 :                 ctos = (!kex->server && mode == MODE_OUT) ||
                 [ +  + ]
     611         [ +  + ]:       2606 :                     (kex->server && mode == MODE_IN);
     612                 :       3744 :                 current_keys[mode]->enc.iv  = keys[ctos ? 0 : 1];
     613         [ +  + ]:       3744 :                 current_keys[mode]->enc.key = keys[ctos ? 2 : 3];
     614         [ +  + ]:       3744 :                 current_keys[mode]->mac.key = keys[ctos ? 4 : 5];
     615                 :            :         }
     616                 :       1872 : }
     617                 :            : 
     618                 :            : void
     619                 :        263 : kex_derive_keys_bn(Kex *kex, u_char *hash, u_int hashlen, const BIGNUM *secret)
     620                 :            : {
     621                 :            :         Buffer shared_secret;
     622                 :            : 
     623                 :        263 :         buffer_init(&shared_secret);
     624                 :        263 :         buffer_put_bignum2(&shared_secret, secret);
     625                 :        526 :         kex_derive_keys(kex, hash, hashlen,
     626                 :        263 :             buffer_ptr(&shared_secret), buffer_len(&shared_secret));
     627                 :        263 :         buffer_free(&shared_secret);
     628                 :        263 : }
     629                 :            : 
     630                 :            : Newkeys *
     631                 :       5028 : kex_get_newkeys(int mode)
     632                 :            : {
     633                 :            :         Newkeys *ret;
     634                 :            : 
     635                 :       5028 :         ret = current_keys[mode];
     636                 :       5028 :         current_keys[mode] = NULL;
     637                 :       5028 :         return ret;
     638                 :            : }
     639                 :            : 
     640                 :            : void
     641                 :        165 : derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
     642                 :            :     u_int8_t cookie[8], u_int8_t id[16])
     643                 :            : {
     644                 :            :         u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
     645                 :            :         int len;
     646                 :            :         struct ssh_digest_ctx *hashctx;
     647                 :            : 
     648         [ -  + ]:        165 :         if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL)
     649                 :          0 :                 fatal("%s: ssh_digest_start", __func__);
     650                 :            : 
     651                 :        165 :         len = BN_num_bytes(host_modulus);
     652         [ -  + ]:        165 :         if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
     653                 :          0 :                 fatal("%s: bad host modulus (len %d)", __func__, len);
     654                 :        165 :         BN_bn2bin(host_modulus, nbuf);
     655         [ -  + ]:        165 :         if (ssh_digest_update(hashctx, nbuf, len) != 0)
     656                 :          0 :                 fatal("%s: ssh_digest_update failed", __func__);
     657                 :            : 
     658                 :        165 :         len = BN_num_bytes(server_modulus);
     659         [ -  + ]:        165 :         if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
     660                 :          0 :                 fatal("%s: bad server modulus (len %d)", __func__, len);
     661                 :        165 :         BN_bn2bin(server_modulus, nbuf);
     662   [ +  -  -  + ]:        330 :         if (ssh_digest_update(hashctx, nbuf, len) != 0 ||
     663                 :        165 :             ssh_digest_update(hashctx, cookie, 8) != 0)
     664                 :          0 :                 fatal("%s: ssh_digest_update failed", __func__);
     665         [ -  + ]:        165 :         if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0)
     666                 :          0 :                 fatal("%s: ssh_digest_final failed", __func__);
     667                 :        165 :         memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
     668                 :            : 
     669                 :        165 :         explicit_bzero(nbuf, sizeof(nbuf));
     670                 :        165 :         explicit_bzero(obuf, sizeof(obuf));
     671                 :        165 : }
     672                 :            : 
     673                 :            : #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
     674                 :            : void
     675                 :            : dump_digest(char *msg, u_char *digest, int len)
     676                 :            : {
     677                 :            :         int i;
     678                 :            : 
     679                 :            :         fprintf(stderr, "%s\n", msg);
     680                 :            :         for (i = 0; i < len; i++) {
     681                 :            :                 fprintf(stderr, "%02x", digest[i]);
     682                 :            :                 if (i%32 == 31)
     683                 :            :                         fprintf(stderr, "\n");
     684                 :            :                 else if (i%8 == 7)
     685                 :            :                         fprintf(stderr, " ");
     686                 :            :         }
     687                 :            :         fprintf(stderr, "\n");
     688                 :            : }
     689                 :            : #endif

Generated by: LCOV version 1.9