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