[BACK]Return to kex.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/kex.c between version 1.93 and 1.94

version 1.93, 2013/11/07 11:58:27 version 1.94, 2014/01/09 23:20:00
Line 46 
Line 46 
 #include "dispatch.h"  #include "dispatch.h"
 #include "monitor.h"  #include "monitor.h"
 #include "roaming.h"  #include "roaming.h"
   #include "digest.h"
   
 /* prototype */  /* prototype */
 static void kex_kexinit_finish(Kex *);  static void kex_kexinit_finish(Kex *);
Line 55 
Line 56 
         char *name;          char *name;
         int type;          int type;
         int ec_nid;          int ec_nid;
         const EVP_MD *(*mdfunc)(void);          int hash_alg;
 };  };
 static const struct kexalg kexalgs[] = {  static const struct kexalg kexalgs[] = {
         { KEX_DH1, KEX_DH_GRP1_SHA1, 0, EVP_sha1 },          { KEX_DH1, KEX_DH_GRP1_SHA1, 0, SSH_DIGEST_SHA1 },
         { KEX_DH14, KEX_DH_GRP14_SHA1, 0, EVP_sha1 },          { KEX_DH14, KEX_DH_GRP14_SHA1, 0, SSH_DIGEST_SHA1 },
         { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, EVP_sha1 },          { KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
         { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, EVP_sha256 },          { KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
         { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2, NID_X9_62_prime256v1, EVP_sha256 },          { KEX_ECDH_SHA2_NISTP256, KEX_ECDH_SHA2,
         { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1, EVP_sha384 },              NID_X9_62_prime256v1, SSH_DIGEST_SHA256 },
         { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1, EVP_sha512 },          { KEX_ECDH_SHA2_NISTP384, KEX_ECDH_SHA2, NID_secp384r1,
         { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, EVP_sha256 },              SSH_DIGEST_SHA384 },
         { NULL, -1, -1, NULL},          { KEX_ECDH_SHA2_NISTP521, KEX_ECDH_SHA2, NID_secp521r1,
               SSH_DIGEST_SHA512 },
           { KEX_CURVE25519_SHA256, KEX_C25519_SHA256, 0, SSH_DIGEST_SHA256 },
           { NULL, -1, -1, -1},
 };  };
   
 char *  char *
Line 387 
Line 391 
         if ((kexalg = kex_alg_by_name(k->name)) == NULL)          if ((kexalg = kex_alg_by_name(k->name)) == NULL)
                 fatal("unsupported kex alg %s", k->name);                  fatal("unsupported kex alg %s", k->name);
         k->kex_type = kexalg->type;          k->kex_type = kexalg->type;
         k->evp_md = kexalg->mdfunc();          k->hash_alg = kexalg->hash_alg;
         k->ec_nid = kexalg->ec_nid;          k->ec_nid = kexalg->ec_nid;
 }  }
   
