summaryrefslogtreecommitdiff
path: root/src/inc/md5.h
blob: ed0ce618f6da2811200dc9c3fb853ad701708bd3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
//
// md5.h
//

// 
// A pretty fast implementation of MD5
//


#ifndef __MD5_H__
#define __MD5_H__

/////////////////////////////////////////////////////////////////////////////////////
//
// Declaration of the central transform function
//
void __stdcall MD5Transform(ULONG state[4], const ULONG* data);
        
/////////////////////////////////////////////////////////////////////////////////////

#include <pshpack1.h>


// This structure is used to return the final resulting hash.
// 
struct MD5HASHDATA
    {
    union
        {
        BYTE rgb[16];
        struct
            {
            ULONGLONG ullLow;
            ULONGLONG ullHigh;
            } u;
        struct
            {
            ULONG     u0;
            ULONG     u1;
            ULONG     u2;
            ULONG     u3;
            } v;
        };
    };

inline BOOL operator==(const MD5HASHDATA& me, const MD5HASHDATA& him)
    {
    return memcmp(&me, &him, sizeof(MD5HASHDATA)) == 0;
    }

inline BOOL operator!=(const MD5HASHDATA& me, const MD5HASHDATA& him)
    {
    return memcmp(&me, &him, sizeof(MD5HASHDATA)) != 0;
    }


// The engine that carries out the hash
//
class MD5
    {
    // These four values must be contiguous, and in this order
    union
        {
        ULONG       m_state[4];
        struct
            {
            ULONG       m_a;              // state 
            ULONG       m_b;              //     ... variables
            ULONG       m_c;              //            ... as found in
            ULONG       m_d;              //                    ... RFC1321
            } u;
        };
    
    BYTE        m_data[64];       // where to accumulate the data as we are passed it
    ULONGLONG   m_cbitHashed;     // amount of data that we've hashed
    ULONG       m_cbData;         // number of bytes presently in data
    
    BYTE        m_padding[64];    // padding data, used if length data not = 0 mod 64

public:

    /////////////////////////////////////////////////////////////////////////////////////

    void Hash(const BYTE* pbData, ULONG cbData, MD5HASHDATA* phash, BOOL fConstructed = FALSE)
        {
        Init(fConstructed);
        HashMore(pbData, cbData);
        GetHashValue(phash);
        }

    /////////////////////////////////////////////////////////////////////////////////////

    void Hash(const BYTE* pbData, ULONGLONG cbData, MD5HASHDATA* phash, BOOL fConstructed = FALSE)
        {
        Init(fConstructed);

        ULARGE_INTEGER ul;
        ul.QuadPart = cbData;

        while (ul.u.HighPart)
            {
            ULONG cbHash = 0xFFFFFFFF;                      // Hash as much as we can at once
            HashMore(pbData, cbHash);
            pbData      += cbHash;
            ul.QuadPart -= cbHash;
            }
        
        HashMore(pbData, ul.u.LowPart);                       // Hash whatever is left

        GetHashValue(phash);
        }

    /////////////////////////////////////////////////////////////////////////////////////

    void Init(BOOL fConstructed = FALSE);

    /////////////////////////////////////////////////////////////////////////////////////

    void HashMore(const void* pvInput, ULONG cbInput);

    /////////////////////////////////////////////////////////////////////////////////////

    void GetHashValue(MD5HASHDATA* phash);

    /////////////////////////////////////////////////////////////////////////////////////

    };

#include <poppack.h>

#endif