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.
24 * This module implements the Secure Hash Algorithm (SHA) as specified in
25 * the Secure Hash Standard (SHS, FIPS PUB 180.1).
28 #include <afsconfig.h>
29 #include "../afs/param.h"
33 #include "../afs/sysincludes.h" /* Standard vendor system headers */
35 #include "../afs/afsincludes.h" /* Afs-based standard headers */
36 #include "../afs/afs_stats.h"
37 #include "../afs/auth.h"
38 #include "../afs/cellconfig.h"
39 #include "../afs/vice.h"
40 #include "../afs/nsafs.h"
42 static int big_endian;
44 static const sha_int hashinit[] = {
45 0x67452301, 0xEFCDAB89, 0x98BADCFE,
46 0x10325476, 0xC3D2E1F0
49 #define ROTL(n, x) (((x) << (n)) | ((x) >> (SHA_BITS_PER_INT - (n))))
51 #ifdef DISABLED_CODE_HERE
52 static sha_int f(int t, sha_int x, sha_int y, sha_int z)
54 if (t < 0 || t >= SHA_ROUNDS) return 0;
56 return (z ^ (x & (y ^ z)));
60 return ((x & y) | (z & (x | y))); /* saves 1 boolean op */
61 return (x ^ y ^ z); /* 60-79 same as 40-59 */
65 /* This is the "magic" function used for each round. */
66 /* Were this a C function, the interface would be: */
67 /* static sha_int f(int t, sha_int x, sha_int y, sha_int z) */
68 /* The function call version preserved above until stable */
70 #define f_a(x, y, z) (z ^ (x & (y ^ z)))
71 #define f_b(x, y, z) (x ^ y ^ z)
72 #define f_c(x, y, z) (( (x & y) | (z & (x | y))))
74 #define f(t, x, y, z) \
75 ( (t < 0 || t >= SHA_ROUNDS) ? 0 : \
76 ( (t < 20) ? f_a(x, y, z) : \
77 ( (t < 40) ? f_b(x, y, z) : \
78 ( (t < 60) ? f_c(x, y, z) : f_b(x, y, z)))))
81 *static sha_int K(int t)
83 * if (t < 0 || t >= SHA_ROUNDS) return 0;
94 /* This macro/function supplies the "magic" constant for each round. */
95 /* The function call version preserved above until stable */
97 static const sha_int k_vals[] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6};
99 #define K(t) ( (t < 0 || t >= SHA_ROUNDS) ? 0 : k_vals[ t/20 ] )
102 * Update the internal state based on the given chunk.
104 static void transform(shaState *shaStateP, sha_int *chunk)
106 sha_int A = shaStateP->digest[0];
107 sha_int B = shaStateP->digest[1];
108 sha_int C = shaStateP->digest[2];
109 sha_int D = shaStateP->digest[3];
110 sha_int E = shaStateP->digest[4];
114 sha_int W[SHA_ROUNDS];
116 for (t = 0; t < SHA_CHUNK_INTS; t++)
118 for (; t < SHA_ROUNDS; t++) {
119 TEMP = W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16];
120 W[t] = ROTL(1, TEMP);
123 for (t = 0; t < SHA_ROUNDS; t++) {
124 TEMP = ROTL(5, A) + f(t, B, C, D) + E + W[t] + K(t);
125 E = D; D = C; C = ROTL(30, B); B = A; A = TEMP;
128 shaStateP->digest[0] += A;
129 shaStateP->digest[1] += B;
130 shaStateP->digest[2] += C;
131 shaStateP->digest[3] += D;
132 shaStateP->digest[4] += E;
137 * This function takes an array of SHA_CHUNK_BYTES bytes
138 * as input and produces an output array of ints that is
139 * SHA_CHUNK_INTS long.
141 static void buildInts(const char *data, sha_int *chunk)
144 * Need to copy the data because we can't be certain that
145 * the input buffer will be aligned correctly.
147 memcpy((void *)chunk, (void *)data, SHA_CHUNK_BYTES);
150 /* This loop does nothing but waste time on a big endian machine. */
153 for (i = 0; i < SHA_CHUNK_INTS; i++)
154 chunk[i] = ntohl(chunk[i]);
159 * This function updates the internal state of the hash by using
160 * buildInts to break the input up into chunks and repeatedly passing
161 * these chunks to transform().
163 void sha_update(shaState *shaStateP, const char *buffer, int bufferLen)
166 sha_int chunk[SHA_CHUNK_INTS];
169 if (buffer == NULL || bufferLen == 0)
172 newLo = shaStateP->bitcountLo + (bufferLen << 3);
173 if (newLo < shaStateP->bitcountLo)
174 shaStateP->bitcountHi++;
175 shaStateP->bitcountLo = newLo;
176 shaStateP->bitcountHi += ((bufferLen >> (SHA_BITS_PER_INT - 3)) & 0x07);
179 * If we won't have enough for a full chunk, just tack this
180 * buffer onto the leftover piece and return.
182 if (shaStateP->leftoverLen + bufferLen < SHA_CHUNK_BYTES) {
183 memcpy((void *)&(shaStateP->leftover[shaStateP->leftoverLen]),
184 (void *)buffer, bufferLen);
185 shaStateP->leftoverLen += bufferLen;
189 /* If we have a leftover chunk, process it first. */
190 if (shaStateP->leftoverLen > 0) {
191 i = (SHA_CHUNK_BYTES - shaStateP->leftoverLen);
192 memcpy((void *)&(shaStateP->leftover[shaStateP->leftoverLen]),
196 buildInts(shaStateP->leftover, chunk);
197 shaStateP->leftoverLen = 0;
198 transform(shaStateP, chunk);
201 while (bufferLen >= SHA_CHUNK_BYTES) {
202 buildInts(buffer, chunk);
203 transform(shaStateP, chunk);
204 buffer += SHA_CHUNK_BYTES;
205 bufferLen -= SHA_CHUNK_BYTES;
207 assert((bufferLen >= 0) && (bufferLen < SHA_CHUNK_BYTES));
210 memcpy((void *)&shaStateP->leftover[0], (void *)buffer, bufferLen);
211 shaStateP->leftoverLen = bufferLen;
217 * This method updates the internal state of the hash using
218 * any leftover data plus appropriate padding and incorporation
219 * of the hash bitcount to finish the hash. The hash value
220 * is not valid until finish() has been called.
222 void sha_finish(shaState *shaStateP)
224 sha_int chunk[SHA_CHUNK_INTS];
227 if (shaStateP->leftoverLen > (SHA_CHUNK_BYTES - 9)) {
228 shaStateP->leftover[shaStateP->leftoverLen++] = 0x80;
229 memset(&(shaStateP->leftover[shaStateP->leftoverLen]), 0,
230 (SHA_CHUNK_BYTES - shaStateP->leftoverLen));
231 buildInts(shaStateP->leftover, chunk);
232 transform(shaStateP, chunk);
233 memset(chunk, 0, SHA_CHUNK_BYTES);
235 shaStateP->leftover[shaStateP->leftoverLen++] = 0x80;
236 memset(&(shaStateP->leftover[shaStateP->leftoverLen]), 0,
237 (SHA_CHUNK_BYTES - shaStateP->leftoverLen));
238 buildInts(shaStateP->leftover, chunk);
240 shaStateP->leftoverLen = 0;
242 chunk[SHA_CHUNK_INTS - 2] = shaStateP->bitcountHi;
243 chunk[SHA_CHUNK_INTS - 1] = shaStateP->bitcountLo;
244 transform(shaStateP, chunk);
249 * Initialize the hash to its "magic" initial value specified by the
250 * SHS standard, and clear out the bitcount and leftover vars.
251 * This should be used to initialize an shaState.
253 void sha_clear(shaState *shaStateP)
255 big_endian = (0x01020304 == htonl(0x01020304));
257 memcpy((void *)&shaStateP->digest[0], (void *)&hashinit[0], SHA_HASH_BYTES);
258 shaStateP->bitcountLo = shaStateP->bitcountHi = 0;
259 shaStateP->leftoverLen = 0;
264 * Hash the buffer and place the result in *shaStateP.
266 void sha_hash(shaState *shaStateP, const char *buffer, int bufferLen)
268 sha_clear(shaStateP);
269 sha_update(shaStateP, buffer, bufferLen);
270 sha_finish(shaStateP);
275 * Returns the current state of the hash as an array of 20 bytes.
276 * This will be an interim result if finish() has not yet been called.
278 void sha_bytes(const shaState *shaStateP, char *bytes)
280 sha_int temp[SHA_HASH_INTS];
283 for (i = 0; i < SHA_HASH_INTS; i++)
284 temp[i] = htonl(shaStateP->digest[i]);
285 memcpy(bytes, (void *)&temp[0], SHA_HASH_BYTES);