3 This file is part of the ARM-Crypto-Lib.
4 Copyright (C) 2006-2010 Daniel Otte (daniel.otte@rub.de)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
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.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
27 * \brief SHA-256 implementation.
33 #include <string.h> /* for memcpy, memmove, memset */
38 #if defined LITTLE_ENDIAN
39 #elif defined BIG_ENDIAN
41 #error specify endianess!!!
45 /*************************************************************************/
48 uint32_t sha256_init_vector[]={
49 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
50 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
53 /*************************************************************************/
56 * \brief \c sh256_init initialises a sha256 context for hashing.
57 * \c sh256_init c initialises the given sha256 context for hashing
58 * @param state pointer to a sha256 context
61 void sha256_init(sha256_ctx_t *state){
63 memcpy(state->h, sha256_init_vector, 8*4);
66 /*************************************************************************/
69 * rotate x right by n positions
72 uint32_t rotr32( uint32_t x, uint8_t n){
73 return ((x>>n) | (x<<(32-n)));
77 uint32_t rotl32( uint32_t x, uint8_t n){
78 return ((x<<n) | (x>>(32-n)));
81 /*************************************************************************/
83 // #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
85 uint32_t change_endian32(uint32_t x){
86 return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
90 /*************************************************************************/
92 /* sha256 functions as macros for speed and size, cause they are called only once */
94 #define CH(x,y,z) (((x)&(y)) ^ ((~(x))&(z)))
95 #define MAJ(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
97 #define SIGMA0(x) (rotr32((x),2) ^ rotr32((x),13) ^ rotl32((x),10))
98 #define SIGMA1(x) (rotr32((x),6) ^ rotr32((x),11) ^ rotl32((x),7))
99 #define SIGMA_a(x) (rotr32((x),7) ^ rotl32((x),14) ^ ((x)>>3))
100 #define SIGMA_b(x) (rotl32((x),15) ^ rotl32((x),13) ^ ((x)>>10))
104 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
105 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
106 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
107 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
108 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
109 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
110 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
111 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
115 /*************************************************************************/
118 * block must be, 512, Bit = 64, Byte, long !!!
120 void sha256_nextBlock (sha256_ctx_t *state, const void* block){
121 uint32_t w[64]; /* this is 256, byte, large, */
126 #if defined LITTLE_ENDIAN
127 for (i=0; i<16; ++i){
128 w[i]= change_endian32(((uint32_t*)block)[i]);
130 #elif defined BIG_ENDIAN
131 memcpy((void*)w, block, 64);
133 for (i=16; i<64; ++i){
134 w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];
137 /* init working variables */
138 memcpy((void*)a,(void*)(state->h), 8*4);
140 /* do the, fun stuff, */
141 for (i=0; i<64; ++i){
142 t1 = a[7] + SIGMA1(a[4]) + CH(a[4],a[5],a[6]) + k[i] + w[i];
143 t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]);
144 memmove(&(a[1]), &(a[0]), 7*4); /* a[7]=a[6]; a[6]=a[5]; a[5]=a[4]; a[4]=a[3]; a[3]=a[2]; a[2]=a[1]; a[1]=a[0]; */
149 /* update, the, state, */
153 state->length += 512;
157 /*************************************************************************/
160 * \brief function to process the last block being hashed
161 * @param state Pointer to the context in which this block should be processed.
162 * @param block Pointer to the message wich should be hashed.
163 * @param length is the length of only THIS block in BITS not in bytes!
164 * bits are big endian, meaning high bits come first.
165 * if you have a message with bits at the end, the byte must be padded with zeros
167 void sha256_lastBlock(sha256_ctx_t *state, const void* block, uint16_t length){
168 uint8_t lb[SHA256_BLOCK_BITS/8]; /* local block */
169 while(length>=SHA256_BLOCK_BITS){
170 sha256_nextBlock(state, block);
171 length -= SHA256_BLOCK_BITS;
172 block = (uint8_t*)block+SHA256_BLOCK_BYTES;
175 state->length += length;
176 memcpy (&(lb[0]), block, length/8);
178 /* set the final one bit */
179 if (length & 0x7){ // if we have single bits at the end
180 lb[length/8] = ((uint8_t*)(block))[length/8];
184 lb[length/8] |= 0x80>>(length & 0x7);
185 length =(length >> 3) + 1; /* from now on length contains the number of BYTES in lb*/
187 if (length>64-8){ /* not enouth space for 64bit length value */
188 memset((void*)(&(lb[length])), 0, 64-length);
189 sha256_nextBlock(state, lb);
190 state->length -= 512;
193 memset((void*)(&(lb[length])), 0, 56-length);
194 /* store the 64bit length value */
195 #if defined LITTLE_ENDIAN
196 /* this is now rolled up */
198 for (i=1; i<=8; ++i){
199 lb[55+i] = (uint8_t)(state->length>>(64- 8*i));
201 #elif defined BIG_ENDIAN
202 *((uint64_t)&(lb[56])) = state->length;
204 sha256_nextBlock(state, lb);
208 /*************************************************************************/
213 void sha256(sha256_hash_t *dest, const void* msg, uint32_t length){ /* length could be choosen longer but this is for µC */
216 while(length >= SHA256_BLOCK_BITS){
217 sha256_nextBlock(&s, msg);
218 msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
219 length -= SHA256_BLOCK_BITS;
221 sha256_lastBlock(&s, msg, length);
222 sha256_ctx2hash(dest,&s);
227 /*************************************************************************/
229 void sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state){
230 #if defined LITTLE_ENDIAN
233 ((uint32_t*)dest)[i] = change_endian32(state->h[i]);
236 if (dest != state->h)
237 memcpy(dest, state->h, SHA256_HASH_BITS/8);
239 # error unsupported endian type!