2 * SHA-256 hash implementation and interface functions
3 * Copyright (c) 2003-2007, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
27 static void sha256_init(struct sha256_state
*md
);
28 static int sha256_process(struct sha256_state
*md
, const unsigned char *in
,
30 static int sha256_done(struct sha256_state
*md
, unsigned char *out
);
34 * sha256_vector - SHA256 hash for data vector
35 * @num_elem: Number of elements in the data vector
36 * @addr: Pointers to the data areas
37 * @len: Lengths of the data blocks
38 * @mac: Buffer for the hash
39 * Returns: 0 on success, -1 of failure
41 int sha256_vector(size_t num_elem
, const u8
*addr
[], const size_t *len
,
44 struct sha256_state ctx
;
48 for (i
= 0; i
< num_elem
; i
++)
49 if (sha256_process(&ctx
, addr
[i
], len
[i
]))
51 if (sha256_done(&ctx
, mac
))
57 /* ===== start - public domain SHA256 implementation ===== */
59 /* This is based on SHA256 implementation in LibTomCrypt that was released into
60 * public domain by Tom St Denis. */
63 static const unsigned long K
[64] = {
64 0x428a2f98UL
, 0x71374491UL
, 0xb5c0fbcfUL
, 0xe9b5dba5UL
, 0x3956c25bUL
,
65 0x59f111f1UL
, 0x923f82a4UL
, 0xab1c5ed5UL
, 0xd807aa98UL
, 0x12835b01UL
,
66 0x243185beUL
, 0x550c7dc3UL
, 0x72be5d74UL
, 0x80deb1feUL
, 0x9bdc06a7UL
,
67 0xc19bf174UL
, 0xe49b69c1UL
, 0xefbe4786UL
, 0x0fc19dc6UL
, 0x240ca1ccUL
,
68 0x2de92c6fUL
, 0x4a7484aaUL
, 0x5cb0a9dcUL
, 0x76f988daUL
, 0x983e5152UL
,
69 0xa831c66dUL
, 0xb00327c8UL
, 0xbf597fc7UL
, 0xc6e00bf3UL
, 0xd5a79147UL
,
70 0x06ca6351UL
, 0x14292967UL
, 0x27b70a85UL
, 0x2e1b2138UL
, 0x4d2c6dfcUL
,
71 0x53380d13UL
, 0x650a7354UL
, 0x766a0abbUL
, 0x81c2c92eUL
, 0x92722c85UL
,
72 0xa2bfe8a1UL
, 0xa81a664bUL
, 0xc24b8b70UL
, 0xc76c51a3UL
, 0xd192e819UL
,
73 0xd6990624UL
, 0xf40e3585UL
, 0x106aa070UL
, 0x19a4c116UL
, 0x1e376c08UL
,
74 0x2748774cUL
, 0x34b0bcb5UL
, 0x391c0cb3UL
, 0x4ed8aa4aUL
, 0x5b9cca4fUL
,
75 0x682e6ff3UL
, 0x748f82eeUL
, 0x78a5636fUL
, 0x84c87814UL
, 0x8cc70208UL
,
76 0x90befffaUL
, 0xa4506cebUL
, 0xbef9a3f7UL
, 0xc67178f2UL
80 /* Various logical functions */
82 ( ((((unsigned long) (x) & 0xFFFFFFFFUL) >> (unsigned long) ((y) & 31)) | \
83 ((unsigned long) (x) << (unsigned long) (32 - ((y) & 31)))) & 0xFFFFFFFFUL)
84 #define Ch(x,y,z) (z ^ (x & (y ^ z)))
85 #define Maj(x,y,z) (((x | y) & z) | (x & y))
86 #define S(x, n) RORc((x), (n))
87 #define R(x, n) (((x)&0xFFFFFFFFUL)>>(n))
88 #define Sigma0(x) (S(x, 2) ^ S(x, 13) ^ S(x, 22))
89 #define Sigma1(x) (S(x, 6) ^ S(x, 11) ^ S(x, 25))
90 #define Gamma0(x) (S(x, 7) ^ S(x, 18) ^ R(x, 3))
91 #define Gamma1(x) (S(x, 17) ^ S(x, 19) ^ R(x, 10))
93 #define MIN(x, y) (((x) < (y)) ? (x) : (y))
96 /* compress 512-bits */
97 static int sha256_compress(struct sha256_state
*md
, unsigned char *buf
)
99 u32 S
[8], W
[64], t0
, t1
;
103 /* copy state into S */
104 for (i
= 0; i
< 8; i
++) {
108 /* copy the state into 512-bits into W[0..15] */
109 for (i
= 0; i
< 16; i
++)
110 W
[i
] = WPA_GET_BE32(buf
+ (4 * i
));
113 for (i
= 16; i
< 64; i
++) {
114 W
[i
] = Gamma1(W
[i
- 2]) + W
[i
- 7] + Gamma0(W
[i
- 15]) +
119 #define RND(a,b,c,d,e,f,g,h,i) \
120 t0 = h + Sigma1(e) + Ch(e, f, g) + K[i] + W[i]; \
121 t1 = Sigma0(a) + Maj(a, b, c); \
125 for (i
= 0; i
< 64; ++i
) {
126 RND(S
[0], S
[1], S
[2], S
[3], S
[4], S
[5], S
[6], S
[7], i
);
127 t
= S
[7]; S
[7] = S
[6]; S
[6] = S
[5]; S
[5] = S
[4];
128 S
[4] = S
[3]; S
[3] = S
[2]; S
[2] = S
[1]; S
[1] = S
[0]; S
[0] = t
;
132 for (i
= 0; i
< 8; i
++) {
133 md
->state
[i
] = md
->state
[i
] + S
[i
];
139 /* Initialize the hash state */
140 static void sha256_init(struct sha256_state
*md
)
144 md
->state
[0] = 0x6A09E667UL
;
145 md
->state
[1] = 0xBB67AE85UL
;
146 md
->state
[2] = 0x3C6EF372UL
;
147 md
->state
[3] = 0xA54FF53AUL
;
148 md
->state
[4] = 0x510E527FUL
;
149 md
->state
[5] = 0x9B05688CUL
;
150 md
->state
[6] = 0x1F83D9ABUL
;
151 md
->state
[7] = 0x5BE0CD19UL
;
155 Process a block of memory though the hash
156 @param md The hash state
157 @param in The data to hash
158 @param inlen The length of the data (octets)
159 @return CRYPT_OK if successful
161 static int sha256_process(struct sha256_state
*md
, const unsigned char *in
,
165 #define block_size 64
167 if (md
->curlen
> sizeof(md
->buf
))
171 if (md
->curlen
== 0 && inlen
>= block_size
) {
172 if (sha256_compress(md
, (unsigned char *) in
) < 0)
174 md
->length
+= block_size
* 8;
178 n
= MIN(inlen
, (block_size
- md
->curlen
));
179 os_memcpy(md
->buf
+ md
->curlen
, in
, n
);
183 if (md
->curlen
== block_size
) {
184 if (sha256_compress(md
, md
->buf
) < 0)
186 md
->length
+= 8 * block_size
;
197 Terminate the hash to get the digest
198 @param md The hash state
199 @param out [out] The destination of the hash (32 bytes)
200 @return CRYPT_OK if successful
202 static int sha256_done(struct sha256_state
*md
, unsigned char *out
)
206 if (md
->curlen
>= sizeof(md
->buf
))
209 /* increase the length of the message */
210 md
->length
+= md
->curlen
* 8;
212 /* append the '1' bit */
213 md
->buf
[md
->curlen
++] = (unsigned char) 0x80;
215 /* if the length is currently above 56 bytes we append zeros
216 * then compress. Then we can fall back to padding zeros and length
217 * encoding like normal.
219 if (md
->curlen
> 56) {
220 while (md
->curlen
< 64) {
221 md
->buf
[md
->curlen
++] = (unsigned char) 0;
223 sha256_compress(md
, md
->buf
);
227 /* pad upto 56 bytes of zeroes */
228 while (md
->curlen
< 56) {
229 md
->buf
[md
->curlen
++] = (unsigned char) 0;
233 WPA_PUT_BE64(md
->buf
+ 56, md
->length
);
234 sha256_compress(md
, md
->buf
);
237 for (i
= 0; i
< 8; i
++)
238 WPA_PUT_BE32(out
+ (4 * i
), md
->state
[i
]);
243 /* ===== end - public domain SHA256 implementation ===== */