]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Provide SHA-384 and SHA-512 as hashes usable in SSH KEX.
authorChris Staite <chris@yourdreamnet.co.uk>
Sat, 1 Nov 2014 08:59:25 +0000 (08:59 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 2 Nov 2014 18:16:54 +0000 (18:16 +0000)
SHA-384 was previously not implemented at all, but is a trivial
adjustment to SHA-512 (different starting constants, and truncate the
output hash). Both are now exposed as 'ssh_hash' structures so that
key exchange methods can ask for them.

ssh.h
sshsh512.c

diff --git a/ssh.h b/ssh.h
index dc34052d29e74d22c05cd7c1f3b052e045687db8..a73e93916910cbf4487ffff05ef3469209b3c1b0 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -204,10 +204,15 @@ typedef struct {
     int blkused;
     uint32 len[4];
 } SHA512_State;
+#define SHA384_State SHA512_State
 void SHA512_Init(SHA512_State * s);
 void SHA512_Bytes(SHA512_State * s, const void *p, int len);
 void SHA512_Final(SHA512_State * s, unsigned char *output);
 void SHA512_Simple(const void *p, int len, unsigned char *output);
+void SHA384_Init(SHA384_State * s);
+#define SHA384_Bytes(s, p, len) SHA512_Bytes(s, p, len)
+void SHA384_Final(SHA384_State * s, unsigned char *output);
+void SHA384_Simple(const void *p, int len, unsigned char *output);
 
 struct ssh_cipher {
     void *(*make_context)(void);
@@ -334,6 +339,8 @@ extern const struct ssh2_ciphers ssh2_blowfish;
 extern const struct ssh2_ciphers ssh2_arcfour;
 extern const struct ssh_hash ssh_sha1;
 extern const struct ssh_hash ssh_sha256;
+extern const struct ssh_hash ssh_sha384;
+extern const struct ssh_hash ssh_sha512;
 extern const struct ssh_kexes ssh_diffiehellman_group1;
 extern const struct ssh_kexes ssh_diffiehellman_group14;
 extern const struct ssh_kexes ssh_diffiehellman_gex;
index 8d0b1ae3629791d3e52dbf2bb5e220f59a0c2157..cd2b296e63bdf1efed34b2423257f6aa9ef704ed 100644 (file)
@@ -2,6 +2,8 @@
  * SHA-512 algorithm as described at
  * 
  *   http://csrc.nist.gov/cryptval/shs.html
+ *
+ * Modifications made for SHA-384 also
  */
 
 #include "ssh.h"
@@ -61,6 +63,22 @@ static void SHA512_Core_Init(SHA512_State *s) {
        s->h[i] = iv[i];
 }
 
+static void SHA384_Core_Init(SHA512_State *s) {
+    static const uint64 iv[] = {
+        INIT(0xcbbb9d5d, 0xc1059ed8),
+        INIT(0x629a292a, 0x367cd507),
+        INIT(0x9159015a, 0x3070dd17),
+        INIT(0x152fecd8, 0xf70e5939),
+        INIT(0x67332667, 0xffc00b31),
+        INIT(0x8eb44a87, 0x68581511),
+        INIT(0xdb0c2e0d, 0x64f98fa7),
+        INIT(0x47b5481d, 0xbefa4fa4),
+    };
+    int i;
+    for (i = 0; i < 8; i++)
+        s->h[i] = iv[i];
+}
+
 static void SHA512_Block(SHA512_State *s, uint64 *block) {
     uint64 w[80];
     uint64 a,b,c,d,e,f,g,h;
@@ -175,6 +193,14 @@ void SHA512_Init(SHA512_State *s) {
        s->len[i] = 0;
 }
 
+void SHA384_Init(SHA512_State *s) {
+    int i;
+    SHA384_Core_Init(s);
+    s->blkused = 0;
+    for (i = 0; i < 4; i++)
+        s->len[i] = 0;
+}
+
 void SHA512_Bytes(SHA512_State *s, const void *p, int len) {
     unsigned char *q = (unsigned char *)p;
     uint64 wordblock[16];
@@ -268,6 +294,12 @@ void SHA512_Final(SHA512_State *s, unsigned char *digest) {
     }
 }
 
+void SHA384_Final(SHA512_State *s, unsigned char *digest) {
+    unsigned char biggerDigest[512 / 8];
+    SHA512_Final(s, biggerDigest);
+    memcpy(digest, biggerDigest, 384 / 8);
+}
+
 void SHA512_Simple(const void *p, int len, unsigned char *output) {
     SHA512_State s;
 
@@ -276,6 +308,67 @@ void SHA512_Simple(const void *p, int len, unsigned char *output) {
     SHA512_Final(&s, output);
 }
 
+void SHA384_Simple(const void *p, int len, unsigned char *output) {
+    SHA512_State s;
+
+    SHA384_Init(&s);
+    SHA512_Bytes(&s, p, len);
+    SHA384_Final(&s, output);
+}
+
+/*
+ * Thin abstraction for things where hashes are pluggable.
+ */
+
+static void *sha512_init(void)
+{
+    SHA512_State *s;
+
+    s = snew(SHA512_State);
+    SHA512_Init(s);
+    return s;
+}
+
+static void sha512_bytes(void *handle, void *p, int len)
+{
+    SHA512_State *s = handle;
+
+    SHA512_Bytes(s, p, len);
+}
+
+static void sha512_final(void *handle, unsigned char *output)
+{
+    SHA512_State *s = handle;
+
+    SHA512_Final(s, output);
+    sfree(s);
+}
+
+const struct ssh_hash ssh_sha512 = {
+    sha512_init, sha512_bytes, sha512_final, 64, "SHA-512"
+};
+
+static void *sha384_init(void)
+{
+    SHA512_State *s;
+
+    s = snew(SHA512_State);
+    SHA384_Init(s);
+    return s;
+}
+
+static void sha384_final(void *handle, unsigned char *output)
+{
+    SHA512_State *s = handle;
+
+    SHA384_Final(s, output);
+    sfree(s);
+}
+
+const struct ssh_hash ssh_sha384 = {
+    sha384_init, sha512_bytes, sha384_final, 48, "SHA-384"
+};
+
 #ifdef TEST
 
 #include <stdio.h>