2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
12 * Licensed Materials - Property of Transarc
14 * For copyright information, see IPL which you accepted in order to
15 * download this software.
17 * COMPONENT_NAME: nsafs
19 * ORIGINS: Transarc Corp.
25 * Revision 1.1 1998/04/07 17:51:02
26 * User space cache manager and netscape plugin
28 * Revision 1.2 1998/01/31 20:55:31
29 * Port of AFS client to user space. This delta replaces the previous
30 * delta, which had too many merge problems after I tried to change
31 * some of the files back to their originals after the review.
33 * Revision 1.1 1998/01/23 20:36:14
34 * Implemented login cache, cleaned up some bugs, and added
35 * directory index generation.
39 * This module implements the Secure Hash Algorithm (SHA) as specified in
40 * the Secure Hash Standard (SHS, FIPS PUB 180.1).
43 #include "../afs/param.h" /* Should be always first */
44 #include "../afs/sysincludes.h" /* Standard vendor system headers */
46 #include "../afs/afsincludes.h" /* Afs-based standard headers */
47 #include "../afs/afs_stats.h"
48 #include "../afs/auth.h"
49 #include "../afs/cellconfig.h"
50 #include "../afs/vice.h"
51 #include "../afs/nsafs.h"
53 static int big_endian;
55 static const sha_int hashinit[] = {
56 0x67452301, 0xEFCDAB89, 0x98BADCFE,
57 0x10325476, 0xC3D2E1F0
60 #define ROTL(n, x) (((x) << (n)) | ((x) >> (SHA_BITS_PER_INT - (n))))
62 #ifdef DISABLED_CODE_HERE
63 static sha_int f(int t, sha_int x, sha_int y, sha_int z)
65 if (t < 0 || t >= SHA_ROUNDS) return 0;
67 return (z ^ (x & (y ^ z)));
71 return ((x & y) | (z & (x | y))); /* saves 1 boolean op */
72 return (x ^ y ^ z); /* 60-79 same as 40-59 */
76 /* This is the "magic" function used for each round. */
77 /* Were this a C function, the interface would be: */
78 /* static sha_int f(int t, sha_int x, sha_int y, sha_int z) */
79 /* The function call version preserved above until stable */
81 #define f_a(x, y, z) (z ^ (x & (y ^ z)))
82 #define f_b(x, y, z) (x ^ y ^ z)
83 #define f_c(x, y, z) (( (x & y) | (z & (x | y))))
85 #define f(t, x, y, z) \
86 ( (t < 0 || t >= SHA_ROUNDS) ? 0 : \
87 ( (t < 20) ? f_a(x, y, z) : \
88 ( (t < 40) ? f_b(x, y, z) : \
89 ( (t < 60) ? f_c(x, y, z) : f_b(x, y, z)))))
92 *static sha_int K(int t)
94 * if (t < 0 || t >= SHA_ROUNDS) return 0;
105 /* This macro/function supplies the "magic" constant for each round. */
106 /* The function call version preserved above until stable */
108 static const sha_int k_vals[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6};
110 #define K(t) ( (t < 0 || t >= SHA_ROUNDS) ? 0 : k_vals[ t/20 ] )
113 * Update the internal state based on the given chunk.
115 static void transform(shaState *shaStateP, sha_int *chunk)
117 sha_int A = shaStateP->digest[0];
118 sha_int B = shaStateP->digest[1];
119 sha_int C = shaStateP->digest[2];
120 sha_int D = shaStateP->digest[3];
121 sha_int E = shaStateP->digest[4];
125 sha_int W[SHA_ROUNDS];
127 for (t = 0; t < SHA_CHUNK_INTS; t++)
129 for (; t < SHA_ROUNDS; t++) {
130 TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
131 W[t] = ROTL(1, TEMP);
134 for (t = 0; t < SHA_ROUNDS; t++) {
135 TEMP = ROTL(5, A) + f(t, B, C, D) + E + W[t] + K(t);
136 E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
139 shaStateP->digest[0] += A;
140 shaStateP->digest[1] += B;
141 shaStateP->digest[2] += C;
142 shaStateP->digest[3] += D;
143 shaStateP->digest[4] += E;
148 * This function takes an array of SHA_CHUNK_BYTES bytes
149 * as input and produces an output array of ints that is
150 * SHA_CHUNK_INTS long.
152 static void buildInts(const char *data, sha_int *chunk)
155 * Need to copy the data because we can't be certain that
156 * the input buffer will be aligned correctly.
158 memcpy((void *)chunk, (void *)data, SHA_CHUNK_BYTES);
161 /* This loop does nothing but waste time on a big endian machine. */
164 for (i = 0; i < SHA_CHUNK_INTS; i++)
165 chunk[i] = ntohl(chunk[i]);
170 * This function updates the internal state of the hash by using
171 * buildInts to break the input up into chunks and repeatedly passing
172 * these chunks to transform().
174 void sha_update(shaState *shaStateP, const char *buffer, int bufferLen)
177 sha_int chunk[SHA_CHUNK_INTS];
180 if (buffer == NULL || bufferLen == 0)
183 newLo = shaStateP->bitcountLo + (bufferLen << 3);
184 if (newLo < shaStateP->bitcountLo)
185 shaStateP->bitcountHi++;
186 shaStateP->bitcountLo = newLo;
187 shaStateP->bitcountHi += ((bufferLen >> (SHA_BITS_PER_INT - 3)) & 0x07);
190 * If we won't have enough for a full chunk, just tack this
191 * buffer onto the leftover piece and return.
193 if (shaStateP->leftoverLen + bufferLen < SHA_CHUNK_BYTES) {
194 memcpy((void *)&(shaStateP->leftover[shaStateP->leftoverLen]),
195 (void *)buffer, bufferLen);
196 shaStateP->leftoverLen += bufferLen;
200 /* If we have a leftover chunk, process it first. */
201 if (shaStateP->leftoverLen > 0) {
202 i = (SHA_CHUNK_BYTES - shaStateP->leftoverLen);
203 memcpy((void *)&(shaStateP->leftover[shaStateP->leftoverLen]),
207 buildInts(shaStateP->leftover, chunk);
208 shaStateP->leftoverLen = 0;
209 transform(shaStateP, chunk);
212 while (bufferLen >= SHA_CHUNK_BYTES) {
213 buildInts(buffer, chunk);
214 transform(shaStateP, chunk);
215 buffer += SHA_CHUNK_BYTES;
216 bufferLen -= SHA_CHUNK_BYTES;
218 assert((bufferLen >= 0) && (bufferLen < SHA_CHUNK_BYTES));
221 memcpy((void *)&shaStateP->leftover[0], (void *)buffer, bufferLen);
222 shaStateP->leftoverLen = bufferLen;
228 * This method updates the internal state of the hash using
229 * any leftover data plus appropriate padding and incorporation
230 * of the hash bitcount to finish the hash. The hash value
231 * is not valid until finish() has been called.
233 void sha_finish(shaState *shaStateP)
235 sha_int chunk[SHA_CHUNK_INTS];
238 if (shaStateP->leftoverLen > (SHA_CHUNK_BYTES - 9)) {
239 shaStateP->leftover[shaStateP->leftoverLen++] = 0x80;
240 memset(&(shaStateP->leftover[shaStateP->leftoverLen]), 0,
241 (SHA_CHUNK_BYTES - shaStateP->leftoverLen));
242 buildInts(shaStateP->leftover, chunk);
243 transform(shaStateP, chunk);
244 memset(chunk, 0, SHA_CHUNK_BYTES);
246 shaStateP->leftover[shaStateP->leftoverLen++] = 0x80;
247 memset(&(shaStateP->leftover[shaStateP->leftoverLen]), 0,
248 (SHA_CHUNK_BYTES - shaStateP->leftoverLen));
249 buildInts(shaStateP->leftover, chunk);
251 shaStateP->leftoverLen = 0;
253 chunk[SHA_CHUNK_INTS - 2] = shaStateP->bitcountHi;
254 chunk[SHA_CHUNK_INTS - 1] = shaStateP->bitcountLo;
255 transform(shaStateP, chunk);
260 * Initialize the hash to its "magic" initial value specified by the
261 * SHS standard, and clear out the bitcount and leftover vars.
262 * This should be used to initialize an shaState.
264 void sha_clear(shaState *shaStateP)
266 big_endian = (0x01020304 == htonl(0x01020304));
268 memcpy((void *)&shaStateP->digest[0], (void *)&hashinit[0], SHA_HASH_BYTES);
269 shaStateP->bitcountLo = shaStateP->bitcountHi = 0;
270 shaStateP->leftoverLen = 0;
275 * Hash the buffer and place the result in *shaStateP.
277 void sha_hash(shaState *shaStateP, const char *buffer, int bufferLen)
279 sha_clear(shaStateP);
280 sha_update(shaStateP, buffer, bufferLen);
281 sha_finish(shaStateP);
286 * Returns the current state of the hash as an array of 20 bytes.
287 * This will be an interim result if finish() has not yet been called.
289 void sha_bytes(const shaState *shaStateP, char *bytes)
291 sha_int temp[SHA_HASH_INTS];
294 for (i = 0; i < SHA_HASH_INTS; i++)
295 temp[i] = htonl(shaStateP->digest[i]);
296 memcpy(bytes, (void *)&temp[0], SHA_HASH_BYTES);