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 CONST UINT32 MD5_K
[][2] = {
32 CONST UINT32 MD5_S
[][4] = {
39 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 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 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
141 UINT32 S
[MD5_HASHSIZE
>> 2];
146 X
= (UINT32
*) Md5Ctx
->M
;
149 // Copy MD5 states to S
151 CopyMem (S
, Md5Ctx
->States
, MD5_HASHSIZE
);
154 for (i
= 0; i
< 4; i
++) {
156 for (j
= 16; j
> 0; j
--) {
157 SA
+= (*MD5_F
[i
]) (SB
, SC
, SD
) + X
[k
] + MD5_T
[t
];
158 SA
= ROTATE_LEFT (SA
, MD5_S
[i
][j
& 3]);
168 for (i
= 0; i
< 4; i
++) {
169 Md5Ctx
->States
[i
] += S
[i
];
174 Copy data segment into the M field of MD5_CTX structure for later transform.
175 If the length of data segment is larger than 64 bytes, then does the transform
176 immediately and the generated Md5 code is stored in the States field of MD5_CTX
177 data struct for later accumulation.
178 All of Md5 code generated for the sequential 64-bytes data segaments are be
179 accumulated in MD5Final() function.
181 @param Md5Ctx[in] the data structure of storing the original data
182 segment and the final result.
184 @param Data[in] the data wanted to be transformed
186 @param DataLen[in] the length of data
193 IN CONST UINT8
*Data
,
199 for (Limit
= 64 - Md5Ctx
->Count
; DataLen
>= 64 - Md5Ctx
->Count
; Limit
= 64) {
200 CopyMem (Md5Ctx
->M
+ Md5Ctx
->Count
, (VOID
*)Data
, Limit
);
201 MD5Transform (Md5Ctx
);
208 CopyMem (Md5Ctx
->M
+ Md5Ctx
->Count
, (VOID
*)Data
, DataLen
);
209 Md5Ctx
->Count
+= DataLen
;
213 Initialize four 32-bits chaining variables and use them to do the Md5 transform.
215 @param Md5Ctx[in] the data structure of Md5
217 @retval EFI_SUCCESS initialization is ok
225 ZeroMem (Md5Ctx
, sizeof (*Md5Ctx
));
228 // Set magic initialization constants.
230 Md5Ctx
->States
[0] = 0x67452301;
231 Md5Ctx
->States
[1] = 0xefcdab89;
232 Md5Ctx
->States
[2] = 0x98badcfe;
233 Md5Ctx
->States
[3] = 0x10325476;
239 the external interface of Md5 algorithm
241 @param Md5Ctx[in] the data structure of storing the original data
242 segment and the final result.
244 @param Data[in] the data wanted to be transformed.
246 @param DataLen[in] the length of data.
248 @retval EFI_SUCCESS the transform is ok.
258 if (EFI_ERROR (Md5Ctx
->Status
)) {
259 return Md5Ctx
->Status
;
262 MD5UpdateBlock (Md5Ctx
, (CONST UINT8
*) Data
, DataLen
);
263 Md5Ctx
->Length
+= DataLen
;
268 accumulate the MD5 value of every data segment and generate the finial
269 result according to MD5 algorithm
271 @param Md5Ctx[in] the data structure of storing the original data
272 segment and the final result.
274 @param HashVal[out] the final 128-bits output.
276 @retval EFI_SUCCESS the transform is ok.
287 if (Md5Ctx
->Status
== EFI_ALREADY_STARTED
) {
289 // Store Hashed value & Zeroize sensitive context information.
291 CopyMem (HashVal
, (UINT8
*) Md5Ctx
->States
, MD5_HASHSIZE
);
292 ZeroMem ((UINT8
*)Md5Ctx
, sizeof (*Md5Ctx
));
297 if (EFI_ERROR (Md5Ctx
->Status
)) {
298 return Md5Ctx
->Status
;
301 PadLength
= Md5Ctx
->Count
>= 56 ? 120 : 56;
302 PadLength
-= Md5Ctx
->Count
;
303 MD5UpdateBlock (Md5Ctx
, Md5HashPadding
, PadLength
);
304 Md5Ctx
->Length
= LShiftU64 (Md5Ctx
->Length
, 3);
305 MD5UpdateBlock (Md5Ctx
, (CONST UINT8
*) &Md5Ctx
->Length
, 8);
307 ZeroMem (Md5Ctx
->M
, sizeof (Md5Ctx
->M
));
309 Md5Ctx
->Status
= EFI_ALREADY_STARTED
;
310 return MD5Final (Md5Ctx
, HashVal
);