]> git.cryptolib.org Git - arm-crypto-lib.git/blob - sha256/sha256.c
added arcfour/rc4
[arm-crypto-lib.git] / sha256 / sha256.c
1 /* sha256.c */
2 /*
3     This file is part of the ARM-Crypto-Lib.
4     Copyright (C) 2006-2010  Daniel Otte (daniel.otte@rub.de)
5
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.
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, see <http://www.gnu.org/licenses/>.
18 */
19 /**
20  * \file                sha256.c
21  * \author              Daniel Otte
22  * \date                16.05.2006
23  *
24  * \par License:
25  *      GPL
26  *
27  * \brief SHA-256 implementation.
28  *
29  *
30  */
31
32 #include <stdint.h>
33 #include <string.h> /* for memcpy, memmove, memset */
34 #include "sha256.h"
35
36 #define LITTLE_ENDIAN
37
38 #if defined LITTLE_ENDIAN
39 #elif defined BIG_ENDIAN
40 #else
41         #error specify endianess!!!
42 #endif
43
44
45 /*************************************************************************/
46
47 const
48 uint32_t sha256_init_vector[]={
49         0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
50     0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 };
51
52
53 /*************************************************************************/
54
55 /**
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
59  * @return none
60  */
61 void sha256_init(sha256_ctx_t *state){
62         state->length=0;
63         memcpy(state->h, sha256_init_vector, 8*4);
64 }
65
66 /*************************************************************************/
67
68 /**
69  * rotate x right by n positions
70  */
71 uint32_t rotr32( uint32_t x, uint8_t n){
72         return ((x>>n) | (x<<(32-n)));
73 }
74
75
76 /*************************************************************************/
77
78 // #define CHANGE_ENDIAN32(x) (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8))
79
80 uint32_t change_endian32(uint32_t x){
81         return (((x)<<24) | ((x)>>24) | (((x)& 0x0000ff00)<<8) | (((x)& 0x00ff0000)>>8));
82 }
83
84
85 /*************************************************************************/
86
87 /* sha256 functions as macros for speed and size, cause they are called only once */
88
89 #define CH(x,y,z)  (((x)&(y)) ^ ((~(x))&(z)))
90 #define MAJ(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
91
92 #define SIGMA0(x) (rotr32((x),2) ^ rotr32((x),13) ^ rotr32((x),22))
93 #define SIGMA1(x) (rotr32((x),6) ^ rotr32((x),11) ^ rotr32((x),25))
94 #define SIGMA_a(x) (rotr32((x),7)  ^ rotr32((x),18) ^ ((x)>>3))
95 #define SIGMA_b(x) (rotr32((x),17) ^ rotr32((x),19) ^ ((x)>>10))
96
97 const
98 uint32_t k[]={
99         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
100         0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
101         0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
102         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
103         0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
104         0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
105         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
106         0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
107 };
108
109
110 /*************************************************************************/
111
112 /**
113  * block must be, 512, Bit = 64, Byte, long !!!
114  */
115 void sha256_nextBlock (sha256_ctx_t *state, const void* block){
116         uint32_t w[64]; /* this is 256, byte, large, */
117         uint8_t  i;
118         uint32_t a[8],t1,t2;
119
120         /* init w */
121 #if defined LITTLE_ENDIAN
122                 for (i=0; i<16; ++i){
123                         w[i]= change_endian32(((uint32_t*)block)[i]);
124                 }
125 #elif defined BIG_ENDIAN
126                 memcpy((void*)w, block, 64);
127 #endif
128                 for (i=16; i<64; ++i){
129                         w[i] = SIGMA_b(w[i-2]) + w[i-7] + SIGMA_a(w[i-15]) + w[i-16];
130                 }
131
132         /* init working variables */
133                 memcpy((void*)a,(void*)(state->h), 8*4);
134
135         /* do the, fun stuff, */
136                 for (i=0; i<64; ++i){
137                         t1 = a[7] + SIGMA1(a[4]) + CH(a[4],a[5],a[6]) + k[i] + w[i];
138                         t2 = SIGMA0(a[0]) + MAJ(a[0],a[1],a[2]);
139                         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]; */
140                         a[4] += t1;
141                         a[0] = t1 + t2;
142                 }
143
144         /* update, the, state, */
145                 for (i=0; i<8; ++i){
146                         state->h[i] += a[i];
147                 }
148                 state->length += 512;
149 }
150
151
152 /*************************************************************************/
153
154 /**
155  * \brief function to process the last block being hashed
156  * @param state Pointer to the context in which this block should be processed.
157  * @param block Pointer to the message wich should be hashed.
158  * @param length is the length of only THIS block in BITS not in bytes!
159  *  bits are big endian, meaning high bits come first.
160  *      if you have a message with bits at the end, the byte must be padded with zeros
161  */
162 void sha256_lastBlock(sha256_ctx_t *state, const void* block, uint16_t length){
163         uint8_t lb[SHA256_BLOCK_BITS/8]; /* local block */
164         while(length>=SHA256_BLOCK_BITS){
165                 sha256_nextBlock(state, block);
166                 length -= SHA256_BLOCK_BITS;
167                 block = (uint8_t*)block+SHA256_BLOCK_BYTES;
168         }
169
170         state->length += length;
171         memcpy (&(lb[0]), block, length/8);
172
173         /* set the final one bit */
174         if (length & 0x7){ // if we have single bits at the end
175                 lb[length/8] = ((uint8_t*)(block))[length/8];
176         } else {
177                 lb[length/8] = 0;
178         }
179         lb[length/8] |= 0x80>>(length & 0x7);
180         length =(length >> 3) + 1; /* from now on length contains the number of BYTES in lb*/
181         /* pad with zeros */
182         if (length>64-8){ /* not enouth space for 64bit length value */
183                 memset((void*)(&(lb[length])), 0, 64-length);
184                 sha256_nextBlock(state, lb);
185                 state->length -= 512;
186                 length = 0;
187         }
188         memset((void*)(&(lb[length])), 0, 56-length);
189         /* store the 64bit length value */
190 #if defined LITTLE_ENDIAN
191                 /* this is now rolled up */
192         uint8_t i;
193         for (i=1; i<=8; ++i){
194                 lb[55+i] = (uint8_t)(state->length>>(64- 8*i));
195         }
196 #elif defined BIG_ENDIAN
197         *((uint64_t)&(lb[56])) = state->length;
198 #endif
199         sha256_nextBlock(state, lb);
200 }
201
202
203 /*************************************************************************/
204
205 /*
206  * length in bits!
207  */
208 void sha256(sha256_hash_t *dest, const void* msg, uint32_t length){ /* length could be choosen longer but this is for µC */
209         sha256_ctx_t s;
210         sha256_init(&s);
211         while(length >= SHA256_BLOCK_BITS){
212                 sha256_nextBlock(&s, msg);
213                 msg = (uint8_t*)msg + SHA256_BLOCK_BITS/8;
214                 length -= SHA256_BLOCK_BITS;
215         }
216         sha256_lastBlock(&s, msg, length);
217         sha256_ctx2hash(dest,&s);
218 }
219
220
221
222 /*************************************************************************/
223
224 void sha256_ctx2hash(sha256_hash_t *dest, const sha256_ctx_t *state){
225 #if defined LITTLE_ENDIAN
226         uint8_t i;
227         for(i=0; i<8; ++i){
228                 ((uint32_t*)dest)[i] = change_endian32(state->h[i]);
229         }
230 #elif BIG_ENDIAN
231         if (dest != state->h)
232                 memcpy(dest, state->h, SHA256_HASH_BITS/8);
233 #else
234 # error unsupported endian type!
235 #endif
236 }
237
238