2 Implementation of MD5 algorithm
4 Copyright (c) 2004 - 2008, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 Implementation of MD5 algorithm
25 STATIC CONST UINT32 MD5_K
[][2] = {
32 STATIC CONST UINT32 MD5_S
[][4] = {
39 STATIC CONST UINT32 MD5_T
[] = {
40 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE,
41 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501,
42 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE,
43 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821,
44 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA,
45 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8,
46 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED,
47 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A,
48 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C,
49 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,
50 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05,
51 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665,
52 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039,
53 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1,
54 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1,
55 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391
58 STATIC CONST UINT8 Md5HashPadding
[] =
60 0x80, 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 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
79 // ROTATE_LEFT rotates x left n bits.
81 #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
84 #define SB S[(j + 1) & 3]
85 #define SC S[(j + 2) & 3]
86 #define SD S[(j + 3) & 3]
89 // TF1, TF2, TF3, TF4 are basic MD5 transform functions
91 UINT32
TF1 (UINT32 A
, UINT32 B
, UINT32 C
)
93 return (A
& B
) | (~A
& C
);
96 UINT32
TF2 (UINT32 A
, UINT32 B
, UINT32 C
)
98 return (A
& C
) | (B
& ~C
);
101 UINT32
TF3 (UINT32 A
, UINT32 B
, UINT32 C
)
106 UINT32
TF4 (UINT32 A
, UINT32 B
, UINT32 C
)
113 (*MD5_TRANSFORM_FUNC
) (
119 STATIC CONST MD5_TRANSFORM_FUNC MD5_F
[] = {
127 Perform the MD5 transform on 64 bytes data segment
129 @param Md5Ctx[in] it includes the data segment for Md5 transform
142 UINT32 S
[MD5_HASHSIZE
>> 2];
147 X
= (UINT32
*) Md5Ctx
->M
;
150 // Copy MD5 states to S
152 CopyMem (S
, Md5Ctx
->States
, MD5_HASHSIZE
);
155 for (i
= 0; i
< 4; i
++) {
157 for (j
= 16; j
> 0; j
--) {
158 SA
+= (*MD5_F
[i
]) (SB
, SC
, SD
) + X
[k
] + MD5_T
[t
];
159 SA
= ROTATE_LEFT (SA
, MD5_S
[i
][j
& 3]);
169 for (i
= 0; i
< 4; i
++) {
170 Md5Ctx
->States
[i
] += S
[i
];
175 Copy data segment into the M field of MD5_CTX structure for later transform.
176 If the length of data segment is larger than 64 bytes, then does the transform
177 immediately and the generated Md5 code is stored in the States field of MD5_CTX
178 data struct for later accumulation.
179 All of Md5 code generated for the sequential 64-bytes data segaments are be
180 accumulated in MD5Final() function.
182 @param Md5Ctx[in] the data structure of storing the original data
183 segment and the final result.
185 @param Data[in] the data wanted to be transformed
187 @param DataLen[in] the length of data
195 IN CONST UINT8
*Data
,
201 for (Limit
= 64 - Md5Ctx
->Count
; DataLen
>= 64 - Md5Ctx
->Count
; Limit
= 64) {
202 CopyMem (Md5Ctx
->M
+ Md5Ctx
->Count
, (VOID
*)Data
, Limit
);
203 MD5Transform (Md5Ctx
);
210 CopyMem (Md5Ctx
->M
+ Md5Ctx
->Count
, (VOID
*)Data
, DataLen
);
211 Md5Ctx
->Count
+= DataLen
;
215 Initialize four 32-bits chaining variables and use them to do the Md5 transform.
217 @param Md5Ctx[in] the data structure of Md5
219 @retval EFI_SUCCESS initialization is ok
227 ZeroMem (Md5Ctx
, sizeof (*Md5Ctx
));
230 // Set magic initialization constants.
232 Md5Ctx
->States
[0] = 0x67452301;
233 Md5Ctx
->States
[1] = 0xefcdab89;
234 Md5Ctx
->States
[2] = 0x98badcfe;
235 Md5Ctx
->States
[3] = 0x10325476;
241 the external interface of Md5 algorithm
243 @param Md5Ctx[in] the data structure of storing the original data
244 segment and the final result.
246 @param Data[in] the data wanted to be transformed.
248 @param DataLen[in] the length of data.
250 @retval EFI_SUCCESS the transform is ok.
260 if (EFI_ERROR (Md5Ctx
->Status
)) {
261 return Md5Ctx
->Status
;
264 MD5UpdateBlock (Md5Ctx
, (CONST UINT8
*) Data
, DataLen
);
265 Md5Ctx
->Length
+= DataLen
;
270 accumulate the MD5 value of every data segment and generate the finial
271 result according to MD5 algorithm
273 @param Md5Ctx[in] the data structure of storing the original data
274 segment and the final result.
276 @param HashVal[out] the final 128-bits output.
278 @retval EFI_SUCCESS the transform is ok.
289 if (Md5Ctx
->Status
== EFI_ALREADY_STARTED
) {
291 // Store Hashed value & Zeroize sensitive context information.
293 CopyMem (HashVal
, (UINT8
*) Md5Ctx
->States
, MD5_HASHSIZE
);
294 ZeroMem ((UINT8
*)Md5Ctx
, sizeof (*Md5Ctx
));
299 if (EFI_ERROR (Md5Ctx
->Status
)) {
300 return Md5Ctx
->Status
;
303 PadLength
= Md5Ctx
->Count
>= 56 ? 120 : 56;
304 PadLength
-= Md5Ctx
->Count
;
305 MD5UpdateBlock (Md5Ctx
, Md5HashPadding
, PadLength
);
306 Md5Ctx
->Length
= LShiftU64 (Md5Ctx
->Length
, 3);
307 MD5UpdateBlock (Md5Ctx
, (CONST UINT8
*) &Md5Ctx
->Length
, 8);
309 ZeroMem (Md5Ctx
->M
, sizeof (Md5Ctx
->M
));
311 Md5Ctx
->Status
= EFI_ALREADY_STARTED
;
312 return MD5Final (Md5Ctx
, HashVal
);