759513d1 |
1 | Cryptographic hash functions |
2 | |
3 | |
4 | Hash functions are very useful cryptographic primitives. |
5 | Catacomb provides a few of the best-known cryptographic hashes. |
6 | |
7 | |
8 | Hash function interface |
9 | |
10 | Hash functions share a regular interface. I'll take Ron |
11 | Rivest's MD5 as an example. |
12 | |
13 | Using a hash function is a three-stage process. You initialize |
14 | a context, you hash some data, and you get the result out of the |
15 | end. The data to be hashed need not be contiguous, and you |
16 | don't have to have it all before you start. Hash function |
17 | contexts don't use up lots of memory. |
18 | |
19 | An MD5 context is called `md5_ctx'. You initialize it with |
20 | `md5_init'. You hash a block of data using `md5_hash' giving it |
21 | the context, the pointer to the data and its length. Finally, |
22 | you extract the data using `md5_done', giving it the address of |
23 | a buffer of MD5_HASHSZ bytes for it to write the result. |
24 | |
25 | There are some other standard operations as well, but they're |
26 | not often used: see the header files for details. |
27 | |
28 | The hash functions supported are: |
29 | |
30 | MD4 By Ron Rivest -- returns a 128-bit hash. MD4 is |
31 | not collision-resistant, and may not even be |
32 | second-preimage-resistant. Don't depend on its |
33 | security. On the other hand, MD4 is *very* |
34 | fast. |
35 | |
36 | MD5 Also by Rivest, also returns a 128-bit hash. |
37 | MD5 is slower than MD4, and more conservative, |
38 | but there are still grave doubts about its |
39 | security. |
40 | |
41 | SHA1 Designed by the US National Security Agency. |
42 | Returns a 160-bit hash. Slower than MD5. Looks |
43 | strong. Fixes a problem in the earlier SHA. |
44 | |
45 | RIPEMD-160 Designed by the people who broke MD4 and MD5. |
46 | Returns a 160-bit hash. Slower than SHA1. My |
47 | personal preference. |
48 | |
49 | |
50 | HMAC interface |
51 | |
52 | It's possible to construct a `keyed hash' or `message |
53 | authentication code' from a hash function. Most methods for |
54 | doing this are insecure. HMAC is a good method, with rigorously |
55 | proven security properties. |
56 | |
57 | Each hash function above has an HMAC mode defined for it. This |
58 | works much the same way as block cipher modes. |
59 | |
60 | Using HMAC is a two-step process. First, you initialize a MAC |
61 | key block `mackey' to contain the key you'll use, and then you |
62 | initialize MAC contexts `macctx' which to actually hash the |
63 | data. Hashing works just the same as the basic hash function, |
64 | except that you use `macinit', `machash' and `macdone' functions |
65 | rather than the plain `init', `hash' and `done'. |
66 | |
67 | |
68 | Generic interfaces |
69 | |
70 | Generic interfaces to hash functions and MACs are provided. See |
71 | README.cipher to get an idea for how a similar generic interface |
72 | works -- I'll only explain the differences here. |
73 | |
74 | The generic hash object, `ghash' contains an `ops' member |
75 | referring to: |
76 | |
77 | h->ops->b->name The name of the hash function. |
78 | |
79 | h->ops->b->hashsz The output size of the hash function. |
80 | |
81 | h->ops->hash(h, p, sz) Hash sz bytes of data starting at |
82 | address p. |
83 | |
84 | h->ops->done(h, b) Stop hashing, write the result to buffer |
85 | b with size `hashsz'. |
86 | |
87 | h->ops->destroy(h) Destroy the generic hash object. |
88 | |
89 | The generic hash class, `gchash', contains a base which has the |
90 | same members as `ops->b' above, and an `init' function which |
91 | takes no arguments and returns a pointer to a `ghash'. |
92 | |
93 | There's a generic MAC interface too. A MAC class, `gcmac' |
94 | contains a hash base (exactly the same, but with a different |
95 | name), and a function `key' which takes a pointer to some key |
96 | data and the key size, and returns a pointer to a `generic mac' |
97 | object, `gmac'. |
98 | |
99 | A `gmac' contains an `ops' member: |
100 | |
101 | m->ops->b->name, m->ops->b->hashsz |
102 | As above. |
103 | |
104 | m->ops->init(m) Returns a generic *hash* object to |
105 | actually compute a MAC over some data. |
106 | |
107 | m->ops->destroy(m) Destroys the generic MAC block. |
108 | |
109 | |
110 | That was quite complex. Here's an example of using a generic |
111 | MAC. |
112 | |
113 | void compute_mac(gcmac *gcm, const void *k, size_t ksz, |
114 | const void *p, size_t sz, |
115 | void *hash) |
116 | { |
117 | gmac *m = gcm->init(k, ksz); |
118 | ghash *h = m->ops->init(m); |
119 | m->ops->destroy(m); |
120 | h->ops->hash(h, p, sz); |
121 | h->ops->done(h, hash); |
122 | h->ops->destroy(h); |
123 | } |
124 | |
125 | Note that the hash doesn't depend on the MAC object continuing |
126 | to exist. |
127 | |
ee62fa16 |
128 | -- [mdw] |
759513d1 |
129 | |
130 | \f |
131 | Local variables: |
132 | mode: text |
133 | End: |