source: UsbWattMeter/trunk/wolfssl-3.7.0/wolfcrypt/src/md4.c@ 164

Last change on this file since 164 was 164, checked in by coas-nagasima, 7 years ago

TOPPERS/ECNLサンプルアプリ「USB充電器電力計」を追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 5.8 KB
Line 
1/* md4.c
2 *
3 * Copyright (C) 2006-2015 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL. (formerly known as CyaSSL)
6 *
7 * wolfSSL 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 * wolfSSL 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#ifdef HAVE_CONFIG_H
23 #include <config.h>
24#endif
25
26#include <wolfssl/wolfcrypt/settings.h>
27
28#ifndef NO_MD4
29
30#include <wolfssl/wolfcrypt/md4.h>
31#ifdef NO_INLINE
32 #include <wolfssl/wolfcrypt/misc.h>
33#else
34 #include <wolfcrypt/src/misc.c>
35#endif
36
37
38#ifdef min
39#define WOLFSSL_HAVE_MIN
40#endif
41#ifndef WOLFSSL_HAVE_MIN
42#define WOLFSSL_HAVE_MIN
43
44 static INLINE word32 min(word32 a, word32 b)
45 {
46 return a > b ? b : a;
47 }
48
49#endif /* WOLFSSL_HAVE_MIN */
50
51
52void wc_InitMd4(Md4* md4)
53{
54 md4->digest[0] = 0x67452301L;
55 md4->digest[1] = 0xefcdab89L;
56 md4->digest[2] = 0x98badcfeL;
57 md4->digest[3] = 0x10325476L;
58
59 md4->buffLen = 0;
60 md4->loLen = 0;
61 md4->hiLen = 0;
62}
63
64
65static void Transform(Md4* md4)
66{
67#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
68#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
69#define H(x, y, z) ((x) ^ (y) ^ (z))
70
71 /* Copy context->state[] to working vars */
72 word32 A = md4->digest[0];
73 word32 B = md4->digest[1];
74 word32 C = md4->digest[2];
75 word32 D = md4->digest[3];
76
77#define function(a,b,c,d,k,s) a=rotlFixed(a+F(b,c,d)+md4->buffer[k],s);
78 function(A,B,C,D, 0, 3);
79 function(D,A,B,C, 1, 7);
80 function(C,D,A,B, 2,11);
81 function(B,C,D,A, 3,19);
82 function(A,B,C,D, 4, 3);
83 function(D,A,B,C, 5, 7);
84 function(C,D,A,B, 6,11);
85 function(B,C,D,A, 7,19);
86 function(A,B,C,D, 8, 3);
87 function(D,A,B,C, 9, 7);
88 function(C,D,A,B,10,11);
89 function(B,C,D,A,11,19);
90 function(A,B,C,D,12, 3);
91 function(D,A,B,C,13, 7);
92 function(C,D,A,B,14,11);
93 function(B,C,D,A,15,19);
94
95#undef function
96#define function(a,b,c,d,k,s) \
97 a=rotlFixed(a+G(b,c,d)+md4->buffer[k]+0x5a827999,s);
98
99 function(A,B,C,D, 0, 3);
100 function(D,A,B,C, 4, 5);
101 function(C,D,A,B, 8, 9);
102 function(B,C,D,A,12,13);
103 function(A,B,C,D, 1, 3);
104 function(D,A,B,C, 5, 5);
105 function(C,D,A,B, 9, 9);
106 function(B,C,D,A,13,13);
107 function(A,B,C,D, 2, 3);
108 function(D,A,B,C, 6, 5);
109 function(C,D,A,B,10, 9);
110 function(B,C,D,A,14,13);
111 function(A,B,C,D, 3, 3);
112 function(D,A,B,C, 7, 5);
113 function(C,D,A,B,11, 9);
114 function(B,C,D,A,15,13);
115
116#undef function
117#define function(a,b,c,d,k,s) \
118 a=rotlFixed(a+H(b,c,d)+md4->buffer[k]+0x6ed9eba1,s);
119
120 function(A,B,C,D, 0, 3);
121 function(D,A,B,C, 8, 9);
122 function(C,D,A,B, 4,11);
123 function(B,C,D,A,12,15);
124 function(A,B,C,D, 2, 3);
125 function(D,A,B,C,10, 9);
126 function(C,D,A,B, 6,11);
127 function(B,C,D,A,14,15);
128 function(A,B,C,D, 1, 3);
129 function(D,A,B,C, 9, 9);
130 function(C,D,A,B, 5,11);
131 function(B,C,D,A,13,15);
132 function(A,B,C,D, 3, 3);
133 function(D,A,B,C,11, 9);
134 function(C,D,A,B, 7,11);
135 function(B,C,D,A,15,15);
136
137 /* Add the working vars back into digest state[] */
138 md4->digest[0] += A;
139 md4->digest[1] += B;
140 md4->digest[2] += C;
141 md4->digest[3] += D;
142}
143
144
145static INLINE void AddLength(Md4* md4, word32 len)
146{
147 word32 tmp = md4->loLen;
148 if ( (md4->loLen += len) < tmp)
149 md4->hiLen++; /* carry low to high */
150}
151
152
153void wc_Md4Update(Md4* md4, const byte* data, word32 len)
154{
155 /* do block size increments */
156 byte* local = (byte*)md4->buffer;
157
158 while (len) {
159 word32 add = min(len, MD4_BLOCK_SIZE - md4->buffLen);
160 XMEMCPY(&local[md4->buffLen], data, add);
161
162 md4->buffLen += add;
163 data += add;
164 len -= add;
165
166 if (md4->buffLen == MD4_BLOCK_SIZE) {
167 #ifdef BIG_ENDIAN_ORDER
168 ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);
169 #endif
170 Transform(md4);
171 AddLength(md4, MD4_BLOCK_SIZE);
172 md4->buffLen = 0;
173 }
174 }
175}
176
177
178void wc_Md4Final(Md4* md4, byte* hash)
179{
180 byte* local = (byte*)md4->buffer;
181
182 AddLength(md4, md4->buffLen); /* before adding pads */
183
184 local[md4->buffLen++] = 0x80; /* add 1 */
185
186 /* pad with zeros */
187 if (md4->buffLen > MD4_PAD_SIZE) {
188 XMEMSET(&local[md4->buffLen], 0, MD4_BLOCK_SIZE - md4->buffLen);
189 md4->buffLen += MD4_BLOCK_SIZE - md4->buffLen;
190
191 #ifdef BIG_ENDIAN_ORDER
192 ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);
193 #endif
194 Transform(md4);
195 md4->buffLen = 0;
196 }
197 XMEMSET(&local[md4->buffLen], 0, MD4_PAD_SIZE - md4->buffLen);
198
199 /* put lengths in bits */
200 md4->hiLen = (md4->loLen >> (8*sizeof(md4->loLen) - 3)) +
201 (md4->hiLen << 3);
202 md4->loLen = md4->loLen << 3;
203
204 /* store lengths */
205 #ifdef BIG_ENDIAN_ORDER
206 ByteReverseWords(md4->buffer, md4->buffer, MD4_BLOCK_SIZE);
207 #endif
208 /* ! length ordering dependent on digest endian type ! */
209 XMEMCPY(&local[MD4_PAD_SIZE], &md4->loLen, sizeof(word32));
210 XMEMCPY(&local[MD4_PAD_SIZE + sizeof(word32)], &md4->hiLen, sizeof(word32));
211
212 Transform(md4);
213 #ifdef BIG_ENDIAN_ORDER
214 ByteReverseWords(md4->digest, md4->digest, MD4_DIGEST_SIZE);
215 #endif
216 XMEMCPY(hash, md4->digest, MD4_DIGEST_SIZE);
217
218 wc_InitMd4(md4); /* reset state */
219}
220
221
222#endif /* NO_MD4 */
223
Note: See TracBrowser for help on using the repository browser.