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>
This commit is contained in:
		
							parent
							
								
									79aa1a8305
								
							
						
					
					
						commit
						29d3242e5c
					
				
					 4 changed files with 48 additions and 3 deletions
				
			
		|  | @ -69,7 +69,8 @@ libutil_headers =				\ | |||
|   nix/libutil/gcrypt-hash.hh			\ | ||||
|   nix/libutil/md5.h				\ | ||||
|   nix/libutil/sha1.h				\ | ||||
|   nix/libutil/sha256.h | ||||
|   nix/libutil/sha256.h				\ | ||||
|   nix/libutil/sha512.h | ||||
| 
 | ||||
| libutil_a_CPPFLAGS =				\ | ||||
|   -I$(top_builddir)/nix				\ | ||||
|  |  | |||
|  | @ -11,6 +11,7 @@ extern "C" { | |||
| #include "md5.h" | ||||
| #include "sha1.h" | ||||
| #include "sha256.h" | ||||
| #include "sha512.h" | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
|  | @ -40,6 +41,7 @@ Hash::Hash(HashType type) | |||
|     if (type == htMD5) hashSize = md5HashSize; | ||||
|     else if (type == htSHA1) hashSize = sha1HashSize; | ||||
|     else if (type == htSHA256) hashSize = sha256HashSize; | ||||
|     else if (type == htSHA512) hashSize = sha512HashSize; | ||||
|     else throw Error("unknown hash type"); | ||||
|     assert(hashSize <= maxHashSize); | ||||
|     memset(hash, 0, maxHashSize); | ||||
|  | @ -199,6 +201,7 @@ struct Ctx | |||
|     MD5_CTX md5; | ||||
|     SHA_CTX sha1; | ||||
|     SHA256_CTX sha256; | ||||
|     SHA512_CTX sha512; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
|  | @ -207,6 +210,7 @@ static void start(HashType ht, Ctx & ctx) | |||
|     if (ht == htMD5) MD5_Init(&ctx.md5); | ||||
|     else if (ht == htSHA1) SHA1_Init(&ctx.sha1); | ||||
|     else if (ht == htSHA256) SHA256_Init(&ctx.sha256); | ||||
|     else if (ht == htSHA512) SHA512_Init(&ctx.sha512); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -216,6 +220,7 @@ static void update(HashType ht, Ctx & ctx, | |||
|     if (ht == htMD5) MD5_Update(&ctx.md5, bytes, len); | ||||
|     else if (ht == htSHA1) SHA1_Update(&ctx.sha1, bytes, len); | ||||
|     else if (ht == htSHA256) SHA256_Update(&ctx.sha256, bytes, len); | ||||
|     else if (ht == htSHA512) SHA512_Update(&ctx.sha512, bytes, len); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -224,6 +229,7 @@ static void finish(HashType ht, Ctx & ctx, unsigned char * hash) | |||
|     if (ht == htMD5) MD5_Final(hash, &ctx.md5); | ||||
|     else if (ht == htSHA1) SHA1_Final(hash, &ctx.sha1); | ||||
|     else if (ht == htSHA256) SHA256_Final(hash, &ctx.sha256); | ||||
|     else if (ht == htSHA512) SHA512_Final(hash, &ctx.sha512); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -321,6 +327,7 @@ HashType parseHashType(const string & s) | |||
|     if (s == "md5") return htMD5; | ||||
|     else if (s == "sha1") return htSHA1; | ||||
|     else if (s == "sha256") return htSHA256; | ||||
|     else if (s == "sha512") return htSHA512; | ||||
|     else return htUnknown; | ||||
| } | ||||
| 
 | ||||
|  | @ -330,6 +337,7 @@ string printHashType(HashType ht) | |||
|     if (ht == htMD5) return "md5"; | ||||
|     else if (ht == htSHA1) return "sha1"; | ||||
|     else if (ht == htSHA256) return "sha256"; | ||||
|     else if (ht == htSHA512) return "sha512"; | ||||
|     else throw Error("cannot print unknown hash type"); | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,19 +7,20 @@ | |||
| namespace nix { | ||||
| 
 | ||||
| 
 | ||||
| typedef enum { htUnknown, htMD5, htSHA1, htSHA256 } HashType; | ||||
| typedef enum { htUnknown, htMD5, htSHA1, htSHA256, htSHA512 } HashType; | ||||
| 
 | ||||
| 
 | ||||
| const int md5HashSize = 16; | ||||
| const int sha1HashSize = 20; | ||||
| const int sha256HashSize = 32; | ||||
| const int sha512HashSize = 64; | ||||
| 
 | ||||
| extern const string base32Chars; | ||||
| 
 | ||||
| 
 | ||||
| struct Hash | ||||
| { | ||||
|     static const unsigned int maxHashSize = 32; | ||||
|     static const unsigned int maxHashSize = 64; | ||||
|     unsigned int hashSize; | ||||
|     unsigned char hash[maxHashSize]; | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										35
									
								
								nix/libutil/sha512.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								nix/libutil/sha512.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | |||
| /* GNU Guix --- Functional package management for GNU
 | ||||
|    Copyright (C) 2012, 2015 Ludovic Courtès <ludo@gnu.org> | ||||
| 
 | ||||
|    This file is part of GNU Guix. | ||||
| 
 | ||||
|    GNU Guix is free software; you can redistribute it and/or modify it | ||||
|    under the terms of the GNU General Public License as published by | ||||
|    the Free Software Foundation; either version 3 of the License, or (at | ||||
|    your option) any later version. | ||||
| 
 | ||||
|    GNU Guix is distributed in the hope that it will be useful, but | ||||
|    WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
|    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||
|    GNU General Public License for more details. | ||||
| 
 | ||||
|    You should have received a copy of the GNU General Public License | ||||
|    along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>.  */
 | ||||
| 
 | ||||
| #include <gcrypt-hash.hh> | ||||
| 
 | ||||
| #define SHA512_CTX guix_hash_context | ||||
| 
 | ||||
| static inline void | ||||
| SHA512_Init (struct SHA512_CTX *ctx) | ||||
| { | ||||
|   guix_hash_init (ctx, GCRY_MD_SHA512); | ||||
| } | ||||
| 
 | ||||
| #define SHA512_Update guix_hash_update | ||||
| 
 | ||||
| static inline void | ||||
| SHA512_Final (void *resbuf, struct SHA512_CTX *ctx) | ||||
| { | ||||
|   guix_hash_final (resbuf, ctx, GCRY_MD_SHA512); | ||||
| } | ||||
		Reference in a new issue