| 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 | |