]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Universal/Network/IScsiDxe/Md5.c
44aceaeafa3cd23df7c8d7cf7733375b0675bcd7
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / Md5.c
1 /*++
2
3 Copyright (c) 2004 - 2007, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13
14 Md5.c
15
16 Abstract:
17
18 Implementation of MD5 algorithm
19
20 --*/
21
22 #include "Md5.h"
23
24 STATIC CONST UINT32 MD5_K[][2] = {
25 { 0, 1 },
26 { 1, 5 },
27 { 5, 3 },
28 { 0, 7 }
29 };
30
31 STATIC CONST UINT32 MD5_S[][4] = {
32 { 7, 22, 17, 12 },
33 { 5, 20, 14, 9 },
34 { 4, 23, 16 ,11 },
35 { 6, 21, 15, 10 },
36 };
37
38 STATIC CONST UINT32 MD5_T[] = {
39 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE,
40 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501,
41 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE,
42 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821,
43 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA,
44 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8,
45 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED,
46 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A,
47 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C,
48 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,
49 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05,
50 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665,
51 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039,
52 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1,
53 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1,
54 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391
55 };
56
57 STATIC CONST UINT8 Md5HashPadding[] =
58 {
59 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
63 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
64 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
75 };
76
77 //
78 // ROTATE_LEFT rotates x left n bits.
79 //
80 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
81
82 #define SA S[j & 3]
83 #define SB S[(j + 1) & 3]
84 #define SC S[(j + 2) & 3]
85 #define SD S[(j + 3) & 3]
86
87 //
88 // TF1, TF2, TF3, TF4 are basic MD5 transform functions
89 //
90 UINT32 TF1 (UINT32 A, UINT32 B, UINT32 C)
91 {
92 return (A & B) | (~A & C);
93 }
94
95 UINT32 TF2 (UINT32 A, UINT32 B, UINT32 C)
96 {
97 return (A & C) | (B & ~C);
98 }
99
100 UINT32 TF3 (UINT32 A, UINT32 B, UINT32 C)
101 {
102 return A ^ B ^ C;
103 }
104
105 UINT32 TF4 (UINT32 A, UINT32 B, UINT32 C)
106 {
107 return B ^ (A | ~C);
108 }
109
110 typedef
111 UINT32
112 (*MD5_TRANSFORM_FUNC) (
113 IN UINT32 A,
114 IN UINT32 B,
115 IN UINT32 C
116 );
117
118 STATIC CONST MD5_TRANSFORM_FUNC MD5_F[] = {
119 TF1,
120 TF2,
121 TF3,
122 TF4
123 };
124
125 STATIC
126 VOID
127 MD5Transform (
128 IN MD5_CTX *Md5Ctx
129 )
130 /*++
131
132 Routine Description:
133
134 GC_TODO: Add function description
135
136 Arguments:
137
138 Md5Ctx - GC_TODO: add argument description
139
140 Returns:
141
142 GC_TODO: add return values
143
144 --*/
145 {
146 UINT32 i;
147 UINT32 j;
148 UINT32 S[MD5_HASHSIZE >> 2];
149 UINT32 *X;
150 UINT32 k;
151 UINT32 t;
152
153 X = (UINT32 *) Md5Ctx->M;
154
155 //
156 // Copy MD5 states to S
157 //
158 NetCopyMem (S, Md5Ctx->States, MD5_HASHSIZE);
159
160 t = 0;
161 for (i = 0; i < 4; i++) {
162 k = MD5_K[i][0];
163 for (j = 16; j > 0; j--) {
164 SA += (*MD5_F[i]) (SB, SC, SD) + X[k] + MD5_T[t];
165 SA = ROTATE_LEFT (SA, MD5_S[i][j & 3]);
166 SA += SB;
167
168 k += MD5_K[i][1];
169 k &= 15;
170
171 t++;
172 }
173 }
174
175 for (i = 0; i < 4; i++) {
176 Md5Ctx->States[i] += S[i];
177 }
178 }
179
180 STATIC
181 VOID
182 MD5UpdateBlock (
183 IN MD5_CTX *Md5Ctx,
184 IN CONST UINT8 *Data,
185 IN UINTN DataLen
186 )
187 /*++
188
189 Routine Description:
190
191 GC_TODO: Add function description
192
193 Arguments:
194
195 Md5Ctx - GC_TODO: add argument description
196 Data - GC_TODO: add argument description
197 DataLen - GC_TODO: add argument description
198
199 Returns:
200
201 GC_TODO: add return values
202
203 --*/
204 {
205 UINTN Limit;
206
207 for (Limit = 64 - Md5Ctx->Count; DataLen >= 64 - Md5Ctx->Count; Limit = 64) {
208 NetCopyMem (Md5Ctx->M + Md5Ctx->Count, (VOID *)Data, Limit);
209 MD5Transform (Md5Ctx);
210
211 Md5Ctx->Count = 0;
212 Data += Limit;
213 DataLen -= Limit;
214 }
215
216 NetCopyMem (Md5Ctx->M + Md5Ctx->Count, (VOID *)Data, DataLen);
217 Md5Ctx->Count += DataLen;
218 }
219
220 EFI_STATUS
221 MD5Init (
222 IN MD5_CTX *Md5Ctx
223 )
224 /*++
225
226 Routine Description:
227
228 GC_TODO: Add function description
229
230 Arguments:
231
232 Md5Ctx - GC_TODO: add argument description
233
234 Returns:
235
236 EFI_SUCCESS - GC_TODO: Add description for return value
237
238 --*/
239 {
240 NetZeroMem (Md5Ctx, sizeof (*Md5Ctx));
241
242 //
243 // Set magic initialization constants.
244 //
245 Md5Ctx->States[0] = 0x67452301;
246 Md5Ctx->States[1] = 0xefcdab89;
247 Md5Ctx->States[2] = 0x98badcfe;
248 Md5Ctx->States[3] = 0x10325476;
249
250 return EFI_SUCCESS;
251 }
252
253 EFI_STATUS
254 MD5Update (
255 IN MD5_CTX *Md5Ctx,
256 IN VOID *Data,
257 IN UINTN DataLen
258 )
259 /*++
260
261 Routine Description:
262
263 GC_TODO: Add function description
264
265 Arguments:
266
267 Md5Ctx - GC_TODO: add argument description
268 Data - GC_TODO: add argument description
269 DataLen - GC_TODO: add argument description
270
271 Returns:
272
273 EFI_SUCCESS - GC_TODO: Add description for return value
274
275 --*/
276 {
277 if (EFI_ERROR (Md5Ctx->Status)) {
278 return Md5Ctx->Status;
279 }
280
281 MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) Data, DataLen);
282 Md5Ctx->Length += DataLen;
283 return EFI_SUCCESS;
284 }
285
286 EFI_STATUS
287 MD5Final (
288 IN MD5_CTX *Md5Ctx,
289 OUT UINT8 *HashVal
290 )
291 /*++
292
293 Routine Description:
294
295 GC_TODO: Add function description
296
297 Arguments:
298
299 Md5Ctx - GC_TODO: add argument description
300 HashVal - GC_TODO: add argument description
301
302 Returns:
303
304 EFI_SUCCESS - GC_TODO: Add description for return value
305
306 --*/
307 {
308 UINTN PadLength;
309
310 if (Md5Ctx->Status == EFI_ALREADY_STARTED) {
311 //
312 // Store Hashed value & Zeroize sensitive context information.
313 //
314 NetCopyMem (HashVal, (UINT8 *) Md5Ctx->States, MD5_HASHSIZE);
315 NetZeroMem ((UINT8 *)Md5Ctx, sizeof (*Md5Ctx));
316
317 return EFI_SUCCESS;
318 }
319
320 if (EFI_ERROR (Md5Ctx->Status)) {
321 return Md5Ctx->Status;
322 }
323
324 PadLength = Md5Ctx->Count >= 56 ? 120 : 56;
325 PadLength -= Md5Ctx->Count;
326 MD5UpdateBlock (Md5Ctx, Md5HashPadding, PadLength);
327 Md5Ctx->Length = LShiftU64 (Md5Ctx->Length, 3);
328 MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) &Md5Ctx->Length, 8);
329
330 NetZeroMem (Md5Ctx->M, sizeof (Md5Ctx->M));
331 Md5Ctx->Length = 0;
332 Md5Ctx->Status = EFI_ALREADY_STARTED;
333 return MD5Final (Md5Ctx, HashVal);
334 }
335