]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/CyaSSL/ctaocrypt/src/md4.c
Commit 3 RX100 low power demos.
[freertos] / FreeRTOS-Plus / CyaSSL / ctaocrypt / src / md4.c
1 /* md4.c
2  *
3  * Copyright (C) 2006-2012 Sawtooth Consulting Ltd.
4  *
5  * This file is part of CyaSSL.
6  *
7  * CyaSSL is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * CyaSSL is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #ifdef HAVE_CONFIG_H
23     #include <config.h>
24 #endif
25
26
27 #ifndef NO_MD4
28
29 #include <cyassl/ctaocrypt/md4.h>
30 #ifdef NO_INLINE
31     #include <cyassl/ctaocrypt/misc.h>
32 #else
33     #include <ctaocrypt/src/misc.c>
34 #endif
35
36
37 #ifndef min
38
39     static INLINE word32 min(word32 a, word32 b)
40     {
41         return a > b ? b : a;
42     }
43
44 #endif /* min */
45
46
47 void InitMd4(Md4* md4)
48 {
49     md4->digest[0] = 0x67452301L;
50     md4->digest[1] = 0xefcdab89L;
51     md4->digest[2] = 0x98badcfeL;
52     md4->digest[3] = 0x10325476L;
53
54     md4->buffLen = 0;
55     md4->loLen   = 0;
56     md4->hiLen   = 0;
57 }
58
59
60 static void Transform(Md4* md4)
61 {
62 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
63 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
64 #define H(x, y, z) ((x) ^ (y) ^ (z))
65
66     /* Copy context->state[] to working vars  */
67     word32 A = md4->digest[0];
68     word32 B = md4->digest[1];
69     word32 C = md4->digest[2];
70     word32 D = md4->digest[3];
71
72 #define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s);
73     function(A,B,C,D, 0, 3);
74     function(D,A,B,C, 1, 7);
75     function(C,D,A,B, 2,11);
76     function(B,C,D,A, 3,19);
77     function(A,B,C,D, 4, 3);
78     function(D,A,B,C, 5, 7);
79     function(C,D,A,B, 6,11);
80     function(B,C,D,A, 7,19);
81     function(A,B,C,D, 8, 3);
82     function(D,A,B,C, 9, 7);
83     function(C,D,A,B,10,11);
84     function(B,C,D,A,11,19);
85     function(A,B,C,D,12, 3);
86     function(D,A,B,C,13, 7);
87     function(C,D,A,B,14,11);
88     function(B,C,D,A,15,19);
89
90 #undef function   
91 #define function(a,b,c,d,k,s) \
92     a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s);
93
94     function(A,B,C,D, 0, 3);
95     function(D,A,B,C, 4, 5);
96     function(C,D,A,B, 8, 9);
97     function(B,C,D,A,12,13);
98     function(A,B,C,D, 1, 3);
99     function(D,A,B,C, 5, 5);
100     function(C,D,A,B, 9, 9);
101     function(B,C,D,A,13,13);
102     function(A,B,C,D, 2, 3);
103     function(D,A,B,C, 6, 5);
104     function(C,D,A,B,10, 9);
105     function(B,C,D,A,14,13);
106     function(A,B,C,D, 3, 3);
107     function(D,A,B,C, 7, 5);
108     function(C,D,A,B,11, 9);
109     function(B,C,D,A,15,13);
110
111 #undef function  
112 #define function(a,b,c,d,k,s) \
113     a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s);
114
115     function(A,B,C,D, 0, 3);
116     function(D,A,B,C, 8, 9);
117     function(C,D,A,B, 4,11);
118     function(B,C,D,A,12,15);
119     function(A,B,C,D, 2, 3);
120     function(D,A,B,C,10, 9);
121     function(C,D,A,B, 6,11);
122     function(B,C,D,A,14,15);
123     function(A,B,C,D, 1, 3);
124     function(D,A,B,C, 9, 9);
125     function(C,D,A,B, 5,11);
126     function(B,C,D,A,13,15);
127     function(A,B,C,D, 3, 3);
128     function(D,A,B,C,11, 9);
129     function(C,D,A,B, 7,11);
130     function(B,C,D,A,15,15);
131     
132     /* Add the working vars back into digest state[]  */
133     md4->digest[0] += A;
134     md4->digest[1] += B;
135     md4->digest[2] += C;
136     md4->digest[3] += D;
137 }
138
139
140 static INLINE void AddLength(Md4* md4, word32 len)
141 {
142     word32 tmp = md4->loLen;
143     if ( (md4->loLen += len) < tmp)
144         md4->hiLen++;                       /* carry low to high */
145 }
146
147
148 void Md4Update(Md4* md4, const byte* data, word32 len)
149 {
150     /* do block size increments */
151     byte* local = (byte*)md4->buffer;
152
153     while (len) {
154         word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen);
155         XMEMCPY(&local[md4->buffLen], data, add);
156
157         md4->buffLen += add;
158         data         += add;
159         len          -= add;
160
161         if (md4->buffLen == MD4_BLOCK_SIZE) {
162             #ifdef BIG_ENDIAN_ORDER
163                 ByteReverseBytes(local, local, MD4_BLOCK_SIZE);
164             #endif
165             Transform(md4);
166             AddLength(md4, MD4_BLOCK_SIZE);
167             md4->buffLen = 0;
168         }
169     }
170 }
171
172
173 void Md4Final(Md4* md4, byte* hash)
174 {
175     byte* local = (byte*)md4->buffer;
176
177     AddLength(md4, md4->buffLen);               /* before adding pads */
178
179     local[md4->buffLen++] = 0x80;  /* add 1 */
180
181     /* pad with zeros */
182     if (md4->buffLen > MD4_PAD_SIZE) {
183         XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen);
184         md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen;
185
186         #ifdef BIG_ENDIAN_ORDER
187             ByteReverseBytes(local, local, MD4_BLOCK_SIZE);
188         #endif
189         Transform(md4);
190         md4->buffLen = 0;
191     }
192     XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen);
193    
194     /* put lengths in bits */
195     md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) + 
196                  (md4->hiLen << 3);
197     md4->loLen = md4->loLen << 3;
198
199     /* store lengths */
200     #ifdef BIG_ENDIAN_ORDER
201         ByteReverseBytes(local, local, MD4_BLOCK_SIZE);
202     #endif
203     /* ! length ordering dependent on digest endian type ! */
204     XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32));
205     XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32));
206
207     Transform(md4);
208     #ifdef BIG_ENDIAN_ORDER
209         ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE);
210     #endif
211     XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE);
212
213     InitMd4(md4);  /* reset state */
214 }
215
216
217 #endif /* NO_MD4 */
218