1 /* ---- HASH FUNCTIONS ---- */
2 module tomcrypt.hash;
3 
4 import core.stdc.config;
5 import core.stdc.stdio;
6 
7 import tomcrypt.custom;
8 import tomcrypt.tomcrypt;
9 
10 extern(C) nothrow:
11 
12 version(LTC_SHA512)
13 {
14     struct sha512_state 
15     {
16         ulong  length;
17         ulong[8] state;
18         c_ulong curlen;
19         ubyte[128] buf;
20     };
21 }
22 
23 version(LTC_SHA256)
24 {
25     struct sha256_state 
26     {
27         ulong length;
28         uint[8] state;
29         uint curlen;
30         ubyte[64] buf;
31     }
32 }
33 
34 version(LTC_SHA1)
35 {
36     struct sha1_state 
37     {
38         ulong length;
39         uint[5] state;
40         uint curlen;
41         ubyte[64] buf;
42     }
43 }
44 
45 version(LTC_MD5)
46 {
47     struct md5_state 
48     {
49         ulong length;
50         uint[4] state;
51         uint curlen;
52         ubyte[64] buf;
53     }
54 }
55 
56 version(LTC_MD4)
57 {
58     struct md4_state 
59     {
60         ulong length;
61         uint[4] state;
62         uint curlen;
63         ubyte[64] buf;
64     }
65 }
66 
67 version(LTC_TIGER)
68 {
69     struct tiger_state 
70     {
71         ulong[3] state;
72         ulong length;
73         c_ulong curlen;
74         ubyte[64] buf;
75     }
76 }
77 
78 version(LTC_MD2)
79 {
80     struct md2_state 
81     {
82         ubyte[16] chksum;
83         ubyte[48] X;
84         ubyte[16] buf;
85         c_ulong curlen;
86     }
87 }
88 
89 version(LTC_RIPEMD128)
90 {
91     struct rmd128_state 
92     {
93         ulong length;
94         ubyte[64] buf;
95         uint curlen;
96         uint[4] state;
97     }
98 }
99 
100 version(LTC_RIPEMD160)
101 {
102     struct rmd160_state 
103     {
104         ulong length;
105         ubyte[64] buf;
106         uint curlen;
107         uint[5] state;
108     }
109 }
110 
111 version(LTC_RIPEMD256)
112 {
113     struct rmd256_state {
114         ulong length;
115         ubyte[64] buf;
116         uint curlen;
117         uint[8] state;
118     }
119 }
120 
121 version(LTC_RIPEMD320)
122 {
123     struct rmd320_state 
124     {
125         ulong length;
126         ubyte[64] buf;
127         uint curlen;
128         uint[10] state;
129     }
130 }
131 
132 version(LTC_WHIRLPOOL)
133 {
134     struct whirlpool_state 
135     {
136         ulong length;
137         ulong[8] state;
138         ubyte[64] buf;
139         uint curlen;
140     }
141 }
142 
143 version(LTC_CHC_HASH)
144 {
145     struct chc_state 
146     {
147         ulong length;
148         ubyte[MAXBLOCKSIZE] state, buf;
149         uint curlen;
150     }
151 }
152 
153 union hash_state 
154 {
155     char[1] dummy;
156     version(LTC_CHC_HASH)
157     {
158         chc_state chc;
159     }
160     
161     version(LTC_WHIRLPOOL)
162     {
163         whirlpool_state whirlpool;
164     }
165     
166     version(LTC_SHA512)
167     {
168         sha512_state sha512;
169     }
170     
171     version(LTC_SHA256)
172     {
173         sha256_state sha256;
174     }
175     
176     version(LTC_SHA1)
177     {
178         sha1_state   sha1;
179     }
180     
181     version(LTC_MD5)
182     {
183         md5_state    md5;
184     }
185     
186     version(LTC_MD4)
187     {
188         md4_state    md4;
189     }
190     
191     version(LTC_MD2)
192     {
193         md2_state    md2;
194     }
195     
196     version(LTC_TIGER)
197     {
198         tiger_state  tiger;
199     }
200     
201     version(LTC_RIPEMD128)
202     {
203         rmd128_state rmd128;
204     }
205     
206     version(LTC_RIPEMD160)
207     {
208         rmd160_state rmd160;
209     }
210     
211     version(LTC_RIPEMD256)
212     {
213         rmd256_state rmd256;
214     }
215     
216     version(LTC_RIPEMD320)
217     {
218         rmd320_state rmd320;
219     }
220     
221     void *data;
222 }
223 
224 /** hash descriptor */
225 struct ltc_hash_descriptor 
226 {
227     /** name of hash */
228     char *name;
229     /** internal ID */
230     ubyte ID;
231     /** Size of digest in octets */
232     c_ulong hashsize;
233     /** Input block size in octets */
234     c_ulong blocksize;
235     /** ASN.1 OID */
236     c_ulong[16] OID;
237     /** Length of DER encoding */
238     c_ulong OIDlen;
239 
240     /** Init a hash state
241       @param hash   The hash to initialize
242       @return CRYPT_OK if successful
243     */
244     int function(hash_state *hash) nothrow init;
245     /** Process a block of data 
246       @param hash   The hash state
247       @param in     The data to hash
248       @param inlen  The length of the data (octets)
249       @return CRYPT_OK if successful
250     */
251     int function(hash_state *hash, const ubyte *_in, c_ulong inlen) nothrow process;
252     /** Produce the digest and store it
253       @param hash   The hash state
254       @param out    [out] The destination of the digest
255       @return CRYPT_OK if successful
256     */
257     int function(hash_state *hash, ubyte *_out) nothrow done;
258     /** Self-test
259       @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
260     */
261     int function() nothrow test;
262 
263     /* accelerated hmac callback: if you need to-do multiple packets just use the generic hmac_memory and provide a hash callback */
264     int  function(     const ubyte *key, c_ulong  keylen,
265                        const ubyte *_in,  c_ulong  inlen, 
266                              ubyte *_out, c_ulong *outlen) nothrow hmac_block;
267 
268 } 
269 extern __gshared ltc_hash_descriptor[] hash_descriptor;
270 
271 version(LTC_CHC_HASH)
272 {
273     int chc_register(int cipher);
274     int chc_init(hash_state * md);
275     int chc_process(hash_state * md, const ubyte *_in, c_ulong inlen);
276     int chc_done(hash_state * md, ubyte *hash);
277     int chc_test();
278     extern __gshared const ltc_hash_descriptor chc_desc;
279 }
280 
281 version(LTC_WHIRLPOOL)
282 {
283     int whirlpool_init(hash_state * md);
284     int whirlpool_process(hash_state * md, const ubyte *_in, c_ulong inlen);
285     int whirlpool_done(hash_state * md, ubyte *hash);
286     int whirlpool_test();
287     extern __gshared const ltc_hash_descriptor whirlpool_desc;
288 }
289 
290 version(LTC_SHA512)
291 {
292     int sha512_init(hash_state * md);
293     int sha512_process(hash_state * md, const ubyte *_in, c_ulong inlen);
294     int sha512_done(hash_state * md, ubyte *hash);
295     int sha512_test();
296     extern __gshared const ltc_hash_descriptor sha512_desc;
297 }
298 
299 version(LTC_SHA384)
300 {
301     version(LTC_SHA512) {}
302     else
303     {
304         pragma(error, "LTC_SHA512 is required for LTC_SHA384");
305     }
306     
307     int sha384_init(hash_state * md);
308     alias sha384_process = sha512_process;
309     int sha384_done(hash_state * md, ubyte *hash);
310     int sha384_test();
311     extern __gshared const ltc_hash_descriptor sha384_desc;
312 }
313 
314 version(LTC_SHA256)
315 {
316     int sha256_init(hash_state * md);
317     int sha256_process(hash_state * md, const ubyte *_in, c_ulong inlen);
318     int sha256_done(hash_state * md, ubyte *hash);
319     int sha256_test();
320     extern __gshared const ltc_hash_descriptor sha256_desc;
321 
322     version(LTC_SHA224)
323     {
324         version(LTC_SHA256) {}
325         else
326         {
327             pragma(error, "LTC_SHA256 is required for LTC_SHA224");
328         }
329     
330         int sha224_init(hash_state * md);
331         alias sha224_process = sha256_process;
332         int sha224_done(hash_state * md, ubyte *hash);
333         int sha224_test();
334         extern __gshared const ltc_hash_descriptor sha224_desc;
335     }
336 }
337 
338 version(LTC_SHA1)
339 {
340     int sha1_init(hash_state * md);
341     int sha1_process(hash_state * md, const ubyte *_in, c_ulong inlen);
342     int sha1_done(hash_state * md, ubyte *hash);
343     int sha1_test();
344     extern __gshared const ltc_hash_descriptor sha1_desc;
345 }
346 
347 version(LTC_MD5)
348 {
349     int md5_init(hash_state * md);
350     int md5_process(hash_state * md, const ubyte *_in, c_ulong inlen);
351     int md5_done(hash_state * md, ubyte *hash);
352     int md5_test();
353     extern __gshared const ltc_hash_descriptor md5_desc;
354 }
355 
356 version(LTC_MD4)
357 {
358     int md4_init(hash_state * md);
359     int md4_process(hash_state * md, const ubyte *_in, c_ulong inlen);
360     int md4_done(hash_state * md, ubyte *hash);
361     int md4_test();
362     extern __gshared const ltc_hash_descriptor md4_desc;
363 }
364 
365 version(LTC_MD2)
366 {
367     int md2_init(hash_state * md);
368     int md2_process(hash_state * md, const ubyte *_in, c_ulong inlen);
369     int md2_done(hash_state * md, ubyte *hash);
370     int md2_test();
371     extern __gshared const ltc_hash_descriptor md2_desc;
372 }
373 
374 version(LTC_TIGER)
375 {
376     int tiger_init(hash_state * md);
377     int tiger_process(hash_state * md, const ubyte *_in, c_ulong inlen);
378     int tiger_done(hash_state * md, ubyte *hash);
379     int tiger_test();
380     extern __gshared const ltc_hash_descriptor tiger_desc;
381 }
382 
383 version(LTC_RIPEMD128)
384 {
385     int rmd128_init(hash_state * md);
386     int rmd128_process(hash_state * md, const ubyte *_in, c_ulong inlen);
387     int rmd128_done(hash_state * md, ubyte *hash);
388     int rmd128_test();
389     extern __gshared const ltc_hash_descriptor rmd128_desc;
390 }
391 
392 version(LTC_RIPEMD160)
393 {
394     int rmd160_init(hash_state * md);
395     int rmd160_process(hash_state * md, const ubyte *_in, c_ulong inlen);
396     int rmd160_done(hash_state * md, ubyte *hash);
397     int rmd160_test();
398     extern __gshared const ltc_hash_descriptor rmd160_desc;
399 }
400 
401 version(LTC_RIPEMD256)
402 {
403     int rmd256_init(hash_state * md);
404     int rmd256_process(hash_state * md, const ubyte *_in, c_ulong inlen);
405     int rmd256_done(hash_state * md, ubyte *hash);
406     int rmd256_test();
407     extern __gshared const ltc_hash_descriptor rmd256_desc;
408 }
409 
410 version(LTC_RIPEMD320)
411 {
412     int rmd320_init(hash_state * md);
413     int rmd320_process(hash_state * md, const ubyte *_in, c_ulong inlen);
414     int rmd320_done(hash_state * md, ubyte *hash);
415     int rmd320_test();
416     extern __gshared const ltc_hash_descriptor rmd320_desc;
417 }
418 
419 
420 int find_hash(const char *name);
421 int find_hash_id(ubyte ID);
422 int find_hash_oid(const c_ulong *ID, c_ulong IDlen);
423 int find_hash_any(const char *name, int digestlen);
424 int register_hash(const ltc_hash_descriptor *hash);
425 int unregister_hash(const ltc_hash_descriptor *hash);
426 int hash_is_valid(int idx);
427 
428 mixin(LTC_MUTEX_PROTO("ltc_hash_mutex"));
429 
430 int hash_memory(int hash, 
431                 const ubyte *_in,  c_ulong inlen, 
432                       ubyte *_out, c_ulong *outlen);
433 int hash_memory_multi(int hash, ubyte *_out, c_ulong *outlen,
434                       const ubyte *_in, c_ulong inlen, ...);
435 int hash_filehandle(int hash, FILE *_in, ubyte *_out, c_ulong *outlen);
436 int hash_file(int hash, const char *fname, ubyte *_out, c_ulong *outlen);
437 
438 /* a simple macro for making hash "process" functions */                 
439 string HASH_PROCESS(string func_name, string compress_name, string state_var, string block_size)
440 {
441     return q{
442 int }~func_name~q{ (hash_state * md, const ubyte *_in, c_ulong inlen)               
443 {                                                                                           
444     c_ulong n;                                                                        
445     int           err;                                                                      
446     mixin(LTC_ARGCHK("md != NULL"));                                                                 
447     mixin(LTC_ARGCHK("_in != NULL"));                                                                 
448     if (md.}~state_var~q{.curlen > sizeof(md..}~state_var~q{.buf)) {                             
449        return CRYPT_INVALID_ARG;                                                            
450     }                                                                                       
451     while (inlen > 0) {                                                                     
452         if (md.}~state_var~q{.curlen == 0 && inlen >= }~block_size~q{) {                           
453            if ((err = }~compress_name~q{ (md, cast(ubyte *)_in)) != CRYPT_OK) {               
454               return err;                                                                   
455            }                                                                                
456            md..}~state_var~q{.length += }~block_size~q{ * 8;                                        
457            _in            += }~block_size~q{;                                                    
458            inlen          -= }~block_size~q{;                                                    
459         } else {
460             
461            auto MIN(T,U)(T a, T b) { return a > b ? b : a;}                                                                             
462            n = MIN(inlen, (}~block_size~q{ - md-> }~state_var~q{ .curlen)); 
463                                          
464            memcpy(md..}~state_var~q{.buf + md..}~state_var~q{.curlen, _in, cast(size_t)n);              
465            md..}~state_var~q{.curlen += n;                                                     
466            _in            += n;                                                             
467            inlen          -= n;                                                             
468            if (md..}~state_var~q{.curlen == }~block_size~q{) {                                      
469               if ((err = }~compress_name~q{ (md, md..}~state_var~q{.buf)) != CRYPT_OK) {            
470                  return err;                                                                
471               }                                                                             
472               md..}~state_var~q{.length += 8*}~block_size~q{;                                       
473               md..}~state_var~q{.curlen = 0;                                                   
474            }                                                                                
475        }                                                                                    
476     }                                                                                       
477     return CRYPT_OK;                                                                        
478 }
479     };
480 }
481 /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_hash.h,v $ */
482 /* $Revision: 1.22 $ */
483 /* $Date: 2007/05/12 14:32:35 $ */