Bugzilla – Attachment 907 Details for
Bug 1023
Add support for dhgex-sha256
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to add dhgex-sha512 to PuTTY
putty-dhgexsha512.diff (text/plain), 14.14 KB, created by
Damien Miller
on 2005-05-11 13:33:35 AEST
(
hide
)
Description:
Patch to add dhgex-sha512 to PuTTY
Filename:
MIME Type:
Creator:
Damien Miller
Created:
2005-05-11 13:33:35 AEST
Size:
14.14 KB
patch
obsolete
>Index: sshdh.c >=================================================================== >--- sshdh.c (revision 5765) >+++ sshdh.c (working copy) >@@ -61,6 +61,11 @@ > NULL, NULL, 0, 0 > }; > >+const struct ssh_kex ssh_diffiehellman_gex_sha512 = { >+ "diffie-hellman-group-exchange-sha512", NULL, >+ NULL, NULL, 0, 0 >+}; >+ > /* > * Variables. > */ >Index: settings.c >=================================================================== >--- settings.c (revision 5765) >+++ settings.c (working copy) >@@ -23,6 +23,7 @@ > }; > > static const struct keyval kexnames[] = { >+ { "dh-gex-sha512", KEX_DHGEX_SHA512 }, > { "dh-gex-sha1", KEX_DHGEX }, > { "dh-group14-sha1", KEX_DHGROUP14 }, > { "dh-group1-sha1", KEX_DHGROUP1 }, >Index: ssh.c >=================================================================== >--- ssh.c (revision 5765) >+++ ssh.c (working copy) >@@ -14,6 +14,10 @@ > #define TRUE 1 > #endif > >+#ifndef MIN >+# define MIN(a,b) (((a)<(b))?(a):(b)) >+#endif >+ > #define SSH1_MSG_DISCONNECT 1 /* 0x1 */ > #define SSH1_SMSG_PUBLIC_KEY 2 /* 0x2 */ > #define SSH1_CMSG_SESSION_KEY 3 /* 0x3 */ >@@ -680,6 +684,7 @@ > /* the above field _must_ be first in the structure */ > > SHA_State exhash, exhashbase; >+ SHA512_State exhash512, exhashbase512; > > Socket s; > >@@ -704,7 +709,9 @@ > void *cs_comp_ctx, *sc_comp_ctx; > const struct ssh_kex *kex; > const struct ssh_signkey *hostkey; >- unsigned char v2_session_id[20]; >+ unsigned char v2_session_id[64]; >+ int v2_session_id_len; >+ > void *kex_ctx; > > char *savedhost; >@@ -1558,7 +1565,7 @@ > > /* > * Utility routines for putting an SSH-protocol `string' and >- * `uint32' into a SHA state. >+ * `uint32' into a SHA/SHA512 state. > */ > static void sha_string(SHA_State * s, void *str, int len) > { >@@ -1575,6 +1582,21 @@ > SHA_Bytes(s, intblk, 4); > } > >+static void sha512_string(SHA512_State * s, void *str, int len) >+{ >+ unsigned char lenblk[4]; >+ PUT_32BIT(lenblk, len); >+ SHA512_Bytes(s, lenblk, 4); >+ SHA512_Bytes(s, str, len); >+} >+ >+static void sha512_uint32(SHA512_State * s, unsigned i) >+{ >+ unsigned char intblk[4]; >+ PUT_32BIT(intblk, i); >+ SHA512_Bytes(s, intblk, 4); >+} >+ > /* > * Packet construction functions. Mostly shared between SSH-1 and SSH-2. > */ >@@ -1979,6 +2001,20 @@ > sfree(p); > } > >+static void sha512_mpint(SHA512_State * s, Bignum b) >+{ >+ unsigned char lenbuf[4]; >+ int len; >+ len = (bignum_bitcount(b) + 8) / 8; >+ PUT_32BIT(lenbuf, len); >+ SHA512_Bytes(s, lenbuf, 4); >+ while (len-- > 0) { >+ lenbuf[0] = bignum_byte(b, len); >+ SHA512_Bytes(s, lenbuf, 1); >+ } >+ memset(lenbuf, 0, sizeof(lenbuf)); >+} >+ > /* > * Packet decode functions for both SSH-1 and SSH-2. > */ >@@ -2391,6 +2427,11 @@ > strcspn(verstring, "\015\012")); > sha_string(&ssh->exhashbase, s->vstring, > strcspn(s->vstring, "\015\012")); >+ SHA512_Init(&ssh->exhashbase512); >+ sha512_string(&ssh->exhashbase512, verstring, >+ strcspn(verstring, "\015\012")); >+ sha512_string(&ssh->exhashbase512, s->vstring, >+ strcspn(s->vstring, "\015\012")); > > /* > * Initialise SSH-2 protocol. >@@ -4918,26 +4959,56 @@ > /* > * SSH-2 key creation method. > */ >-static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, >- unsigned char *sessid, char chr, >- unsigned char *keyspace) >+static void ssh2_mkkey(Ssh ssh, Bignum K, unsigned char *H, int H_len, >+ unsigned char *sessid, int sessid_len, char chr, >+ unsigned char *keyspace, int keyspace_len) > { > SHA_State s; >- /* First 20 bytes. */ >- SHA_Init(&s); >- if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) >- sha_mpint(&s, K); >- SHA_Bytes(&s, H, 20); >- SHA_Bytes(&s, &chr, 1); >- SHA_Bytes(&s, sessid, 20); >- SHA_Final(&s, keyspace); >- /* Next 20 bytes. */ >- SHA_Init(&s); >- if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) >- sha_mpint(&s, K); >- SHA_Bytes(&s, H, 20); >- SHA_Bytes(&s, keyspace, 20); >- SHA_Final(&s, keyspace + 20); >+ SHA512_State s512; >+ int i; >+ unsigned char outbuf[64]; >+ >+ if (ssh->kex == &ssh_diffiehellman_gex_sha512) { >+ /* First 64 bytes. */ >+ SHA512_Init(&s512); >+ if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) >+ sha512_mpint(&s512, K); >+ SHA512_Bytes(&s512, H, H_len); >+ SHA512_Bytes(&s512, &chr, 1); >+ SHA512_Bytes(&s512, sessid, sessid_len); >+ SHA512_Final(&s512, keyspace); >+ /* Expand to fill keyspace */ >+ for (i = 64; i < keyspace_len; i += 64) { >+ SHA512_Init(&s512); >+ if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) >+ sha512_mpint(&s512, K); >+ SHA512_Bytes(&s512, H, H_len); >+ SHA512_Bytes(&s512, keyspace, i); >+ SHA512_Final(&s512, outbuf); >+ memcpy(keyspace + i, outbuf, MIN(keyspace_len - i, 64)); >+ memset(outbuf, 0, sizeof(outbuf)); >+ } >+ } else { >+ /* First 20 bytes. */ >+ SHA_Init(&s); >+ if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) >+ sha_mpint(&s, K); >+ SHA_Bytes(&s, H, H_len); >+ SHA_Bytes(&s, &chr, 1); >+ SHA_Bytes(&s, sessid, sessid_len); >+ SHA_Final(&s, keyspace); >+ /* Expand to fill keyspace */ >+ for (i = 20; i < keyspace_len; i += 20) { >+ SHA_Init(&s); >+ if (!(ssh->remote_bugs & BUG_SSH2_DERIVEKEY)) >+ sha_mpint(&s, K); >+ SHA_Bytes(&s, H, sessid_len); >+ SHA_Bytes(&s, keyspace, i); >+ SHA_Final(&s, outbuf); >+ memcpy(keyspace + i, outbuf, MIN(keyspace_len - i, 20)); >+ memset(outbuf, 0, sizeof(outbuf)); >+ } >+ } > } > > /* >@@ -4962,7 +5033,8 @@ > char *hostkeydata, *sigdata, *keystr, *fingerprint; > int hostkeylen, siglen; > void *hkey; /* actual host key */ >- unsigned char exchange_hash[20]; >+ unsigned char exchange_hash[64]; >+ int exchange_hash_len; > int n_preferred_kex; > const struct ssh_kex *preferred_kex[KEX_MAX]; > int n_preferred_ciphers; >@@ -5003,6 +5075,10 @@ > s->n_preferred_kex = 0; > for (i = 0; i < KEX_MAX; i++) { > switch (ssh->cfg.ssh_kexlist[i]) { >+ case KEX_DHGEX_SHA512: >+ s->preferred_kex[s->n_preferred_kex++] = >+ &ssh_diffiehellman_gex_sha512; >+ break; > case KEX_DHGEX: > s->preferred_kex[s->n_preferred_kex++] = > &ssh_diffiehellman_gex; >@@ -5174,15 +5250,18 @@ > } > > ssh->exhash = ssh->exhashbase; >+ ssh->exhash512 = ssh->exhashbase512; > sha_string(&ssh->exhash, s->pktout->data + 5, s->pktout->length - 5); >+ sha512_string(&ssh->exhash512, s->pktout->data + 5, s->pktout->length - 5); > > ssh2_pkt_send_noqueue(ssh, s->pktout); > > if (!pktin) > crWaitUntil(pktin); >- if (pktin->length > 5) >+ if (pktin->length > 5) { > sha_string(&ssh->exhash, pktin->data + 5, pktin->length - 5); >- >+ sha512_string(&ssh->exhash512, pktin->data + 5, pktin->length - 5); >+ } > /* > * Now examine the other side's KEXINIT to see what we're up > * to. >@@ -5411,10 +5490,6 @@ > scbits = s->sccipher_tobe->keylen; > s->nbits = (csbits > scbits ? csbits : scbits); > } >- /* The keys only have 160-bit entropy, since they're based on >- * a SHA-1 hash. So cap the key size at 160 bits. */ >- if (s->nbits > 160) >- s->nbits = 160; > > /* > * If we're doing Diffie-Hellman group exchange, start by >@@ -5486,29 +5561,44 @@ > * involve user interaction. */ > set_busy_status(ssh->frontend, BUSY_NOT); > >- sha_string(&ssh->exhash, s->hostkeydata, s->hostkeylen); >- if (ssh->kex == &ssh_diffiehellman_gex) { >- sha_uint32(&ssh->exhash, s->pbits); >- sha_mpint(&ssh->exhash, s->p); >- sha_mpint(&ssh->exhash, s->g); >+ >+ if (ssh->kex == &ssh_diffiehellman_gex_sha512) { >+ sha512_string(&ssh->exhash512, s->hostkeydata, s->hostkeylen); >+ sha512_uint32(&ssh->exhash512, s->pbits); >+ sha512_mpint(&ssh->exhash512, s->p); >+ sha512_mpint(&ssh->exhash512, s->g); >+ sha512_mpint(&ssh->exhash512, s->e); >+ sha512_mpint(&ssh->exhash512, s->f); >+ sha512_mpint(&ssh->exhash512, s->K); >+ SHA512_Final(&ssh->exhash512, s->exchange_hash); >+ s->exchange_hash_len = 64; >+ } else { >+ sha_string(&ssh->exhash, s->hostkeydata, s->hostkeylen); >+ if (ssh->kex == &ssh_diffiehellman_gex) { >+ sha_uint32(&ssh->exhash, s->pbits); >+ sha_mpint(&ssh->exhash, s->p); >+ sha_mpint(&ssh->exhash, s->g); >+ } >+ sha_mpint(&ssh->exhash, s->e); >+ sha_mpint(&ssh->exhash, s->f); >+ sha_mpint(&ssh->exhash, s->K); >+ SHA_Final(&ssh->exhash, s->exchange_hash); >+ s->exchange_hash_len = 20; > } >- sha_mpint(&ssh->exhash, s->e); >- sha_mpint(&ssh->exhash, s->f); >- sha_mpint(&ssh->exhash, s->K); >- SHA_Final(&ssh->exhash, s->exchange_hash); > > dh_cleanup(ssh->kex_ctx); > ssh->kex_ctx = NULL; > > #if 0 > debug(("Exchange hash is:\n")); >- dmemdump(s->exchange_hash, 20); >+ dmemdump(s->exchange_hash, s->exchange_hash_len); > #endif > > s->hkey = ssh->hostkey->newkey(s->hostkeydata, s->hostkeylen); > if (!s->hkey || > !ssh->hostkey->verifysig(s->hkey, s->sigdata, s->siglen, >- (char *)s->exchange_hash, 20)) { >+ (char *)s->exchange_hash, >+ s->exchange_hash_len)) { > bombout(("Server's host key did not match the signature supplied")); > crStop(0); > } >@@ -5557,7 +5647,8 @@ > */ > if (!s->got_session_id) { > memcpy(ssh->v2_session_id, s->exchange_hash, >- sizeof(s->exchange_hash)); >+ s->exchange_hash_len); >+ ssh->v2_session_id_len = s->exchange_hash_len; > s->got_session_id = TRUE; > } > >@@ -5592,12 +5683,18 @@ > * hash from the _first_ key exchange. > */ > { >- unsigned char keyspace[40]; >- ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'C',keyspace); >+ unsigned char keyspace[128]; >+ ssh2_mkkey(ssh,s->K,s->exchange_hash,s->exchange_hash_len, >+ ssh->v2_session_id,ssh->v2_session_id_len,'C', >+ keyspace,sizeof(keyspace)); > ssh->cscipher->setkey(ssh->cs_cipher_ctx, keyspace); >- ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'A',keyspace); >+ ssh2_mkkey(ssh,s->K,s->exchange_hash,s->exchange_hash_len, >+ ssh->v2_session_id,ssh->v2_session_id_len,'A', >+ keyspace,sizeof(keyspace)); > ssh->cscipher->setiv(ssh->cs_cipher_ctx, keyspace); >- ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'E',keyspace); >+ ssh2_mkkey(ssh,s->K,s->exchange_hash,s->exchange_hash_len, >+ ssh->v2_session_id,ssh->v2_session_id_len,'E', >+ keyspace,sizeof(keyspace)); > ssh->csmac->setkey(ssh->cs_mac_ctx, keyspace); > } > >@@ -5650,12 +5747,18 @@ > * hash from the _first_ key exchange. > */ > { >- unsigned char keyspace[40]; >- ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'D',keyspace); >+ unsigned char keyspace[128]; >+ ssh2_mkkey(ssh,s->K,s->exchange_hash,s->exchange_hash_len, >+ ssh->v2_session_id,ssh->v2_session_id_len,'D', >+ keyspace,sizeof(keyspace)); > ssh->sccipher->setkey(ssh->sc_cipher_ctx, keyspace); >- ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'B',keyspace); >+ ssh2_mkkey(ssh,s->K,s->exchange_hash,s->exchange_hash_len, >+ ssh->v2_session_id,ssh->v2_session_id_len,'B', >+ keyspace,sizeof(keyspace)); > ssh->sccipher->setiv(ssh->sc_cipher_ctx, keyspace); >- ssh2_mkkey(ssh,s->K,s->exchange_hash,ssh->v2_session_id,'F',keyspace); >+ ssh2_mkkey(ssh,s->K,s->exchange_hash,s->exchange_hash_len, >+ ssh->v2_session_id,ssh->v2_session_id_len,'F', >+ keyspace,sizeof(keyspace)); > ssh->scmac->setkey(ssh->sc_mac_ctx, keyspace); > } > logeventf(ssh, "Initialised %.200s server->client encryption", >@@ -5671,7 +5774,8 @@ > */ > freebn(s->f); > freebn(s->K); >- if (ssh->kex == &ssh_diffiehellman_gex) { >+ if (ssh->kex == &ssh_diffiehellman_gex || >+ ssh->kex == &ssh_diffiehellman_gex_sha512) { > freebn(s->g); > freebn(s->p); > } >@@ -6833,7 +6937,8 @@ > ssh2_pkt_addstring_start(s->pktout); > ssh2_pkt_addstring_data(s->pktout, s->pkblob, s->pklen); > >- s->siglen = s->pktout->length - 5 + 4 + 20; >+ s->siglen = s->pktout->length - 5 + 4 + >+ ssh->v2_session_id_len; > if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID) > s->siglen -= 4; > s->len = 1; /* message type */ >@@ -6852,11 +6957,12 @@ > s->q += 4; > /* Now the data to be signed... */ > if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) { >- PUT_32BIT(s->q, 20); >+ PUT_32BIT(s->q, ssh->v2_session_id_len); > s->q += 4; > } >- memcpy(s->q, ssh->v2_session_id, 20); >- s->q += 20; >+ memcpy(s->q, ssh->v2_session_id, >+ ssh->v2_session_id_len); >+ s->q += ssh->v2_session_id_len; > memcpy(s->q, s->pktout->data + 5, > s->pktout->length - 5); > s->q += s->pktout->length - 5; >@@ -7160,16 +7266,19 @@ > * followed by everything so far placed in the > * outgoing packet. > */ >- sigdata_len = s->pktout->length - 5 + 4 + 20; >+ sigdata_len = s->pktout->length - 5 + 4 + >+ ssh->v2_session_id_len; > if (ssh->remote_bugs & BUG_SSH2_PK_SESSIONID) > sigdata_len -= 4; > sigdata = snewn(sigdata_len, unsigned char); > p = 0; > if (!(ssh->remote_bugs & BUG_SSH2_PK_SESSIONID)) { >- PUT_32BIT(sigdata+p, 20); >+ PUT_32BIT(sigdata+p, ssh->v2_session_id_len); > p += 4; > } >- memcpy(sigdata+p, ssh->v2_session_id, 20); p += 20; >+ memcpy(sigdata+p, ssh->v2_session_id, >+ ssh->v2_session_id_len); >+ p += ssh->v2_session_id_len; > memcpy(sigdata+p, s->pktout->data + 5, > s->pktout->length - 5); > p += s->pktout->length - 5; >Index: ssh.h >=================================================================== >--- ssh.h (revision 5765) >+++ ssh.h (working copy) >@@ -239,6 +239,7 @@ > extern const struct ssh_kex ssh_diffiehellman_group1; > extern const struct ssh_kex ssh_diffiehellman_group14; > extern const struct ssh_kex ssh_diffiehellman_gex; >+extern const struct ssh_kex ssh_diffiehellman_gex_sha512; > extern const struct ssh_signkey ssh_dss; > extern const struct ssh_signkey ssh_rsa; > extern const struct ssh_mac ssh_md5; >Index: putty.h >=================================================================== >--- putty.h (revision 5765) >+++ putty.h (working copy) >@@ -249,6 +249,7 @@ > KEX_DHGROUP1, > KEX_DHGROUP14, > KEX_DHGEX, >+ KEX_DHGEX_SHA512, > KEX_MAX > }; >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 1023
:
886
|
906
|
907
|
939
|
940
|
942
|
1019