1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | // |
5 | // md5.h |
6 | // |
7 | |
8 | // |
9 | // A pretty fast implementation of MD5 |
10 | // |
11 | |
12 | |
13 | #ifndef __MD5_H__ |
14 | #define __MD5_H__ |
15 | |
16 | ///////////////////////////////////////////////////////////////////////////////////// |
17 | // |
18 | // Declaration of the central transform function |
19 | // |
20 | void __stdcall MD5Transform(ULONG state[4], const ULONG* data); |
21 | |
22 | ///////////////////////////////////////////////////////////////////////////////////// |
23 | |
24 | #include <pshpack1.h> |
25 | |
26 | |
27 | // This structure is used to return the final resulting hash. |
28 | // |
29 | struct MD5HASHDATA |
30 | { |
31 | union |
32 | { |
33 | BYTE rgb[16]; |
34 | struct |
35 | { |
36 | ULONGLONG ullLow; |
37 | ULONGLONG ullHigh; |
38 | } u; |
39 | struct |
40 | { |
41 | ULONG u0; |
42 | ULONG u1; |
43 | ULONG u2; |
44 | ULONG u3; |
45 | } v; |
46 | }; |
47 | }; |
48 | |
49 | inline BOOL operator==(const MD5HASHDATA& me, const MD5HASHDATA& him) |
50 | { |
51 | return memcmp(&me, &him, sizeof(MD5HASHDATA)) == 0; |
52 | } |
53 | |
54 | inline BOOL operator!=(const MD5HASHDATA& me, const MD5HASHDATA& him) |
55 | { |
56 | return memcmp(&me, &him, sizeof(MD5HASHDATA)) != 0; |
57 | } |
58 | |
59 | |
60 | // The engine that carries out the hash |
61 | // |
62 | class MD5 |
63 | { |
64 | // These four values must be contiguous, and in this order |
65 | union |
66 | { |
67 | ULONG m_state[4]; |
68 | struct |
69 | { |
70 | ULONG m_a; // state |
71 | ULONG m_b; // ... variables |
72 | ULONG m_c; // ... as found in |
73 | ULONG m_d; // ... RFC1321 |
74 | } u; |
75 | }; |
76 | |
77 | BYTE m_data[64]; // where to accumulate the data as we are passed it |
78 | ULONGLONG m_cbitHashed; // amount of data that we've hashed |
79 | ULONG m_cbData; // number of bytes presently in data |
80 | |
81 | BYTE m_padding[64]; // padding data, used if length data not = 0 mod 64 |
82 | |
83 | public: |
84 | |
85 | ///////////////////////////////////////////////////////////////////////////////////// |
86 | |
87 | void Hash(const BYTE* pbData, ULONG cbData, MD5HASHDATA* phash, BOOL fConstructed = FALSE) |
88 | { |
89 | Init(fConstructed); |
90 | HashMore(pbData, cbData); |
91 | GetHashValue(phash); |
92 | } |
93 | |
94 | ///////////////////////////////////////////////////////////////////////////////////// |
95 | |
96 | void Hash(const BYTE* pbData, ULONGLONG cbData, MD5HASHDATA* phash, BOOL fConstructed = FALSE) |
97 | { |
98 | Init(fConstructed); |
99 | |
100 | ULARGE_INTEGER ul; |
101 | ul.QuadPart = cbData; |
102 | |
103 | while (ul.u.HighPart) |
104 | { |
105 | ULONG cbHash = 0xFFFFFFFF; // Hash as much as we can at once |
106 | HashMore(pbData, cbHash); |
107 | pbData += cbHash; |
108 | ul.QuadPart -= cbHash; |
109 | } |
110 | |
111 | HashMore(pbData, ul.u.LowPart); // Hash whatever is left |
112 | |
113 | GetHashValue(phash); |
114 | } |
115 | |
116 | ///////////////////////////////////////////////////////////////////////////////////// |
117 | |
118 | void Init(BOOL fConstructed = FALSE); |
119 | |
120 | ///////////////////////////////////////////////////////////////////////////////////// |
121 | |
122 | void HashMore(const void* pvInput, ULONG cbInput); |
123 | |
124 | ///////////////////////////////////////////////////////////////////////////////////// |
125 | |
126 | void GetHashValue(MD5HASHDATA* phash); |
127 | |
128 | ///////////////////////////////////////////////////////////////////////////////////// |
129 | |
130 | }; |
131 | |
132 | #include <poppack.h> |
133 | |
134 | #endif |
135 | |