summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-11-04 16:31:06 +0100
committerLudovic Courtès <ludo@gnu.org>2015-12-02 19:37:59 +0200
commit29d3242e5c428d3b0e8dc9db1c81cd4053e5271c (patch)
tree9265c393bba91ada32e17f33b0725f5aee5cddd8
parent79aa1a83054af1600ba235ddf305337b5df78271 (diff)
daemon: Support SHA-512 hashes.
Fixes #679. Note: on x86_64, SHA-512 is considerably faster than SHA-256 (198 MB/s versus 131 MB/s). Co-authored-by: Ludovic Courtès <ludo@gnu.org>
-rw-r--r--daemon.am3
-rw-r--r--nix/libutil/hash.cc8
-rw-r--r--nix/libutil/hash.hh5
-rw-r--r--nix/libutil/sha512.h35
4 files changed, 48 insertions, 3 deletions
diff --git a/daemon.am b/daemon.am
index f75eef2e98b..ca272a9cb68 100644
--- a/daemon.am
+++ b/daemon.am
@@ -69,7 +69,8 @@ libutil_headers = \
69 nix/libutil/gcrypt-hash.hh \ 69 nix/libutil/gcrypt-hash.hh \
70 nix/libutil/md5.h \ 70 nix/libutil/md5.h \
71 nix/libutil/sha1.h \ 71 nix/libutil/sha1.h \
72 nix/libutil/sha256.h 72 nix/libutil/sha256.h \
73 nix/libutil/sha512.h
73 74
74libutil_a_CPPFLAGS = \ 75libutil_a_CPPFLAGS = \
75 -I$(top_builddir)/nix \ 76 -I$(top_builddir)/nix \
diff --git a/nix/libutil/hash.cc b/nix/libutil/hash.cc
index 2da00a53de0..ea69aa64f91 100644
--- a/nix/libutil/hash.cc
+++ b/nix/libutil/hash.cc
@@ -11,6 +11,7 @@ extern "C" {
11#include "md5.h" 11#include "md5.h"
12#include "sha1.h" 12#include "sha1.h"
13#include "sha256.h" 13#include "sha256.h"
14#include "sha512.h"
14} 15}
15#endif 16#endif
16 17
@@ -40,6 +41,7 @@ Hash::Hash(HashType type)
40 if (type == htMD5) hashSize = md5HashSize; 41 if (type == htMD5) hashSize = md5HashSize;
41 else if (type == htSHA1) hashSize = sha1HashSize; 42 else if (type == htSHA1) hashSize = sha1HashSize;
42 else if (type == htSHA256) hashSize = sha256HashSize; 43 else if (type == htSHA256) hashSize = sha256HashSize;
44 else if (type == htSHA512) hashSize = sha512HashSize;
43 else throw Error("unknown hash type"); 45 else throw Error("unknown hash type");
44 assert(hashSize <= maxHashSize); 46 assert(hashSize <= maxHashSize);
45 memset(hash, 0, maxHashSize); 47 memset(hash, 0, maxHashSize);
@@ -199,6 +201,7 @@ struct Ctx
199 MD5_CTX md5; 201 MD5_CTX md5;
200 SHA_CTX sha1; 202 SHA_CTX sha1;
201 SHA256_CTX sha256; 203 SHA256_CTX sha256;
204 SHA512_CTX sha512;
202}; 205};
203 206
204 207
@@ -207,6 +210,7 @@ static void start(HashType ht, Ctx & ctx)
207 if (ht == htMD5) MD5_Init(&ctx.md5); 210 if (ht == htMD5) MD5_Init(&ctx.md5);
208 else if (ht == htSHA1) SHA1_Init(&ctx.sha1); 211 else if (ht == htSHA1) SHA1_Init(&ctx.sha1);
209 else if (ht == htSHA256) SHA256_Init(&ctx.sha256); 212 else if (ht == htSHA256) SHA256_Init(&ctx.sha256);
213 else if (ht == htSHA512) SHA512_Init(&ctx.sha512);
210} 214}
211 215
212 216
@@ -216,6 +220,7 @@ static void update(HashType ht, Ctx & ctx,
216 if (ht == htMD5) MD5_Update(&ctx.md5, bytes, len); 220 if (ht == htMD5) MD5_Update(&ctx.md5, bytes, len);
217 else if (ht == htSHA1) SHA1_Update(&ctx.sha1, bytes, len); 221 else if (ht == htSHA1) SHA1_Update(&ctx.sha1, bytes, len);
218 else if (ht == htSHA256) SHA256_Update(&ctx.sha256, bytes, len); 222 else if (ht == htSHA256) SHA256_Update(&ctx.sha256, bytes, len);
223 else if (ht == htSHA512) SHA512_Update(&ctx.sha512, bytes, len);
219} 224}
220 225
221 226
@@ -224,6 +229,7 @@ static void finish(HashType ht, Ctx & ctx, unsigned char * hash)
224 if (ht == htMD5) MD5_Final(hash, &ctx.md5); 229 if (ht == htMD5) MD5_Final(hash, &ctx.md5);
225 else if (ht == htSHA1) SHA1_Final(hash, &ctx.sha1); 230 else if (ht == htSHA1) SHA1_Final(hash, &ctx.sha1);
226 else if (ht == htSHA256) SHA256_Final(hash, &ctx.sha256); 231 else if (ht == htSHA256) SHA256_Final(hash, &ctx.sha256);
232 else if (ht == htSHA512) SHA512_Final(hash, &ctx.sha512);
227} 233}
228 234
229 235
@@ -321,6 +327,7 @@ HashType parseHashType(const string & s)
321 if (s == "md5") return htMD5; 327 if (s == "md5") return htMD5;
322 else if (s == "sha1") return htSHA1; 328 else if (s == "sha1") return htSHA1;
323 else if (s == "sha256") return htSHA256; 329 else if (s == "sha256") return htSHA256;
330 else if (s == "sha512") return htSHA512;
324 else return htUnknown; 331 else return htUnknown;
325} 332}
326 333
@@ -330,6 +337,7 @@ string printHashType(HashType ht)
330 if (ht == htMD5) return "md5"; 337 if (ht == htMD5) return "md5";
331 else if (ht == htSHA1) return "sha1"; 338 else if (ht == htSHA1) return "sha1";
332 else if (ht == htSHA256) return "sha256"; 339 else if (ht == htSHA256) return "sha256";
340 else if (ht == htSHA512) return "sha512";
333 else throw Error("cannot print unknown hash type"); 341 else throw Error("cannot print unknown hash type");
334} 342}
335 343
diff --git a/nix/libutil/hash.hh b/nix/libutil/hash.hh
index 8f099c4f078..6b5e47cd8a2 100644
--- a/nix/libutil/hash.hh
+++ b/nix/libutil/hash.hh
@@ -7,19 +7,20 @@
7namespace nix { 7namespace nix {
8 8
9 9
10typedef enum { htUnknown, htMD5, htSHA1, htSHA256 } HashType; 10typedef enum { htUnknown, htMD5, htSHA1, htSHA256, htSHA512 } HashType;
11 11
12 12
13const int md5HashSize = 16; 13const int md5HashSize = 16;
14const int sha1HashSize = 20; 14const int sha1HashSize = 20;
15const int sha256HashSize = 32; 15const int sha256HashSize = 32;
16const int sha512HashSize = 64;
16 17
17extern const string base32Chars; 18extern const string base32Chars;
18 19
19 20
20struct Hash 21struct Hash
21{ 22{
22 static const unsigned int maxHashSize = 32; 23 static const unsigned int maxHashSize = 64;
23 unsigned int hashSize; 24 unsigned int hashSize;
24 unsigned char hash[maxHashSize]; 25 unsigned char hash[maxHashSize];
25 26
diff --git a/nix/libutil/sha512.h b/nix/libutil/sha512.h
new file mode 100644
index 00000000000..d2abab4c5ff
--- /dev/null
+++ b/nix/libutil/sha512.h
@@ -0,0 +1,35 @@
1/* GNU Guix --- Functional package management for GNU
2 Copyright (C) 2012, 2015 Ludovic Courtès <ludo@gnu.org>
3
4 This file is part of GNU Guix.
5
6 GNU Guix is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or (at
9 your option) any later version.
10
11 GNU Guix is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Guix. If not, see <http://www.gnu.org/licenses/>. */
18
19#include <gcrypt-hash.hh>
20
21#define SHA512_CTX guix_hash_context
22
23static inline void
24SHA512_Init (struct SHA512_CTX *ctx)
25{
26 guix_hash_init (ctx, GCRY_MD_SHA512);
27}
28
29#define SHA512_Update guix_hash_update
30
31static inline void
32SHA512_Final (void *resbuf, struct SHA512_CTX *ctx)
33{
34 guix_hash_final (resbuf, ctx, GCRY_MD_SHA512);
35}