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