]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/IScsiDxe/Md5.c
MdeModulePkg: Clean up source files
[mirror_edk2.git] / MdeModulePkg / Universal / Network / IScsiDxe / Md5.c
CommitLineData
12618416 1/** @file\r
242354a2 2 Implementation of MD5 algorithm.\r
6a690e23 3\r
d1102dba 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
e5eed7d3 5This program and the accompanying materials\r
7a444476 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
12618416 13**/\r
6a690e23 14\r
15#include "Md5.h"\r
16\r
242354a2 17CONST UINT32 Md5_Data[][2] = {\r
6a690e23 18 { 0, 1 },\r
19 { 1, 5 },\r
20 { 5, 3 },\r
21 { 0, 7 }\r
22};\r
23\r
242354a2 24CONST UINT32 Md5_S[][4] = {\r
6a690e23 25 { 7, 22, 17, 12 },\r
26 { 5, 20, 14, 9 },\r
27 { 4, 23, 16 ,11 },\r
28 { 6, 21, 15, 10 },\r
29};\r
30\r
242354a2 31CONST UINT32 Md5_T[] = {\r
6a690e23 32 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE,\r
33 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501,\r
34 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE,\r
35 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821,\r
36 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA,\r
37 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8,\r
38 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED,\r
39 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A,\r
40 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C,\r
41 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,\r
42 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05,\r
43 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665,\r
44 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039,\r
45 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1,\r
46 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1,\r
47 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391\r
48};\r
49\r
fe1e36e5 50CONST UINT8 Md5HashPadding[] =\r
6a690e23 51{\r
52 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
6a690e23 60 0x00, 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
d1102dba
LG
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\r
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00\r
6a690e23 68};\r
69\r
70//\r
71// ROTATE_LEFT rotates x left n bits.\r
72//\r
73#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))\r
74\r
242354a2 75#define SA MedStates[Index2 & 3]\r
76#define SB MedStates[(Index2 + 1) & 3]\r
77#define SC MedStates[(Index2 + 2) & 3]\r
78#define SD MedStates[(Index2 + 3) & 3]\r
6a690e23 79\r
242354a2 80/**\r
81 Tf1 is one basic MD5 transform function.\r
d1102dba 82\r
242354a2 83 @param[in] A A 32-bit quantity.\r
d1102dba 84 @param[in] B A 32-bit quantity.\r
242354a2 85 @param[in] C A 32-bit quantity.\r
86\r
87 @return Output was produced as a 32-bit quantity based on the\r
d1102dba 88 three 32-bit input quantity.\r
242354a2 89**/\r
d1102dba 90UINT32\r
242354a2 91Tf1 (\r
d1102dba
LG
92 IN UINT32 A,\r
93 IN UINT32 B,\r
c5de0d55 94 IN UINT32 C\r
242354a2 95 )\r
6a690e23 96{\r
97 return (A & B) | (~A & C);\r
98}\r
99\r
242354a2 100/**\r
101 Tf2 is one basic MD5 transform function.\r
d1102dba 102\r
242354a2 103 @param[in] A A 32-bit quantity.\r
d1102dba 104 @param[in] B A 32-bit quantity.\r
242354a2 105 @param[in] C A 32-bit quantity.\r
106\r
107 @return Output was produced as a 32-bit quantity based on the\r
d1102dba 108 three 32-bit input quantity.\r
242354a2 109**/\r
d1102dba 110UINT32\r
242354a2 111Tf2 (\r
d1102dba
LG
112 IN UINT32 A,\r
113 IN UINT32 B,\r
c5de0d55 114 IN UINT32 C\r
242354a2 115 )\r
6a690e23 116{\r
117 return (A & C) | (B & ~C);\r
118}\r
119\r
242354a2 120/**\r
121 Tf3 is one basic MD5 transform function.\r
d1102dba 122\r
242354a2 123 @param[in] A A 32-bit quantity.\r
d1102dba 124 @param[in] B A 32-bit quantity.\r
242354a2 125 @param[in] C A 32-bit quantity.\r
126\r
127 @return Output was produced as a 32-bit quantity based on the\r
d1102dba 128 three 32-bit input quantity.\r
242354a2 129**/\r
d1102dba 130UINT32\r
242354a2 131Tf3 (\r
d1102dba
LG
132 IN UINT32 A,\r
133 IN UINT32 B,\r
c5de0d55 134 IN UINT32 C\r
242354a2 135 )\r
6a690e23 136{\r
137 return A ^ B ^ C;\r
138}\r
139\r
242354a2 140/**\r
141 Tf4 is one basic MD5 transform function.\r
d1102dba 142\r
242354a2 143 @param[in] A A 32-bit quantity.\r
d1102dba 144 @param[in] B A 32-bit quantity.\r
242354a2 145 @param[in] C A 32-bit quantity.\r
146\r
147 @return Output was produced as a 32-bit quantity based on the\r
d1102dba 148 three 32-bit input quantity.\r
242354a2 149**/\r
d1102dba 150UINT32\r
242354a2 151Tf4 (\r
d1102dba
LG
152 IN UINT32 A,\r
153 IN UINT32 B,\r
c5de0d55 154 IN UINT32 C\r
242354a2 155 )\r
6a690e23 156{\r
157 return B ^ (A | ~C);\r
158}\r
159\r
160typedef\r
161UINT32\r
162(*MD5_TRANSFORM_FUNC) (\r
163 IN UINT32 A,\r
164 IN UINT32 B,\r
165 IN UINT32 C\r
166 );\r
167\r
242354a2 168CONST MD5_TRANSFORM_FUNC Md5_F[] = {\r
169 Tf1,\r
170 Tf2,\r
171 Tf3,\r
172 Tf4\r
6a690e23 173};\r
174\r
12618416 175/**\r
242354a2 176 Perform the MD5 transform on 64 bytes data segment.\r
12618416 177\r
c5de0d55 178 @param[in, out] Md5Ctx It includes the data segment for Md5 transform.\r
12618416 179**/\r
6a690e23 180VOID\r
181MD5Transform (\r
c5de0d55 182 IN OUT MD5_CTX *Md5Ctx\r
6a690e23 183 )\r
6a690e23 184{\r
242354a2 185 UINT32 Index1;\r
186 UINT32 Index2;\r
187 UINT32 MedStates[MD5_HASHSIZE >> 2];\r
188 UINT32 *Data;\r
189 UINT32 IndexD;\r
190 UINT32 IndexT;\r
6a690e23 191\r
242354a2 192 Data = (UINT32 *) Md5Ctx->M;\r
6a690e23 193\r
194 //\r
242354a2 195 // Copy MD5 states to MedStates\r
6a690e23 196 //\r
242354a2 197 CopyMem (MedStates, Md5Ctx->States, MD5_HASHSIZE);\r
198\r
199 IndexT = 0;\r
200 for (Index1 = 0; Index1 < 4; Index1++) {\r
201 IndexD = Md5_Data[Index1][0];\r
202 for (Index2 = 16; Index2 > 0; Index2--) {\r
203 SA += (*Md5_F[Index1]) (SB, SC, SD) + Data[IndexD] + Md5_T[IndexT];\r
204 SA = ROTATE_LEFT (SA, Md5_S[Index1][Index2 & 3]);\r
6a690e23 205 SA += SB;\r
206\r
242354a2 207 IndexD += Md5_Data[Index1][1];\r
208 IndexD &= 15;\r
6a690e23 209\r
242354a2 210 IndexT++;\r
6a690e23 211 }\r
212 }\r
213\r
242354a2 214 for (Index1 = 0; Index1 < 4; Index1++) {\r
215 Md5Ctx->States[Index1] += MedStates[Index1];\r
6a690e23 216 }\r
217}\r
218\r
12618416 219/**\r
220 Copy data segment into the M field of MD5_CTX structure for later transform.\r
221 If the length of data segment is larger than 64 bytes, then does the transform\r
222 immediately and the generated Md5 code is stored in the States field of MD5_CTX\r
d1102dba 223 data struct for later accumulation.\r
12618416 224 All of Md5 code generated for the sequential 64-bytes data segaments are be\r
225 accumulated in MD5Final() function.\r
226\r
c5de0d55 227 @param[in, out] Md5Ctx The data structure of storing the original data\r
228 segment and the final result.\r
229 @param[in] Data The data wanted to be transformed.\r
230 @param[in] DataLen The length of data.\r
12618416 231**/\r
6a690e23 232VOID\r
233MD5UpdateBlock (\r
c5de0d55 234 IN OUT MD5_CTX *Md5Ctx,\r
6a690e23 235 IN CONST UINT8 *Data,\r
236 IN UINTN DataLen\r
237 )\r
6a690e23 238{\r
239 UINTN Limit;\r
240\r
241 for (Limit = 64 - Md5Ctx->Count; DataLen >= 64 - Md5Ctx->Count; Limit = 64) {\r
e48e37fc 242 CopyMem (Md5Ctx->M + Md5Ctx->Count, (VOID *)Data, Limit);\r
6a690e23 243 MD5Transform (Md5Ctx);\r
d1102dba 244\r
6a690e23 245 Md5Ctx->Count = 0;\r
246 Data += Limit;\r
247 DataLen -= Limit;\r
248 }\r
249\r
e48e37fc 250 CopyMem (Md5Ctx->M + Md5Ctx->Count, (VOID *)Data, DataLen);\r
6a690e23 251 Md5Ctx->Count += DataLen;\r
252}\r
253\r
12618416 254/**\r
255 Initialize four 32-bits chaining variables and use them to do the Md5 transform.\r
256\r
c5de0d55 257 @param[out] Md5Ctx The data structure of Md5.\r
12618416 258\r
242354a2 259 @retval EFI_SUCCESS Initialization is ok.\r
12618416 260**/\r
6a690e23 261EFI_STATUS\r
262MD5Init (\r
c5de0d55 263 OUT MD5_CTX *Md5Ctx\r
6a690e23 264 )\r
6a690e23 265{\r
e48e37fc 266 ZeroMem (Md5Ctx, sizeof (*Md5Ctx));\r
6a690e23 267\r
268 //\r
269 // Set magic initialization constants.\r
270 //\r
271 Md5Ctx->States[0] = 0x67452301;\r
272 Md5Ctx->States[1] = 0xefcdab89;\r
273 Md5Ctx->States[2] = 0x98badcfe;\r
d1102dba 274 Md5Ctx->States[3] = 0x10325476;\r
6a690e23 275\r
276 return EFI_SUCCESS;\r
277}\r
278\r
12618416 279/**\r
280 the external interface of Md5 algorithm\r
281\r
c5de0d55 282 @param[in, out] Md5Ctx The data structure of storing the original data\r
283 segment and the final result.\r
284 @param[in] Data The data wanted to be transformed.\r
285 @param[in] DataLen The length of data.\r
12618416 286\r
242354a2 287 @retval EFI_SUCCESS The transform is ok.\r
963dbb30 288 @retval Others Other errors as indicated.\r
12618416 289**/\r
6a690e23 290EFI_STATUS\r
291MD5Update (\r
c5de0d55 292 IN OUT MD5_CTX *Md5Ctx,\r
293 IN VOID *Data,\r
294 IN UINTN DataLen\r
6a690e23 295 )\r
6a690e23 296{\r
297 if (EFI_ERROR (Md5Ctx->Status)) {\r
298 return Md5Ctx->Status;\r
299 }\r
300\r
301 MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) Data, DataLen);\r
302 Md5Ctx->Length += DataLen;\r
303 return EFI_SUCCESS;\r
304}\r
305\r
12618416 306/**\r
242354a2 307 Accumulate the MD5 value of every data segment and generate the finial\r
308 result according to MD5 algorithm.\r
12618416 309\r
c5de0d55 310 @param[in, out] Md5Ctx The data structure of storing the original data\r
311 segment and the final result.\r
312 @param[out] HashVal The final 128-bits output.\r
12618416 313\r
242354a2 314 @retval EFI_SUCCESS The transform is ok.\r
963dbb30 315 @retval Others Other errors as indicated.\r
12618416 316**/\r
6a690e23 317EFI_STATUS\r
318MD5Final (\r
c5de0d55 319 IN OUT MD5_CTX *Md5Ctx,\r
320 OUT UINT8 *HashVal\r
6a690e23 321 )\r
6a690e23 322{\r
323 UINTN PadLength;\r
324\r
325 if (Md5Ctx->Status == EFI_ALREADY_STARTED) {\r
326 //\r
327 // Store Hashed value & Zeroize sensitive context information.\r
328 //\r
e48e37fc 329 CopyMem (HashVal, (UINT8 *) Md5Ctx->States, MD5_HASHSIZE);\r
330 ZeroMem ((UINT8 *)Md5Ctx, sizeof (*Md5Ctx));\r
d1102dba 331\r
6a690e23 332 return EFI_SUCCESS;\r
333 }\r
334\r
335 if (EFI_ERROR (Md5Ctx->Status)) {\r
336 return Md5Ctx->Status;\r
337 }\r
338\r
339 PadLength = Md5Ctx->Count >= 56 ? 120 : 56;\r
340 PadLength -= Md5Ctx->Count;\r
341 MD5UpdateBlock (Md5Ctx, Md5HashPadding, PadLength);\r
342 Md5Ctx->Length = LShiftU64 (Md5Ctx->Length, 3);\r
343 MD5UpdateBlock (Md5Ctx, (CONST UINT8 *) &Md5Ctx->Length, 8);\r
344\r
e48e37fc 345 ZeroMem (Md5Ctx->M, sizeof (Md5Ctx->M));\r
6a690e23 346 Md5Ctx->Length = 0;\r
347 Md5Ctx->Status = EFI_ALREADY_STARTED;\r
348 return MD5Final (Md5Ctx, HashVal);\r
349}\r
350\r