Line 513 
Line 517 
     BIGNUM *shared_secret)      BIGNUM *shared_secret)
 {  {
         Buffer b;          Buffer b;
         EVP_MD_CTX md;          struct ssh_digest_ctx *hashctx;
         char c = id;          char c = id;
         u_int have;          u_int have;
         int mdsz;          size_t mdsz;
         u_char *digest;          u_char *digest;
   
         if ((mdsz = EVP_MD_size(kex->evp_md)) <= 0)          if ((mdsz = ssh_digest_bytes(kex->hash_alg)) == 0)
                 fatal("bad kex md size %d", mdsz);                  fatal("bad kex md size %zu", mdsz);
         digest = xmalloc(roundup(need, mdsz));          digest = xmalloc(roundup(need, mdsz));
   
         buffer_init(&b);          buffer_init(&b);
         buffer_put_bignum2(&b, shared_secret);          buffer_put_bignum2(&b, shared_secret);
   
         /* K1 = HASH(K || H || "A" || session_id) */          /* K1 = HASH(K || H || "A" || session_id) */
         EVP_DigestInit(&md, kex->evp_md);          if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
         if (!(datafellows & SSH_BUG_DERIVEKEY))                  fatal("%s: ssh_digest_start failed", __func__);
                 EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));          if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
         EVP_DigestUpdate(&md, hash, hashlen);              ssh_digest_update(hashctx, hash, hashlen) != 0 ||
         EVP_DigestUpdate(&md, &c, 1);              ssh_digest_update(hashctx, &c, 1) != 0 ||
         EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);              ssh_digest_update(hashctx, kex->session_id,
         EVP_DigestFinal(&md, digest, NULL);              kex->session_id_len) != 0)
                   fatal("%s: ssh_digest_update failed", __func__);
           if (ssh_digest_final(hashctx, digest, mdsz) != 0)
                   fatal("%s: ssh_digest_final failed", __func__);
           ssh_digest_free(hashctx);
   
         /*          /*
          * expand key:           * expand key:
Line 541 
Line 549 
          * Key = K1 || K2 || ... || Kn           * Key = K1 || K2 || ... || Kn
          */           */
         for (have = mdsz; need > have; have += mdsz) {          for (have = mdsz; need > have; have += mdsz) {
                 EVP_DigestInit(&md, kex->evp_md);                  if ((hashctx = ssh_digest_start(kex->hash_alg)) == NULL)
                 if (!(datafellows & SSH_BUG_DERIVEKEY))                          fatal("%s: ssh_digest_start failed", __func__);
                         EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));                  if (ssh_digest_update_buffer(hashctx, &b) != 0 ||
                 EVP_DigestUpdate(&md, hash, hashlen);                      ssh_digest_update(hashctx, hash, hashlen) != 0 ||
                 EVP_DigestUpdate(&md, digest, have);                      ssh_digest_update(hashctx, digest, have) != 0)
                 EVP_DigestFinal(&md, digest + have, NULL);                          fatal("%s: ssh_digest_update failed", __func__);
                   if (ssh_digest_final(hashctx, digest + have, mdsz) != 0)
                           fatal("%s: ssh_digest_final failed", __func__);
                   ssh_digest_free(hashctx);
         }          }
         buffer_free(&b);          buffer_free(&b);
 #ifdef DEBUG_KEX  #ifdef DEBUG_KEX
Line 596 
Line 607 
 derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,  derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
     u_int8_t cookie[8], u_int8_t id[16])      u_int8_t cookie[8], u_int8_t id[16])
 {  {
         const EVP_MD *evp_md = EVP_md5();          u_int8_t nbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
         EVP_MD_CTX md;  
         u_int8_t nbuf[2048], obuf[EVP_MAX_MD_SIZE];  
         int len;          int len;
           struct ssh_digest_ctx *hashctx;
   
         EVP_DigestInit(&md, evp_md);          if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL)
                   fatal("%s: ssh_digest_start", __func__);
   
         len = BN_num_bytes(host_modulus);          len = BN_num_bytes(host_modulus);
         if (len < (512 / 8) || (u_int)len > sizeof(nbuf))          if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
                 fatal("%s: bad host modulus (len %d)", __func__, len);                  fatal("%s: bad host modulus (len %d)", __func__, len);
         BN_bn2bin(host_modulus, nbuf);          BN_bn2bin(host_modulus, nbuf);
         EVP_DigestUpdate(&md, nbuf, len);          if (ssh_digest_update(hashctx, nbuf, len) != 0)
                   fatal("%s: ssh_digest_update failed", __func__);
   
         len = BN_num_bytes(server_modulus);          len = BN_num_bytes(server_modulus);
         if (len < (512 / 8) || (u_int)len > sizeof(nbuf))          if (len < (512 / 8) || (u_int)len > sizeof(nbuf))
                 fatal("%s: bad server modulus (len %d)", __func__, len);                  fatal("%s: bad server modulus (len %d)", __func__, len);
         BN_bn2bin(server_modulus, nbuf);          BN_bn2bin(server_modulus, nbuf);
         EVP_DigestUpdate(&md, nbuf, len);          if (ssh_digest_update(hashctx, nbuf, len) != 0 ||
               ssh_digest_update(hashctx, cookie, 8) != 0)
                   fatal("%s: ssh_digest_update failed", __func__);
           if (ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0)
                   fatal("%s: ssh_digest_final failed", __func__);
           memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
   
         EVP_DigestUpdate(&md, cookie, 8);  
   
         EVP_DigestFinal(&md, obuf, NULL);  
         memcpy(id, obuf, 16);  
   
         memset(nbuf, 0, sizeof(nbuf));          memset(nbuf, 0, sizeof(nbuf));
         memset(obuf, 0, sizeof(obuf));          memset(obuf, 0, sizeof(obuf));
         memset(&md, 0, sizeof(md));  
 }  }
   
 #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)  #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)

Legend:
Removed from v.1.93  
changed lines
  Added in v.1.94