diff options
author | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-04-09 16:29:05 +0000 |
---|---|---|
committer | Maurus Cuelenaere <mcuelenaere@gmail.com> | 2008-04-09 16:29:05 +0000 |
commit | 49236bb62bedc07221de0b04005809d63f03f9ee (patch) | |
tree | 598db82232180437b82c7dfab13199bbaff35c52 | |
parent | ab796a2e4981f159fdbc86e8c2d3f5c86cf978a4 (diff) | |
download | rockbox-49236bb62bedc07221de0b04005809d63f03f9ee.tar.gz rockbox-49236bb62bedc07221de0b04005809d63f03f9ee.zip |
Change HMAC-SHA1 implementation to the one taken from gnulib, which
contains a more clear copyright notice.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@17054 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | tools/creative.c | 4 | ||||
-rw-r--r-- | tools/hmac-sha1.c | 827 | ||||
-rw-r--r-- | tools/hmac-sha1.h | 174 |
3 files changed, 557 insertions, 448 deletions
diff --git a/tools/creative.c b/tools/creative.c index 5b8f15abc0..b9041ca513 100644 --- a/tools/creative.c +++ b/tools/creative.c | |||
@@ -68,8 +68,8 @@ static int make_ciff_file(unsigned char *inbuf, int length, | |||
68 | memcpy(&outbuf[0x98+length], "LLUN", 4); | 68 | memcpy(&outbuf[0x98+length], "LLUN", 4); |
69 | int2le(20, &outbuf[0x98+length+4]); | 69 | int2le(20, &outbuf[0x98+length+4]); |
70 | /* Do checksum */ | 70 | /* Do checksum */ |
71 | hmac_sha((unsigned char *)devices[device].null, strlen(devices[device].null), | 71 | hmac_sha1((unsigned char *)devices[device].null, strlen(devices[device].null), |
72 | outbuf, 0x98+length, key, 20); | 72 | outbuf, 0x98+length, key); |
73 | memcpy(&outbuf[0x98+length+8], key, 20); | 73 | memcpy(&outbuf[0x98+length+8], key, 20); |
74 | return length+0x90+0x1C+8; | 74 | return length+0x90+0x1C+8; |
75 | } | 75 | } |
diff --git a/tools/hmac-sha1.c b/tools/hmac-sha1.c index 8882b10b9a..d036a45a86 100644 --- a/tools/hmac-sha1.c +++ b/tools/hmac-sha1.c | |||
@@ -1,453 +1,516 @@ | |||
1 | /* | 1 | /* sha1.c - Functions to compute SHA1 message digest of files or |
2 | * sha1.c | 2 | memory blocks according to the NIST specification FIPS-180-1. |
3 | * | ||
4 | * Description: | ||
5 | * This file implements the Secure Hashing Algorithm 1 as | ||
6 | * defined in FIPS PUB 180-1 published April 17, 1995. | ||
7 | * | ||
8 | * The SHA-1, produces a 160-bit message digest for a given | ||
9 | * data stream. It should take about 2**n steps to find a | ||
10 | * message with the same digest as a given message and | ||
11 | * 2**(n/2) to find any two messages with the same digest, | ||
12 | * when n is the digest size in bits. Therefore, this | ||
13 | * algorithm can serve as a means of providing a | ||
14 | * "fingerprint" for a message. | ||
15 | * | ||
16 | * Portability Issues: | ||
17 | * SHA-1 is defined in terms of 32-bit "words". This code | ||
18 | * uses <stdint.h> (included via "sha1.h" to define 32 and 8 | ||
19 | * bit unsigned integer types. If your C compiler does not | ||
20 | * support 32 bit unsigned integers, this code is not | ||
21 | * appropriate. | ||
22 | * | ||
23 | * Caveats: | ||
24 | * SHA-1 is designed to work with messages less than 2^64 bits | ||
25 | * long. Although SHA-1 allows a message digest to be generated | ||
26 | * for messages of any number of bits less than 2^64, this | ||
27 | * implementation only works with messages with a length that is | ||
28 | * a multiple of the size of an 8-bit character. | ||
29 | * | ||
30 | */ | ||
31 | 3 | ||
32 | #include <string.h> | 4 | Copyright (C) 2000, 2001, 2003, 2004, 2005, 2006 Free Software |
5 | Foundation, Inc. | ||
6 | |||
7 | This program is free software; you can redistribute it and/or modify it | ||
8 | under the terms of the GNU General Public License as published by the | ||
9 | Free Software Foundation; either version 2, or (at your option) any | ||
10 | later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software Foundation, | ||
19 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
20 | |||
21 | /* Written by Scott G. Miller | ||
22 | Credits: | ||
23 | Robert Klep <robert@ilse.nl> -- Expansion function fix | ||
24 | */ | ||
33 | 25 | ||
34 | #include "hmac-sha1.h" | 26 | #include "hmac-sha1.h" |
35 | 27 | ||
36 | /* | 28 | #include <stddef.h> |
37 | * Define the SHA1 circular left shift macro | 29 | #include <string.h> |
38 | */ | ||
39 | #define SHA1CircularShift(bits,word) \ | ||
40 | (((word) << (bits)) | ((word) >> (32-(bits)))) | ||
41 | |||
42 | /* Local Function Prototyptes */ | ||
43 | void SHA1PadMessage(SHA1Context *); | ||
44 | void SHA1ProcessMessageBlock(SHA1Context *); | ||
45 | |||
46 | /* | ||
47 | * SHA1Reset | ||
48 | * | ||
49 | * Description: | ||
50 | * This function will initialize the SHA1Context in preparation | ||
51 | * for computing a new SHA1 message digest. | ||
52 | * | ||
53 | * Parameters: | ||
54 | * context: [in/out] | ||
55 | * The context to reset. | ||
56 | * | ||
57 | * Returns: | ||
58 | * sha Error Code. | ||
59 | * | ||
60 | */ | ||
61 | int SHA1Reset(SHA1Context *context) | ||
62 | { | ||
63 | if (!context) | ||
64 | { | ||
65 | return shaNull; | ||
66 | } | ||
67 | 30 | ||
68 | context->Length_Low = 0; | ||
69 | context->Length_High = 0; | ||
70 | context->Message_Block_Index = 0; | ||
71 | 31 | ||
72 | context->Intermediate_Hash[0] = 0x67452301; | 32 | #ifdef WORDS_BIGENDIAN |
73 | context->Intermediate_Hash[1] = 0xEFCDAB89; | 33 | # define SWAP(n) (n) |
74 | context->Intermediate_Hash[2] = 0x98BADCFE; | 34 | #else |
75 | context->Intermediate_Hash[3] = 0x10325476; | 35 | # define SWAP(n) \ |
76 | context->Intermediate_Hash[4] = 0xC3D2E1F0; | 36 | (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) |
37 | #endif | ||
77 | 38 | ||
78 | context->Computed = 0; | 39 | #define BLOCKSIZE 4096 |
79 | context->Corrupted = 0; | 40 | #if BLOCKSIZE % 64 != 0 |
41 | # error "invalid BLOCKSIZE" | ||
42 | #endif | ||
80 | 43 | ||
81 | return shaSuccess; | 44 | /* This array contains the bytes used to pad the buffer to the next |
45 | 64-byte boundary. (RFC 1321, 3.1: Step 1) */ | ||
46 | static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; | ||
47 | |||
48 | |||
49 | /* Take a pointer to a 160 bit block of data (five 32 bit ints) and | ||
50 | initialize it to the start constants of the SHA1 algorithm. This | ||
51 | must be called before using hash in the call to sha1_hash. */ | ||
52 | void | ||
53 | sha1_init_ctx (struct sha1_ctx *ctx) | ||
54 | { | ||
55 | ctx->A = 0x67452301; | ||
56 | ctx->B = 0xefcdab89; | ||
57 | ctx->C = 0x98badcfe; | ||
58 | ctx->D = 0x10325476; | ||
59 | ctx->E = 0xc3d2e1f0; | ||
60 | |||
61 | ctx->total[0] = ctx->total[1] = 0; | ||
62 | ctx->buflen = 0; | ||
82 | } | 63 | } |
83 | 64 | ||
84 | /* | 65 | /* Put result from CTX in first 20 bytes following RESBUF. The result |
85 | * SHA1Result | 66 | must be in little endian byte order. |
86 | * | 67 | |
87 | * Description: | 68 | IMPORTANT: On some systems it is required that RESBUF is correctly |
88 | * This function will return the 160-bit message digest into the | 69 | aligned for a 32-bit value. */ |
89 | * Message_Digest array provided by the caller. | 70 | void * |
90 | * NOTE: The first octet of hash is stored in the 0th element, | 71 | sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf) |
91 | * the last octet of hash in the 19th element. | ||
92 | * | ||
93 | * Parameters: | ||
94 | * context: [in/out] | ||
95 | * The context to use to calculate the SHA-1 hash. | ||
96 | * Message_Digest: [out] | ||
97 | * Where the digest is returned. | ||
98 | * | ||
99 | * Returns: | ||
100 | * sha Error Code. | ||
101 | * | ||
102 | */ | ||
103 | int SHA1Result( SHA1Context *context, | ||
104 | uint8_t Message_Digest[SHA1HashSize]) | ||
105 | { | 72 | { |
106 | int i; | 73 | ((uint32_t *) resbuf)[0] = SWAP (ctx->A); |
74 | ((uint32_t *) resbuf)[1] = SWAP (ctx->B); | ||
75 | ((uint32_t *) resbuf)[2] = SWAP (ctx->C); | ||
76 | ((uint32_t *) resbuf)[3] = SWAP (ctx->D); | ||
77 | ((uint32_t *) resbuf)[4] = SWAP (ctx->E); | ||
107 | 78 | ||
108 | if (!context || !Message_Digest) | 79 | return resbuf; |
109 | { | 80 | } |
110 | return shaNull; | ||
111 | } | ||
112 | 81 | ||
113 | if (context->Corrupted) | 82 | /* Process the remaining bytes in the internal buffer and the usual |
114 | { | 83 | prolog according to the standard and write the result to RESBUF. |
115 | return context->Corrupted; | ||
116 | } | ||
117 | 84 | ||
118 | if (!context->Computed) | 85 | IMPORTANT: On some systems it is required that RESBUF is correctly |
119 | { | 86 | aligned for a 32-bit value. */ |
120 | SHA1PadMessage(context); | 87 | void * |
121 | for(i=0; i<64; ++i) | 88 | sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf) |
122 | { | 89 | { |
123 | /* message may be sensitive, clear it out */ | 90 | /* Take yet unprocessed bytes into account. */ |
124 | context->Message_Block[i] = 0; | 91 | uint32_t bytes = ctx->buflen; |
125 | } | 92 | size_t size = (bytes < 56) ? 64 / 4 : 64 * 2 / 4; |
126 | context->Length_Low = 0; /* and clear length */ | ||
127 | context->Length_High = 0; | ||
128 | context->Computed = 1; | ||
129 | } | ||
130 | 93 | ||
131 | for(i = 0; i < SHA1HashSize; ++i) | 94 | /* Now count remaining bytes. */ |
132 | { | 95 | ctx->total[0] += bytes; |
133 | Message_Digest[i] = context->Intermediate_Hash[i>>2] | 96 | if (ctx->total[0] < bytes) |
134 | >> 8 * ( 3 - ( i & 0x03 ) ); | 97 | ++ctx->total[1]; |
135 | } | 98 | |
99 | /* Put the 64-bit file length in *bits* at the end of the buffer. */ | ||
100 | ctx->buffer[size - 2] = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29)); | ||
101 | ctx->buffer[size - 1] = SWAP (ctx->total[0] << 3); | ||
102 | |||
103 | memcpy (&((char *) ctx->buffer)[bytes], fillbuf, (size - 2) * 4 - bytes); | ||
104 | |||
105 | /* Process last bytes. */ | ||
106 | sha1_process_block (ctx->buffer, size * 4, ctx); | ||
136 | 107 | ||
137 | return shaSuccess; | 108 | return sha1_read_ctx (ctx, resbuf); |
138 | } | 109 | } |
139 | 110 | ||
140 | /* | 111 | /* Compute SHA1 message digest for bytes read from STREAM. The |
141 | * SHA1Input | 112 | resulting message digest number will be written into the 16 bytes |
142 | * | 113 | beginning at RESBLOCK. */ |
143 | * Description: | 114 | int |
144 | * This function accepts an array of octets as the next portion | 115 | sha1_stream (FILE *stream, void *resblock) |
145 | * of the message. | ||
146 | * | ||
147 | * Parameters: | ||
148 | * context: [in/out] | ||
149 | * The SHA context to update | ||
150 | * message_array: [in] | ||
151 | * An array of characters representing the next portion of | ||
152 | * the message. | ||
153 | * length: [in] | ||
154 | * The length of the message in message_array | ||
155 | * | ||
156 | * Returns: | ||
157 | * sha Error Code. | ||
158 | * | ||
159 | */ | ||
160 | int SHA1Input( SHA1Context *context, | ||
161 | const uint8_t *message_array, | ||
162 | unsigned length) | ||
163 | { | 116 | { |
164 | if (!length) | 117 | struct sha1_ctx ctx; |
165 | { | 118 | char buffer[BLOCKSIZE + 72]; |
166 | return shaSuccess; | 119 | size_t sum; |
167 | } | ||
168 | 120 | ||
169 | if (!context || !message_array) | 121 | /* Initialize the computation context. */ |
170 | { | 122 | sha1_init_ctx (&ctx); |
171 | return shaNull; | ||
172 | } | ||
173 | 123 | ||
174 | if (context->Computed) | 124 | /* Iterate over full file contents. */ |
125 | while (1) | ||
175 | { | 126 | { |
176 | context->Corrupted = shaStateError; | 127 | /* We read the file in blocks of BLOCKSIZE bytes. One call of the |
177 | return shaStateError; | 128 | computation function processes the whole buffer so that with the |
129 | next round of the loop another block can be read. */ | ||
130 | size_t n; | ||
131 | sum = 0; | ||
132 | |||
133 | /* Read block. Take care for partial reads. */ | ||
134 | while (1) | ||
135 | { | ||
136 | n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); | ||
137 | |||
138 | sum += n; | ||
139 | |||
140 | if (sum == BLOCKSIZE) | ||
141 | break; | ||
142 | |||
143 | if (n == 0) | ||
144 | { | ||
145 | /* Check for the error flag IFF N == 0, so that we don't | ||
146 | exit the loop after a partial read due to e.g., EAGAIN | ||
147 | or EWOULDBLOCK. */ | ||
148 | if (ferror (stream)) | ||
149 | return 1; | ||
150 | goto process_partial_block; | ||
151 | } | ||
152 | |||
153 | /* We've read at least one byte, so ignore errors. But always | ||
154 | check for EOF, since feof may be true even though N > 0. | ||
155 | Otherwise, we could end up calling fread after EOF. */ | ||
156 | if (feof (stream)) | ||
157 | goto process_partial_block; | ||
158 | } | ||
159 | |||
160 | /* Process buffer with BLOCKSIZE bytes. Note that | ||
161 | BLOCKSIZE % 64 == 0 | ||
162 | */ | ||
163 | sha1_process_block (buffer, BLOCKSIZE, &ctx); | ||
178 | } | 164 | } |
179 | 165 | ||
180 | if (context->Corrupted) | 166 | process_partial_block:; |
181 | { | 167 | |
182 | return context->Corrupted; | 168 | /* Process any remaining bytes. */ |
183 | } | 169 | if (sum > 0) |
184 | while(length-- && !context->Corrupted) | 170 | sha1_process_bytes (buffer, sum, &ctx); |
185 | { | ||
186 | context->Message_Block[context->Message_Block_Index++] = | ||
187 | (*message_array & 0xFF); | ||
188 | |||
189 | context->Length_Low += 8; | ||
190 | if (context->Length_Low == 0) | ||
191 | { | ||
192 | context->Length_High++; | ||
193 | if (context->Length_High == 0) | ||
194 | { | ||
195 | /* Message is too long */ | ||
196 | context->Corrupted = 1; | ||
197 | } | ||
198 | } | ||
199 | |||
200 | if (context->Message_Block_Index == 64) | ||
201 | { | ||
202 | SHA1ProcessMessageBlock(context); | ||
203 | } | ||
204 | |||
205 | message_array++; | ||
206 | } | ||
207 | 171 | ||
208 | return shaSuccess; | 172 | /* Construct result in desired memory. */ |
173 | sha1_finish_ctx (&ctx, resblock); | ||
174 | return 0; | ||
209 | } | 175 | } |
210 | 176 | ||
211 | /* | 177 | /* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The |
212 | * SHA1ProcessMessageBlock | 178 | result is always in little endian byte order, so that a byte-wise |
213 | * | 179 | output yields to the wanted ASCII representation of the message |
214 | * Description: | 180 | digest. */ |
215 | * This function will process the next 512 bits of the message | 181 | void * |
216 | * stored in the Message_Block array. | 182 | sha1_buffer (const char *buffer, size_t len, void *resblock) |
217 | * | ||
218 | * Parameters: | ||
219 | * None. | ||
220 | * | ||
221 | * Returns: | ||
222 | * Nothing. | ||
223 | * | ||
224 | * Comments: | ||
225 | * Many of the variable names in this code, especially the | ||
226 | * single character names, were used because those were the | ||
227 | * names used in the publication. | ||
228 | * | ||
229 | * | ||
230 | */ | ||
231 | void SHA1ProcessMessageBlock(SHA1Context *context) | ||
232 | { | 183 | { |
233 | const uint32_t K[] = { /* Constants defined in SHA-1 */ | 184 | struct sha1_ctx ctx; |
234 | 0x5A827999, | ||
235 | 0x6ED9EBA1, | ||
236 | 0x8F1BBCDC, | ||
237 | 0xCA62C1D6 | ||
238 | }; | ||
239 | int t; /* Loop counter */ | ||
240 | uint32_t temp; /* Temporary word value */ | ||
241 | uint32_t W[80]; /* Word sequence */ | ||
242 | uint32_t A, B, C, D, E; /* Word buffers */ | ||
243 | |||
244 | /* | ||
245 | * Initialize the first 16 words in the array W | ||
246 | */ | ||
247 | for(t = 0; t < 16; t++) | ||
248 | { | ||
249 | W[t] = context->Message_Block[t * 4] << 24; | ||
250 | W[t] |= context->Message_Block[t * 4 + 1] << 16; | ||
251 | W[t] |= context->Message_Block[t * 4 + 2] << 8; | ||
252 | W[t] |= context->Message_Block[t * 4 + 3]; | ||
253 | } | ||
254 | 185 | ||
255 | for(t = 16; t < 80; t++) | 186 | /* Initialize the computation context. */ |
256 | { | 187 | sha1_init_ctx (&ctx); |
257 | W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); | ||
258 | } | ||
259 | 188 | ||
260 | A = context->Intermediate_Hash[0]; | 189 | /* Process whole buffer but last len % 64 bytes. */ |
261 | B = context->Intermediate_Hash[1]; | 190 | sha1_process_bytes (buffer, len, &ctx); |
262 | C = context->Intermediate_Hash[2]; | ||
263 | D = context->Intermediate_Hash[3]; | ||
264 | E = context->Intermediate_Hash[4]; | ||
265 | 191 | ||
266 | for(t = 0; t < 20; t++) | 192 | /* Put result in desired memory area. */ |
267 | { | 193 | return sha1_finish_ctx (&ctx, resblock); |
268 | temp = SHA1CircularShift(5,A) + | 194 | } |
269 | ((B & C) | ((~B) & D)) + E + W[t] + K[0]; | ||
270 | E = D; | ||
271 | D = C; | ||
272 | C = SHA1CircularShift(30,B); | ||
273 | B = A; | ||
274 | A = temp; | ||
275 | } | ||
276 | 195 | ||
277 | for(t = 20; t < 40; t++) | 196 | void |
197 | sha1_process_bytes (const void *buffer, size_t len, struct sha1_ctx *ctx) | ||
198 | { | ||
199 | /* When we already have some bits in our internal buffer concatenate | ||
200 | both inputs first. */ | ||
201 | if (ctx->buflen != 0) | ||
278 | { | 202 | { |
279 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1]; | 203 | size_t left_over = ctx->buflen; |
280 | E = D; | 204 | size_t add = 128 - left_over > len ? len : 128 - left_over; |
281 | D = C; | 205 | |
282 | C = SHA1CircularShift(30,B); | 206 | memcpy (&((char *) ctx->buffer)[left_over], buffer, add); |
283 | B = A; | 207 | ctx->buflen += add; |
284 | A = temp; | 208 | |
209 | if (ctx->buflen > 64) | ||
210 | { | ||
211 | sha1_process_block (ctx->buffer, ctx->buflen & ~63, ctx); | ||
212 | |||
213 | ctx->buflen &= 63; | ||
214 | /* The regions in the following copy operation cannot overlap. */ | ||
215 | memcpy (ctx->buffer, | ||
216 | &((char *) ctx->buffer)[(left_over + add) & ~63], | ||
217 | ctx->buflen); | ||
218 | } | ||
219 | |||
220 | buffer = (const char *) buffer + add; | ||
221 | len -= add; | ||
285 | } | 222 | } |
286 | 223 | ||
287 | for(t = 40; t < 60; t++) | 224 | /* Process available complete blocks. */ |
225 | if (len >= 64) | ||
288 | { | 226 | { |
289 | temp = SHA1CircularShift(5,A) + | 227 | #if !_STRING_ARCH_unaligned |
290 | ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; | 228 | # define alignof(type) offsetof (struct { char c; type x; }, x) |
291 | E = D; | 229 | # define UNALIGNED_P(p) (((size_t) p) % alignof (uint32_t) != 0) |
292 | D = C; | 230 | if (UNALIGNED_P (buffer)) |
293 | C = SHA1CircularShift(30,B); | 231 | while (len > 64) |
294 | B = A; | 232 | { |
295 | A = temp; | 233 | sha1_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); |
234 | buffer = (const char *) buffer + 64; | ||
235 | len -= 64; | ||
236 | } | ||
237 | else | ||
238 | #endif | ||
239 | { | ||
240 | sha1_process_block (buffer, len & ~63, ctx); | ||
241 | buffer = (const char *) buffer + (len & ~63); | ||
242 | len &= 63; | ||
243 | } | ||
296 | } | 244 | } |
297 | 245 | ||
298 | for(t = 60; t < 80; t++) | 246 | /* Move remaining bytes in internal buffer. */ |
247 | if (len > 0) | ||
299 | { | 248 | { |
300 | temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3]; | 249 | size_t left_over = ctx->buflen; |
301 | E = D; | 250 | |
302 | D = C; | 251 | memcpy (&((char *) ctx->buffer)[left_over], buffer, len); |
303 | C = SHA1CircularShift(30,B); | 252 | left_over += len; |
304 | B = A; | 253 | if (left_over >= 64) |
305 | A = temp; | 254 | { |
255 | sha1_process_block (ctx->buffer, 64, ctx); | ||
256 | left_over -= 64; | ||
257 | memcpy (ctx->buffer, &ctx->buffer[16], left_over); | ||
258 | } | ||
259 | ctx->buflen = left_over; | ||
306 | } | 260 | } |
261 | } | ||
307 | 262 | ||
308 | context->Intermediate_Hash[0] += A; | 263 | /* --- Code below is the primary difference between md5.c and sha1.c --- */ |
309 | context->Intermediate_Hash[1] += B; | ||
310 | context->Intermediate_Hash[2] += C; | ||
311 | context->Intermediate_Hash[3] += D; | ||
312 | context->Intermediate_Hash[4] += E; | ||
313 | 264 | ||
314 | context->Message_Block_Index = 0; | 265 | /* SHA1 round constants */ |
315 | } | 266 | #define K1 0x5a827999 |
267 | #define K2 0x6ed9eba1 | ||
268 | #define K3 0x8f1bbcdc | ||
269 | #define K4 0xca62c1d6 | ||
270 | |||
271 | /* Round functions. Note that F2 is the same as F4. */ | ||
272 | #define F1(B,C,D) ( D ^ ( B & ( C ^ D ) ) ) | ||
273 | #define F2(B,C,D) (B ^ C ^ D) | ||
274 | #define F3(B,C,D) ( ( B & C ) | ( D & ( B | C ) ) ) | ||
275 | #define F4(B,C,D) (B ^ C ^ D) | ||
316 | 276 | ||
277 | /* Process LEN bytes of BUFFER, accumulating context into CTX. | ||
278 | It is assumed that LEN % 64 == 0. | ||
279 | Most of this code comes from GnuPG's cipher/sha1.c. */ | ||
317 | 280 | ||
318 | /* | 281 | void |
319 | * SHA1PadMessage | 282 | sha1_process_block (const void *buffer, size_t len, struct sha1_ctx *ctx) |
320 | * | ||
321 | * Description: | ||
322 | * According to the standard, the message must be padded to an even | ||
323 | * 512 bits. The first padding bit must be a '1'. The last 64 | ||
324 | * bits represent the length of the original message. All bits in | ||
325 | * between should be 0. This function will pad the message | ||
326 | * according to those rules by filling the Message_Block array | ||
327 | * accordingly. It will also call the ProcessMessageBlock function | ||
328 | * provided appropriately. When it returns, it can be assumed that | ||
329 | * the message digest has been computed. | ||
330 | * | ||
331 | * Parameters: | ||
332 | * context: [in/out] | ||
333 | * The context to pad | ||
334 | * ProcessMessageBlock: [in] | ||
335 | * The appropriate SHA*ProcessMessageBlock function | ||
336 | * Returns: | ||
337 | * Nothing. | ||
338 | * | ||
339 | */ | ||
340 | |||
341 | void SHA1PadMessage(SHA1Context *context) | ||
342 | { | 283 | { |
343 | /* | 284 | const uint32_t *words = buffer; |
344 | * Check to see if the current message block is too small to hold | 285 | size_t nwords = len / sizeof (uint32_t); |
345 | * the initial padding bits and length. If so, we will pad the | 286 | const uint32_t *endp = words + nwords; |
346 | * block, process it, and then continue padding into a second | 287 | uint32_t x[16]; |
347 | * block. | 288 | uint32_t a = ctx->A; |
348 | */ | 289 | uint32_t b = ctx->B; |
349 | if (context->Message_Block_Index > 55) | 290 | uint32_t c = ctx->C; |
291 | uint32_t d = ctx->D; | ||
292 | uint32_t e = ctx->E; | ||
293 | |||
294 | /* First increment the byte count. RFC 1321 specifies the possible | ||
295 | length of the file up to 2^64 bits. Here we only compute the | ||
296 | number of bytes. Do a double word increment. */ | ||
297 | ctx->total[0] += len; | ||
298 | if (ctx->total[0] < len) | ||
299 | ++ctx->total[1]; | ||
300 | |||
301 | #define rol(x, n) (((x) << (n)) | ((uint32_t) (x) >> (32 - (n)))) | ||
302 | |||
303 | #define M(I) ( tm = x[I&0x0f] ^ x[(I-14)&0x0f] \ | ||
304 | ^ x[(I-8)&0x0f] ^ x[(I-3)&0x0f] \ | ||
305 | , (x[I&0x0f] = rol(tm, 1)) ) | ||
306 | |||
307 | #define R(A,B,C,D,E,F,K,M) do { E += rol( A, 5 ) \ | ||
308 | + F( B, C, D ) \ | ||
309 | + K \ | ||
310 | + M; \ | ||
311 | B = rol( B, 30 ); \ | ||
312 | } while(0) | ||
313 | |||
314 | while (words < endp) | ||
350 | { | 315 | { |
351 | context->Message_Block[context->Message_Block_Index++] = 0x80; | 316 | uint32_t tm; |
352 | while(context->Message_Block_Index < 64) | 317 | int t; |
353 | { | 318 | for (t = 0; t < 16; t++) |
354 | context->Message_Block[context->Message_Block_Index++] = 0; | 319 | { |
355 | } | 320 | x[t] = SWAP (*words); |
356 | 321 | words++; | |
357 | SHA1ProcessMessageBlock(context); | 322 | } |
358 | 323 | ||
359 | while(context->Message_Block_Index < 56) | 324 | R( a, b, c, d, e, F1, K1, x[ 0] ); |
360 | { | 325 | R( e, a, b, c, d, F1, K1, x[ 1] ); |
361 | context->Message_Block[context->Message_Block_Index++] = 0; | 326 | R( d, e, a, b, c, F1, K1, x[ 2] ); |
362 | } | 327 | R( c, d, e, a, b, F1, K1, x[ 3] ); |
328 | R( b, c, d, e, a, F1, K1, x[ 4] ); | ||
329 | R( a, b, c, d, e, F1, K1, x[ 5] ); | ||
330 | R( e, a, b, c, d, F1, K1, x[ 6] ); | ||
331 | R( d, e, a, b, c, F1, K1, x[ 7] ); | ||
332 | R( c, d, e, a, b, F1, K1, x[ 8] ); | ||
333 | R( b, c, d, e, a, F1, K1, x[ 9] ); | ||
334 | R( a, b, c, d, e, F1, K1, x[10] ); | ||
335 | R( e, a, b, c, d, F1, K1, x[11] ); | ||
336 | R( d, e, a, b, c, F1, K1, x[12] ); | ||
337 | R( c, d, e, a, b, F1, K1, x[13] ); | ||
338 | R( b, c, d, e, a, F1, K1, x[14] ); | ||
339 | R( a, b, c, d, e, F1, K1, x[15] ); | ||
340 | R( e, a, b, c, d, F1, K1, M(16) ); | ||
341 | R( d, e, a, b, c, F1, K1, M(17) ); | ||
342 | R( c, d, e, a, b, F1, K1, M(18) ); | ||
343 | R( b, c, d, e, a, F1, K1, M(19) ); | ||
344 | R( a, b, c, d, e, F2, K2, M(20) ); | ||
345 | R( e, a, b, c, d, F2, K2, M(21) ); | ||
346 | R( d, e, a, b, c, F2, K2, M(22) ); | ||
347 | R( c, d, e, a, b, F2, K2, M(23) ); | ||
348 | R( b, c, d, e, a, F2, K2, M(24) ); | ||
349 | R( a, b, c, d, e, F2, K2, M(25) ); | ||
350 | R( e, a, b, c, d, F2, K2, M(26) ); | ||
351 | R( d, e, a, b, c, F2, K2, M(27) ); | ||
352 | R( c, d, e, a, b, F2, K2, M(28) ); | ||
353 | R( b, c, d, e, a, F2, K2, M(29) ); | ||
354 | R( a, b, c, d, e, F2, K2, M(30) ); | ||
355 | R( e, a, b, c, d, F2, K2, M(31) ); | ||
356 | R( d, e, a, b, c, F2, K2, M(32) ); | ||
357 | R( c, d, e, a, b, F2, K2, M(33) ); | ||
358 | R( b, c, d, e, a, F2, K2, M(34) ); | ||
359 | R( a, b, c, d, e, F2, K2, M(35) ); | ||
360 | R( e, a, b, c, d, F2, K2, M(36) ); | ||
361 | R( d, e, a, b, c, F2, K2, M(37) ); | ||
362 | R( c, d, e, a, b, F2, K2, M(38) ); | ||
363 | R( b, c, d, e, a, F2, K2, M(39) ); | ||
364 | R( a, b, c, d, e, F3, K3, M(40) ); | ||
365 | R( e, a, b, c, d, F3, K3, M(41) ); | ||
366 | R( d, e, a, b, c, F3, K3, M(42) ); | ||
367 | R( c, d, e, a, b, F3, K3, M(43) ); | ||
368 | R( b, c, d, e, a, F3, K3, M(44) ); | ||
369 | R( a, b, c, d, e, F3, K3, M(45) ); | ||
370 | R( e, a, b, c, d, F3, K3, M(46) ); | ||
371 | R( d, e, a, b, c, F3, K3, M(47) ); | ||
372 | R( c, d, e, a, b, F3, K3, M(48) ); | ||
373 | R( b, c, d, e, a, F3, K3, M(49) ); | ||
374 | R( a, b, c, d, e, F3, K3, M(50) ); | ||
375 | R( e, a, b, c, d, F3, K3, M(51) ); | ||
376 | R( d, e, a, b, c, F3, K3, M(52) ); | ||
377 | R( c, d, e, a, b, F3, K3, M(53) ); | ||
378 | R( b, c, d, e, a, F3, K3, M(54) ); | ||
379 | R( a, b, c, d, e, F3, K3, M(55) ); | ||
380 | R( e, a, b, c, d, F3, K3, M(56) ); | ||
381 | R( d, e, a, b, c, F3, K3, M(57) ); | ||
382 | R( c, d, e, a, b, F3, K3, M(58) ); | ||
383 | R( b, c, d, e, a, F3, K3, M(59) ); | ||
384 | R( a, b, c, d, e, F4, K4, M(60) ); | ||
385 | R( e, a, b, c, d, F4, K4, M(61) ); | ||
386 | R( d, e, a, b, c, F4, K4, M(62) ); | ||
387 | R( c, d, e, a, b, F4, K4, M(63) ); | ||
388 | R( b, c, d, e, a, F4, K4, M(64) ); | ||
389 | R( a, b, c, d, e, F4, K4, M(65) ); | ||
390 | R( e, a, b, c, d, F4, K4, M(66) ); | ||
391 | R( d, e, a, b, c, F4, K4, M(67) ); | ||
392 | R( c, d, e, a, b, F4, K4, M(68) ); | ||
393 | R( b, c, d, e, a, F4, K4, M(69) ); | ||
394 | R( a, b, c, d, e, F4, K4, M(70) ); | ||
395 | R( e, a, b, c, d, F4, K4, M(71) ); | ||
396 | R( d, e, a, b, c, F4, K4, M(72) ); | ||
397 | R( c, d, e, a, b, F4, K4, M(73) ); | ||
398 | R( b, c, d, e, a, F4, K4, M(74) ); | ||
399 | R( a, b, c, d, e, F4, K4, M(75) ); | ||
400 | R( e, a, b, c, d, F4, K4, M(76) ); | ||
401 | R( d, e, a, b, c, F4, K4, M(77) ); | ||
402 | R( c, d, e, a, b, F4, K4, M(78) ); | ||
403 | R( b, c, d, e, a, F4, K4, M(79) ); | ||
404 | |||
405 | a = ctx->A += a; | ||
406 | b = ctx->B += b; | ||
407 | c = ctx->C += c; | ||
408 | d = ctx->D += d; | ||
409 | e = ctx->E += e; | ||
363 | } | 410 | } |
364 | else | ||
365 | { | ||
366 | context->Message_Block[context->Message_Block_Index++] = 0x80; | ||
367 | while(context->Message_Block_Index < 56) | ||
368 | { | ||
369 | context->Message_Block[context->Message_Block_Index++] = 0; | ||
370 | } | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * Store the message length as the last 8 octets | ||
375 | */ | ||
376 | context->Message_Block[56] = context->Length_High >> 24; | ||
377 | context->Message_Block[57] = context->Length_High >> 16; | ||
378 | context->Message_Block[58] = context->Length_High >> 8; | ||
379 | context->Message_Block[59] = context->Length_High; | ||
380 | context->Message_Block[60] = context->Length_Low >> 24; | ||
381 | context->Message_Block[61] = context->Length_Low >> 16; | ||
382 | context->Message_Block[62] = context->Length_Low >> 8; | ||
383 | context->Message_Block[63] = context->Length_Low; | ||
384 | |||
385 | SHA1ProcessMessageBlock(context); | ||
386 | } | 411 | } |
387 | #define SHA_DIGESTSIZE 20 | ||
388 | 412 | ||
389 | #define SHA_BLOCKSIZE 64 | 413 | /* memxor.c -- perform binary exclusive OR operation of two memory blocks. |
414 | Copyright (C) 2005, 2006 Free Software Foundation, Inc. | ||
390 | 415 | ||
391 | /* Function to compute the digest */ | 416 | This program is free software; you can redistribute it and/or modify |
392 | void | 417 | it under the terms of the GNU General Public License as published by |
393 | hmac_sha(unsigned char* k, /* secret key */ | 418 | the Free Software Foundation; either version 2, or (at your option) |
394 | int lk, /* length of the key in bytes */ | 419 | any later version. |
395 | unsigned char* d, /* data */ | 420 | |
396 | int ld, /* length of data in bytes */ | 421 | This program is distributed in the hope that it will be useful, |
397 | unsigned char* out, /* output buffer, at least "t" bytes */ | 422 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
398 | int t) | 423 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
424 | GNU General Public License for more details. | ||
425 | |||
426 | You should have received a copy of the GNU General Public License | ||
427 | along with this program; if not, write to the Free Software Foundation, | ||
428 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
429 | |||
430 | /* Written by Simon Josefsson. The interface was inspired by memxor | ||
431 | in Niels Möller's Nettle. */ | ||
432 | |||
433 | void * | ||
434 | memxor (void * dest, const void * src, size_t n) | ||
399 | { | 435 | { |
400 | SHA1Context ictx, octx ; | 436 | char const *s = src; |
401 | unsigned char isha[SHA_DIGESTSIZE], osha[SHA_DIGESTSIZE] ; | 437 | char *d = dest; |
402 | unsigned char key[SHA_DIGESTSIZE] ; | ||
403 | unsigned char buf[SHA_BLOCKSIZE] ; | ||
404 | int i ; | ||
405 | 438 | ||
406 | if (lk > SHA_BLOCKSIZE) { | 439 | for (; n > 0; n--) |
440 | *d++ ^= *s++; | ||
407 | 441 | ||
408 | SHA1Context tctx ; | 442 | return dest; |
443 | } | ||
409 | 444 | ||
410 | SHA1Reset(&tctx) ; | 445 | /* hmac-sha1.c -- hashed message authentication codes |
411 | SHA1Input(&tctx, k, lk) ; | 446 | Copyright (C) 2005, 2006 Free Software Foundation, Inc. |
412 | SHA1Result(&tctx, key) ; | ||
413 | 447 | ||
414 | k = key ; | 448 | This program is free software; you can redistribute it and/or modify |
415 | lk = SHA_DIGESTSIZE ; | 449 | it under the terms of the GNU General Public License as published by |
416 | } | 450 | the Free Software Foundation; either version 2, or (at your option) |
451 | any later version. | ||
417 | 452 | ||
418 | /**** Inner Digest ****/ | 453 | This program is distributed in the hope that it will be useful, |
454 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
455 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
456 | GNU General Public License for more details. | ||
419 | 457 | ||
420 | SHA1Reset(&ictx) ; | 458 | You should have received a copy of the GNU General Public License |
459 | along with this program; if not, write to the Free Software Foundation, | ||
460 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
421 | 461 | ||
422 | /* Pad the key for inner digest */ | 462 | /* Written by Simon Josefsson. */ |
423 | for (i = 0 ; i < lk ; ++i) | ||
424 | buf[i] = k[i] ^ 0x36 ; | ||
425 | 463 | ||
426 | for (i = lk ; i < SHA_BLOCKSIZE ; ++i) | 464 | #define IPAD 0x36 |
427 | buf[i] = 0x36 ; | 465 | #define OPAD 0x5c |
466 | |||
467 | int | ||
468 | hmac_sha1 (const void *key, size_t keylen, | ||
469 | const void *in, size_t inlen, void *resbuf) | ||
470 | { | ||
471 | struct sha1_ctx inner; | ||
472 | struct sha1_ctx outer; | ||
473 | char optkeybuf[20]; | ||
474 | char block[64]; | ||
475 | char innerhash[20]; | ||
476 | |||
477 | /* Reduce the key's size, so that it becomes <= 64 bytes large. */ | ||
478 | |||
479 | if (keylen > 64) | ||
480 | { | ||
481 | struct sha1_ctx keyhash; | ||
482 | |||
483 | sha1_init_ctx (&keyhash); | ||
484 | sha1_process_bytes (key, keylen, &keyhash); | ||
485 | sha1_finish_ctx (&keyhash, optkeybuf); | ||
486 | |||
487 | key = optkeybuf; | ||
488 | keylen = 20; | ||
489 | } | ||
428 | 490 | ||
429 | SHA1Input(&ictx, buf, SHA_BLOCKSIZE) ; | 491 | /* Compute INNERHASH from KEY and IN. */ |
430 | SHA1Input(&ictx, d, ld) ; | ||
431 | 492 | ||
432 | SHA1Result(&ictx, isha) ; | 493 | sha1_init_ctx (&inner); |
433 | 494 | ||
434 | /**** Outter Digest ****/ | 495 | memset (block, IPAD, sizeof (block)); |
496 | memxor (block, key, keylen); | ||
435 | 497 | ||
436 | SHA1Reset(&octx) ; | 498 | sha1_process_block (block, 64, &inner); |
499 | sha1_process_bytes (in, inlen, &inner); | ||
437 | 500 | ||
438 | /* Pad the key for outter digest */ | 501 | sha1_finish_ctx (&inner, innerhash); |
439 | 502 | ||
503 | /* Compute result from KEY and INNERHASH. */ | ||
440 | 504 | ||
441 | for (i = 0 ; i < lk ; ++i) buf[i] = k[i] ^ 0x5C ; | 505 | sha1_init_ctx (&outer); |
442 | for (i = lk ; i < SHA_BLOCKSIZE ; ++i) buf[i] = 0x5C ; | ||
443 | 506 | ||
444 | SHA1Input(&octx, buf, SHA_BLOCKSIZE) ; | 507 | memset (block, OPAD, sizeof (block)); |
445 | SHA1Input(&octx, isha, SHA_DIGESTSIZE) ; | 508 | memxor (block, key, keylen); |
446 | 509 | ||
447 | SHA1Result(&octx, osha) ; | 510 | sha1_process_block (block, 64, &outer); |
511 | sha1_process_bytes (innerhash, 20, &outer); | ||
448 | 512 | ||
449 | /* truncate the results */ | 513 | sha1_finish_ctx (&outer, resbuf); |
450 | t = t > SHA_DIGESTSIZE ? SHA_DIGESTSIZE : t ; | ||
451 | memcpy(out, osha, t); | ||
452 | 514 | ||
515 | return 0; | ||
453 | } | 516 | } |
diff --git a/tools/hmac-sha1.h b/tools/hmac-sha1.h index e5be1cfc38..b3969d6148 100644 --- a/tools/hmac-sha1.h +++ b/tools/hmac-sha1.h | |||
@@ -1,77 +1,123 @@ | |||
1 | /* | 1 | /* Taken from gnulib (http://savannah.gnu.org/projects/gnulib/) */ |
2 | * sha1.h | 2 | /* Declarations of functions and data types used for SHA1 sum |
3 | * | 3 | library functions. |
4 | * Description: | 4 | Copyright (C) 2000, 2001, 2003, 2005, 2006 Free Software Foundation, Inc. |
5 | * This is the header file for code which implements the Secure | ||
6 | * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published | ||
7 | * April 17, 1995. | ||
8 | * | ||
9 | * Many of the variable names in this code, especially the | ||
10 | * single character names, were used because those were the names | ||
11 | * used in the publication. | ||
12 | * | ||
13 | * Please read the file sha1.c for more information. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #ifndef _SHA1_H_ | ||
18 | #define _SHA1_H_ | ||
19 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | ||
7 | under the terms of the GNU General Public License as published by the | ||
8 | Free Software Foundation; either version 2, or (at your option) any | ||
9 | later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but 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 this program; if not, write to the Free Software Foundation, | ||
18 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
19 | |||
20 | #ifndef SHA1_H | ||
21 | #define SHA1_H 1 | ||
22 | |||
23 | #include <stdio.h> | ||
20 | #include <stdint.h> | 24 | #include <stdint.h> |
21 | /* | 25 | |
22 | * If you do not have the ISO standard stdint.h header file, then you | 26 | /* Structure to save state of computation between the single steps. */ |
23 | * must typdef the following: | 27 | struct sha1_ctx |
24 | * name meaning | ||
25 | * uint32_t unsigned 32 bit integer | ||
26 | * uint8_t unsigned 8 bit integer (i.e., unsigned char) | ||
27 | * int_least16_t integer of >= 16 bits | ||
28 | * | ||
29 | */ | ||
30 | |||
31 | #ifndef _SHA_enum_ | ||
32 | #define _SHA_enum_ | ||
33 | enum | ||
34 | { | 28 | { |
35 | shaSuccess = 0, | 29 | uint32_t A; |
36 | shaNull, /* Null pointer parameter */ | 30 | uint32_t B; |
37 | shaInputTooLong, /* input data too long */ | 31 | uint32_t C; |
38 | shaStateError /* called Input after Result */ | 32 | uint32_t D; |
33 | uint32_t E; | ||
34 | |||
35 | uint32_t total[2]; | ||
36 | uint32_t buflen; | ||
37 | uint32_t buffer[32]; | ||
39 | }; | 38 | }; |
40 | #endif | ||
41 | #define SHA1HashSize 20 | ||
42 | 39 | ||
43 | /* | ||
44 | * This structure will hold context information for the SHA-1 | ||
45 | * hashing operation | ||
46 | */ | ||
47 | typedef struct SHA1Context | ||
48 | { | ||
49 | uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ | ||
50 | 40 | ||
51 | uint32_t Length_Low; /* Message length in bits */ | 41 | /* Initialize structure containing state of computation. */ |
52 | uint32_t Length_High; /* Message length in bits */ | 42 | extern void sha1_init_ctx (struct sha1_ctx *ctx); |
43 | |||
44 | /* Starting with the result of former calls of this function (or the | ||
45 | initialization function update the context for the next LEN bytes | ||
46 | starting at BUFFER. | ||
47 | It is necessary that LEN is a multiple of 64!!! */ | ||
48 | extern void sha1_process_block (const void *buffer, size_t len, | ||
49 | struct sha1_ctx *ctx); | ||
50 | |||
51 | /* Starting with the result of former calls of this function (or the | ||
52 | initialization function update the context for the next LEN bytes | ||
53 | starting at BUFFER. | ||
54 | It is NOT required that LEN is a multiple of 64. */ | ||
55 | extern void sha1_process_bytes (const void *buffer, size_t len, | ||
56 | struct sha1_ctx *ctx); | ||
57 | |||
58 | /* Process the remaining bytes in the buffer and put result from CTX | ||
59 | in first 20 bytes following RESBUF. The result is always in little | ||
60 | endian byte order, so that a byte-wise output yields to the wanted | ||
61 | ASCII representation of the message digest. | ||
62 | |||
63 | IMPORTANT: On some systems it is required that RESBUF be correctly | ||
64 | aligned for a 32 bits value. */ | ||
65 | extern void *sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf); | ||
53 | 66 | ||
54 | /* Index into message block array */ | ||
55 | int_least16_t Message_Block_Index; | ||
56 | uint8_t Message_Block[64]; /* 512-bit message blocks */ | ||
57 | 67 | ||
58 | int Computed; /* Is the digest computed? */ | 68 | /* Put result from CTX in first 20 bytes following RESBUF. The result is |
59 | int Corrupted; /* Is the message digest corrupted? */ | 69 | always in little endian byte order, so that a byte-wise output yields |
60 | } SHA1Context; | 70 | to the wanted ASCII representation of the message digest. |
61 | 71 | ||
62 | /* | 72 | IMPORTANT: On some systems it is required that RESBUF is correctly |
63 | * Function Prototypes | 73 | aligned for a 32 bits value. */ |
64 | */ | 74 | extern void *sha1_read_ctx (const struct sha1_ctx *ctx, void *resbuf); |
65 | 75 | ||
66 | int SHA1Reset( SHA1Context *); | ||
67 | int SHA1Input( SHA1Context *, | ||
68 | const uint8_t *, | ||
69 | unsigned int); | ||
70 | int SHA1Result( SHA1Context *, | ||
71 | uint8_t Message_Digest[SHA1HashSize]); | ||
72 | 76 | ||
73 | void hmac_sha(unsigned char* k, int lk, | 77 | /* Compute SHA1 message digest for bytes read from STREAM. The |
74 | unsigned char* d, int ld, | 78 | resulting message digest number will be written into the 20 bytes |
75 | unsigned char* out, int t); | 79 | beginning at RESBLOCK. */ |
80 | extern int sha1_stream (FILE *stream, void *resblock); | ||
81 | |||
82 | /* Compute SHA1 message digest for LEN bytes beginning at BUFFER. The | ||
83 | result is always in little endian byte order, so that a byte-wise | ||
84 | output yields to the wanted ASCII representation of the message | ||
85 | digest. */ | ||
86 | extern void *sha1_buffer (const char *buffer, size_t len, void *resblock); | ||
76 | 87 | ||
77 | #endif | 88 | #endif |
89 | |||
90 | |||
91 | /* hmac.h -- hashed message authentication codes | ||
92 | Copyright (C) 2005 Free Software Foundation, Inc. | ||
93 | |||
94 | This program is free software; you can redistribute it and/or modify | ||
95 | it under the terms of the GNU General Public License as published by | ||
96 | the Free Software Foundation; either version 2, or (at your option) | ||
97 | any later version. | ||
98 | |||
99 | This program is distributed in the hope that it will be useful, | ||
100 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
101 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
102 | GNU General Public License for more details. | ||
103 | |||
104 | You should have received a copy of the GNU General Public License | ||
105 | along with this program; if not, write to the Free Software Foundation, | ||
106 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ | ||
107 | |||
108 | /* Written by Simon Josefsson. */ | ||
109 | |||
110 | #ifndef HMAC_H | ||
111 | #define HMAC_H 1 | ||
112 | |||
113 | #include <stddef.h> | ||
114 | |||
115 | /* Compute Hashed Message Authentication Code with SHA-1, over BUFFER | ||
116 | data of BUFLEN bytes using the KEY of KEYLEN bytes, writing the | ||
117 | output to pre-allocated 20 byte minimum RESBUF buffer. Return 0 on | ||
118 | success. */ | ||
119 | int | ||
120 | hmac_sha1 (const void *key, size_t keylen, | ||
121 | const void *in, size_t inlen, void *resbuf); | ||
122 | |||
123 | #endif /* HMAC_H */ | ||