OpenCore  1.0.4
OpenCore Bootloader
Loading...
Searching...
No Matches
Md5.c
Go to the documentation of this file.
1
19/*********************************************************************
20* Filename: md5.c
21* Author: Brad Conte (brad AT bradconte.com)
22* Copyright:
23* Disclaimer: This code is presented "as is" without any guarantees.
24* Details: Implementation of the MD5 hashing algorithm.
25 Algorithm specification can be found here:
26 * http://tools.ietf.org/html/rfc1321
27 This implementation uses little endian byte order.
28*********************************************************************/
29
30#include "CryptoInternal.h"
31
32#define ROTLEFT(A, B) ((A << B) | (A >> (32 - B)))
33
34#define F(X, Y, Z) ((X & Y) | (~X & Z))
35#define G(X, Y, Z) ((X & Z) | (Y & ~Z))
36#define H(X, Y, Z) (X ^ Y ^ Z)
37#define I(X, Y, Z) (Y ^ (X | ~Z))
38
39#define FF(A, B, C, D, M, S, T) do { A += F(B,C,D) + M + T;\
40 A = B + ROTLEFT(A,S); } while (0)
41#define GG(A, B, C, D, M, S, T) do { A += G(B,C,D) + M + T;\
42 A = B + ROTLEFT(A,S); } while (0)
43#define HH(A, B, C, D, M, S, T) do { A += H(B,C,D) + M + T;\
44 A = B + ROTLEFT(A,S); } while (0)
45#define II(A, B, C, D, M, S, T) do { A += I(B,C,D) + M + T;\
46 A = B + ROTLEFT(A,S); } while (0)
47
48#ifdef OC_CRYPTO_SUPPORTS_MD5
49
50VOID
51Md5Transform (
52 MD5_CONTEXT *Ctx,
53 CONST UINT8 *Data
54 )
55{
56 UINT32 A, B, C, D, M[16], Index1, Index2;
57
58 //
59 // MD5 specifies big endian byte order, but this implementation assumes a little
60 // endian byte order CPU. Reverse all the bytes upon input, and re-reverse them
61 // on output (in md5_final()).
62 //
63 for (Index1 = 0, Index2 = 0; Index1 < 16; ++Index1, Index2 += 4) {
64 M[Index1] = (Data[Index2]) + (Data[Index2 + 1] << 8)
65 + (Data[Index2 + 2] << 16) + (Data[Index2 + 3] << 24);
66 }
67
68 A = Ctx->State[0];
69 B = Ctx->State[1];
70 C = Ctx->State[2];
71 D = Ctx->State[3];
72
73 FF (A, B, C, D, M[0], 7, 0xD76AA478);
74 FF (D, A, B, C, M[1], 12, 0xE8C7B756);
75 FF (C, D, A, B, M[2], 17, 0x242070DB);
76 FF (B, C, D, A, M[3], 22, 0xC1BDCEEE);
77 FF (A, B, C, D, M[4], 7, 0xF57C0FAF);
78 FF (D, A, B, C, M[5], 12, 0x4787C62A);
79 FF (C, D, A, B, M[6], 17, 0xA8304613);
80 FF (B, C, D, A, M[7], 22, 0xFD469501);
81 FF (A, B, C, D, M[8], 7, 0x698098D8);
82 FF (D, A, B, C, M[9], 12, 0x8B44F7AF);
83 FF (C, D, A, B, M[10], 17, 0xFFFF5BB1);
84 FF (B, C, D, A, M[11], 22, 0x895CD7BE);
85 FF (A, B, C, D, M[12], 7, 0x6B901122);
86 FF (D, A, B, C, M[13], 12, 0xFD987193);
87 FF (C, D, A, B, M[14], 17, 0xA679438E);
88 FF (B, C, D, A, M[15], 22, 0x49B40821);
89
90 GG (A, B, C, D, M[1], 5, 0xF61E2562);
91 GG (D, A, B, C, M[6], 9, 0xC040B340);
92 GG (C, D, A, B, M[11], 14, 0x265E5A51);
93 GG (B, C, D, A, M[0], 20, 0xE9B6C7AA);
94 GG (A, B, C, D, M[5], 5, 0xD62F105D);
95 GG (D, A, B, C, M[10], 9, 0x02441453);
96 GG (C, D, A, B, M[15], 14, 0xD8A1E681);
97 GG (B, C, D, A, M[4], 20, 0xE7D3FBC8);
98 GG (A, B, C, D, M[9], 5, 0x21E1CDE6);
99 GG (D, A, B, C, M[14], 9, 0xC33707D6);
100 GG (C, D, A, B, M[3], 14, 0xF4D50D87);
101 GG (B, C, D, A, M[8], 20, 0x455A14ED);
102 GG (A, B, C, D, M[13], 5, 0xA9E3E905);
103 GG (D, A, B, C, M[2], 9, 0xFCEFA3F8);
104 GG (C, D, A, B, M[7], 14, 0x676F02D9);
105 GG (B, C, D, A, M[12], 20, 0x8D2A4C8A);
106
107 HH (A, B, C, D, M[5], 4, 0xFFFA3942);
108 HH (D, A, B, C, M[8], 11, 0x8771F681);
109 HH (C, D, A, B, M[11], 16, 0x6D9D6122);
110 HH (B, C, D, A, M[14], 23, 0xFDE5380C);
111 HH (A, B, C, D, M[1], 4, 0xA4BEEA44);
112 HH (D, A, B, C, M[4], 11, 0x4BDECFA9);
113 HH (C, D, A, B, M[7], 16, 0xF6BB4B60);
114 HH (B, C, D, A, M[10], 23, 0xBEBFBC70);
115 HH (A, B, C, D, M[13], 4, 0x289B7EC6);
116 HH (D, A, B, C, M[0], 11, 0xEAA127FA);
117 HH (C, D, A, B, M[3], 16, 0xD4EF3085);
118 HH (B, C, D, A, M[6], 23, 0x04881D05);
119 HH (A, B, C, D, M[9], 4, 0xD9D4D039);
120 HH (D, A, B, C, M[12], 11, 0xE6DB99E5);
121 HH (C, D, A, B, M[15], 16, 0x1FA27CF8);
122 HH (B, C, D, A, M[2], 23, 0xC4AC5665);
123
124 II (A, B, C, D, M[0], 6, 0xF4292244);
125 II (D, A, B, C, M[7], 10, 0x432AFF97);
126 II (C, D, A, B, M[14], 15, 0xAB9423A7);
127 II (B, C, D, A, M[5], 21, 0xFC93A039);
128 II (A, B, C, D, M[12], 6, 0x655B59C3);
129 II (D, A, B, C, M[3], 10, 0x8F0CCC92);
130 II (C, D, A, B, M[10], 15, 0xFFEFF47D);
131 II (B, C, D, A, M[1], 21, 0x85845DD1);
132 II (A, B, C, D, M[8], 6, 0x6FA87E4F);
133 II (D, A, B, C, M[15], 10, 0xFE2CE6E0);
134 II (C, D, A, B, M[6], 15, 0xA3014314);
135 II (B, C, D, A, M[13], 21, 0x4E0811A1);
136 II (A, B, C, D, M[4], 6, 0xF7537E82);
137 II (D, A, B, C, M[11], 10, 0xBD3AF235);
138 II (C, D, A, B, M[2], 15, 0x2AD7D2BB);
139 II (B, C, D, A, M[9], 21, 0xEB86D391);
140
141 Ctx->State[0] += A;
142 Ctx->State[1] += B;
143 Ctx->State[2] += C;
144 Ctx->State[3] += D;
145}
146
147VOID
148Md5Init (
149 MD5_CONTEXT *Ctx
150 )
151{
152 Ctx->DataLen = 0;
153 Ctx->BitLen = 0;
154 Ctx->State[0] = 0x67452301;
155 Ctx->State[1] = 0xEFCDAB89;
156 Ctx->State[2] = 0x98BADCFE;
157 Ctx->State[3] = 0x10325476;
158}
159
160VOID
161Md5Update (
162 MD5_CONTEXT *Ctx,
163 CONST UINT8 *Data,
164 UINTN Len
165 )
166{
167 UINTN Index;
168
169 for (Index = 0; Index < Len; ++Index) {
170 Ctx->Data[Ctx->DataLen] = Data[Index];
171 Ctx->DataLen++;
172 if (Ctx->DataLen == 64) {
173 Md5Transform (Ctx, Ctx->Data);
174 Ctx->BitLen += 512;
175 Ctx->DataLen = 0;
176 }
177 }
178}
179
180VOID
181Md5Final (
182 MD5_CONTEXT *Ctx,
183 UINT8 *Hash
184 )
185{
186 UINTN Index = Ctx->DataLen;
187
188 //
189 // Pad whatever Data is left in the buffer.
190 //
191 if (Ctx->DataLen < 56) {
192 Ctx->Data[Index++] = 0x80;
193 ZeroMem (Ctx->Data + Index, 56-Index);
194 } else if (Ctx->DataLen >= 56) {
195 Ctx->Data[Index++] = 0x80;
196 ZeroMem (Ctx->Data + Index, 64-Index);
197 Md5Transform (Ctx, Ctx->Data);
198 ZeroMem (Ctx->Data, 56);
199 }
200
201 //
202 // Append to the padding the total message's length in bits and transform.
203 //
204 Ctx->BitLen += Ctx->DataLen * 8;
205 Ctx->Data[56] = (UINT8)(Ctx->BitLen);
206 Ctx->Data[57] = (UINT8)(Ctx->BitLen >> 8);
207 Ctx->Data[58] = (UINT8)(Ctx->BitLen >> 16);
208 Ctx->Data[59] = (UINT8)(Ctx->BitLen >> 24);
209 Ctx->Data[60] = (UINT8)(Ctx->BitLen >> 32);
210 Ctx->Data[61] = (UINT8)(Ctx->BitLen >> 40);
211 Ctx->Data[62] = (UINT8)(Ctx->BitLen >> 48);
212 Ctx->Data[63] = (UINT8)(Ctx->BitLen >> 56);
213 Md5Transform (Ctx, Ctx->Data);
214
215 //
216 // Since this implementation uses little endian byte ordering and MD uses big endian,
217 // reverse all the bytes when copying the final State to the output Hash.
218 //
219 for (Index = 0; Index < 4; ++Index) {
220 Hash[Index] = (UINT8)((Ctx->State[0] >> (Index * 8)) & 0x000000FF);
221 Hash[Index + 4] = (UINT8)((Ctx->State[1] >> (Index * 8)) & 0x000000FF);
222 Hash[Index + 8] = (UINT8)((Ctx->State[2] >> (Index * 8)) & 0x000000FF);
223 Hash[Index + 12] = (UINT8)((Ctx->State[3] >> (Index * 8)) & 0x000000FF);
224 }
225}
226
227VOID
228Md5 (
229 UINT8 *Hash,
230 UINT8 *Data,
231 UINTN Len
232 )
233{
234 MD5_CONTEXT Ctx;
235
236 Md5Init (&Ctx);
237 Md5Update (&Ctx, Data, Len);
238 Md5Final (&Ctx, Hash);
239 SecureZeroMem (&Ctx, sizeof (Ctx));
240}
241
242#endif
#define HH(A, B, C, D, M, S, T)
Definition Md5.c:43
#define GG(A, B, C, D, M, S, T)
Definition Md5.c:41
#define II(A, B, C, D, M, S, T)
Definition Md5.c:45
#define FF(A, B, C, D, M, S, T)
Definition Md5.c:39
VOID Md5Init(MD5_CONTEXT *Context)
VOID Md5Final(MD5_CONTEXT *Context, UINT8 *Hash)
VOID Md5(UINT8 *Hash, UINT8 *Data, UINTN Len)
VOID * SecureZeroMem(OUT VOID *Buffer, IN UINTN Length)
Definition SecureMem.c:73
VOID Md5Update(MD5_CONTEXT *Context, CONST UINT8 *Data, UINTN Len)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
#define Len
Definition deflate.h:82
UINT8 Data[64]
UINT32 State[4]