/src/botan/src/lib/hash/md5/md5.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * MD5 |
3 | | * (C) 1999-2008 Jack Lloyd |
4 | | * |
5 | | * Botan is released under the Simplified BSD License (see license.txt) |
6 | | */ |
7 | | |
8 | | #include <botan/internal/md5.h> |
9 | | #include <botan/internal/loadstor.h> |
10 | | #include <botan/internal/rotate.h> |
11 | | #include <botan/internal/bit_ops.h> |
12 | | |
13 | | namespace Botan { |
14 | | |
15 | | std::unique_ptr<HashFunction> MD5::copy_state() const |
16 | 0 | { |
17 | 0 | return std::unique_ptr<HashFunction>(new MD5(*this)); |
18 | 0 | } |
19 | | |
20 | | namespace { |
21 | | |
22 | | /* |
23 | | * MD5 FF Function |
24 | | */ |
25 | | template<size_t S> |
26 | | inline void FF(uint32_t& A, uint32_t B, uint32_t C, uint32_t D, uint32_t M) |
27 | 9.00k | { |
28 | 9.00k | A += choose(B, C, D) + M; |
29 | 9.00k | A = rotl<S>(A) + B; |
30 | 9.00k | } md5.cpp:void Botan::(anonymous namespace)::FF<7ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 27 | 2.25k | { | 28 | 2.25k | A += choose(B, C, D) + M; | 29 | 2.25k | A = rotl<S>(A) + B; | 30 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::FF<12ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 27 | 2.25k | { | 28 | 2.25k | A += choose(B, C, D) + M; | 29 | 2.25k | A = rotl<S>(A) + B; | 30 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::FF<17ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 27 | 2.25k | { | 28 | 2.25k | A += choose(B, C, D) + M; | 29 | 2.25k | A = rotl<S>(A) + B; | 30 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::FF<22ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 27 | 2.25k | { | 28 | 2.25k | A += choose(B, C, D) + M; | 29 | 2.25k | A = rotl<S>(A) + B; | 30 | 2.25k | } |
|
31 | | |
32 | | /* |
33 | | * MD5 GG Function |
34 | | */ |
35 | | template<size_t S> |
36 | | inline void GG(uint32_t& A, uint32_t B, uint32_t C, uint32_t D, uint32_t M) |
37 | 9.00k | { |
38 | 9.00k | A += choose(D, B, C) + M; |
39 | 9.00k | A = rotl<S>(A) + B; |
40 | 9.00k | } md5.cpp:void Botan::(anonymous namespace)::GG<5ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 37 | 2.25k | { | 38 | 2.25k | A += choose(D, B, C) + M; | 39 | 2.25k | A = rotl<S>(A) + B; | 40 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::GG<9ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 37 | 2.25k | { | 38 | 2.25k | A += choose(D, B, C) + M; | 39 | 2.25k | A = rotl<S>(A) + B; | 40 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::GG<14ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 37 | 2.25k | { | 38 | 2.25k | A += choose(D, B, C) + M; | 39 | 2.25k | A = rotl<S>(A) + B; | 40 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::GG<20ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 37 | 2.25k | { | 38 | 2.25k | A += choose(D, B, C) + M; | 39 | 2.25k | A = rotl<S>(A) + B; | 40 | 2.25k | } |
|
41 | | |
42 | | /* |
43 | | * MD5 HH Function |
44 | | */ |
45 | | template<size_t S> |
46 | | inline void HH(uint32_t& A, uint32_t B, uint32_t C, uint32_t D, uint32_t M) |
47 | 9.00k | { |
48 | 9.00k | A += (B ^ C ^ D) + M; |
49 | 9.00k | A = rotl<S>(A) + B; |
50 | 9.00k | } md5.cpp:void Botan::(anonymous namespace)::HH<4ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 47 | 2.25k | { | 48 | 2.25k | A += (B ^ C ^ D) + M; | 49 | 2.25k | A = rotl<S>(A) + B; | 50 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::HH<11ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 47 | 2.25k | { | 48 | 2.25k | A += (B ^ C ^ D) + M; | 49 | 2.25k | A = rotl<S>(A) + B; | 50 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::HH<16ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 47 | 2.25k | { | 48 | 2.25k | A += (B ^ C ^ D) + M; | 49 | 2.25k | A = rotl<S>(A) + B; | 50 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::HH<23ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 47 | 2.25k | { | 48 | 2.25k | A += (B ^ C ^ D) + M; | 49 | 2.25k | A = rotl<S>(A) + B; | 50 | 2.25k | } |
|
51 | | |
52 | | /* |
53 | | * MD5 II Function |
54 | | */ |
55 | | template<size_t S> |
56 | | inline void II(uint32_t& A, uint32_t B, uint32_t C, uint32_t D, uint32_t M) |
57 | 9.00k | { |
58 | | // This expr is choose(D, B ^ C, ~C), but that is slower |
59 | 9.00k | A += (C ^ (B | ~D)) + M; |
60 | 9.00k | A = rotl<S>(A) + B; |
61 | 9.00k | } md5.cpp:void Botan::(anonymous namespace)::II<6ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 57 | 2.25k | { | 58 | | // This expr is choose(D, B ^ C, ~C), but that is slower | 59 | 2.25k | A += (C ^ (B | ~D)) + M; | 60 | 2.25k | A = rotl<S>(A) + B; | 61 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::II<10ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 57 | 2.25k | { | 58 | | // This expr is choose(D, B ^ C, ~C), but that is slower | 59 | 2.25k | A += (C ^ (B | ~D)) + M; | 60 | 2.25k | A = rotl<S>(A) + B; | 61 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::II<15ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 57 | 2.25k | { | 58 | | // This expr is choose(D, B ^ C, ~C), but that is slower | 59 | 2.25k | A += (C ^ (B | ~D)) + M; | 60 | 2.25k | A = rotl<S>(A) + B; | 61 | 2.25k | } |
md5.cpp:void Botan::(anonymous namespace)::II<21ul>(unsigned int&, unsigned int, unsigned int, unsigned int, unsigned int) Line | Count | Source | 57 | 2.25k | { | 58 | | // This expr is choose(D, B ^ C, ~C), but that is slower | 59 | 2.25k | A += (C ^ (B | ~D)) + M; | 60 | 2.25k | A = rotl<S>(A) + B; | 61 | 2.25k | } |
|
62 | | |
63 | | } |
64 | | |
65 | | /* |
66 | | * MD5 Compression Function |
67 | | */ |
68 | | void MD5::compress_n(const uint8_t input[], size_t blocks) |
69 | 228 | { |
70 | 228 | uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3]; |
71 | | |
72 | 791 | for(size_t i = 0; i != blocks; ++i) |
73 | 563 | { |
74 | 563 | load_le(m_M.data(), input, m_M.size()); |
75 | | |
76 | 563 | FF< 7>(A,B,C,D,m_M[ 0]+0xD76AA478); FF<12>(D,A,B,C,m_M[ 1]+0xE8C7B756); |
77 | 563 | FF<17>(C,D,A,B,m_M[ 2]+0x242070DB); FF<22>(B,C,D,A,m_M[ 3]+0xC1BDCEEE); |
78 | 563 | FF< 7>(A,B,C,D,m_M[ 4]+0xF57C0FAF); FF<12>(D,A,B,C,m_M[ 5]+0x4787C62A); |
79 | 563 | FF<17>(C,D,A,B,m_M[ 6]+0xA8304613); FF<22>(B,C,D,A,m_M[ 7]+0xFD469501); |
80 | 563 | FF< 7>(A,B,C,D,m_M[ 8]+0x698098D8); FF<12>(D,A,B,C,m_M[ 9]+0x8B44F7AF); |
81 | 563 | FF<17>(C,D,A,B,m_M[10]+0xFFFF5BB1); FF<22>(B,C,D,A,m_M[11]+0x895CD7BE); |
82 | 563 | FF< 7>(A,B,C,D,m_M[12]+0x6B901122); FF<12>(D,A,B,C,m_M[13]+0xFD987193); |
83 | 563 | FF<17>(C,D,A,B,m_M[14]+0xA679438E); FF<22>(B,C,D,A,m_M[15]+0x49B40821); |
84 | | |
85 | 563 | GG< 5>(A,B,C,D,m_M[ 1]+0xF61E2562); GG< 9>(D,A,B,C,m_M[ 6]+0xC040B340); |
86 | 563 | GG<14>(C,D,A,B,m_M[11]+0x265E5A51); GG<20>(B,C,D,A,m_M[ 0]+0xE9B6C7AA); |
87 | 563 | GG< 5>(A,B,C,D,m_M[ 5]+0xD62F105D); GG< 9>(D,A,B,C,m_M[10]+0x02441453); |
88 | 563 | GG<14>(C,D,A,B,m_M[15]+0xD8A1E681); GG<20>(B,C,D,A,m_M[ 4]+0xE7D3FBC8); |
89 | 563 | GG< 5>(A,B,C,D,m_M[ 9]+0x21E1CDE6); GG< 9>(D,A,B,C,m_M[14]+0xC33707D6); |
90 | 563 | GG<14>(C,D,A,B,m_M[ 3]+0xF4D50D87); GG<20>(B,C,D,A,m_M[ 8]+0x455A14ED); |
91 | 563 | GG< 5>(A,B,C,D,m_M[13]+0xA9E3E905); GG< 9>(D,A,B,C,m_M[ 2]+0xFCEFA3F8); |
92 | 563 | GG<14>(C,D,A,B,m_M[ 7]+0x676F02D9); GG<20>(B,C,D,A,m_M[12]+0x8D2A4C8A); |
93 | | |
94 | 563 | HH< 4>(A,B,C,D,m_M[ 5]+0xFFFA3942); HH<11>(D,A,B,C,m_M[ 8]+0x8771F681); |
95 | 563 | HH<16>(C,D,A,B,m_M[11]+0x6D9D6122); HH<23>(B,C,D,A,m_M[14]+0xFDE5380C); |
96 | 563 | HH< 4>(A,B,C,D,m_M[ 1]+0xA4BEEA44); HH<11>(D,A,B,C,m_M[ 4]+0x4BDECFA9); |
97 | 563 | HH<16>(C,D,A,B,m_M[ 7]+0xF6BB4B60); HH<23>(B,C,D,A,m_M[10]+0xBEBFBC70); |
98 | 563 | HH< 4>(A,B,C,D,m_M[13]+0x289B7EC6); HH<11>(D,A,B,C,m_M[ 0]+0xEAA127FA); |
99 | 563 | HH<16>(C,D,A,B,m_M[ 3]+0xD4EF3085); HH<23>(B,C,D,A,m_M[ 6]+0x04881D05); |
100 | 563 | HH< 4>(A,B,C,D,m_M[ 9]+0xD9D4D039); HH<11>(D,A,B,C,m_M[12]+0xE6DB99E5); |
101 | 563 | HH<16>(C,D,A,B,m_M[15]+0x1FA27CF8); HH<23>(B,C,D,A,m_M[ 2]+0xC4AC5665); |
102 | | |
103 | 563 | II< 6>(A,B,C,D,m_M[ 0]+0xF4292244); II<10>(D,A,B,C,m_M[ 7]+0x432AFF97); |
104 | 563 | II<15>(C,D,A,B,m_M[14]+0xAB9423A7); II<21>(B,C,D,A,m_M[ 5]+0xFC93A039); |
105 | 563 | II< 6>(A,B,C,D,m_M[12]+0x655B59C3); II<10>(D,A,B,C,m_M[ 3]+0x8F0CCC92); |
106 | 563 | II<15>(C,D,A,B,m_M[10]+0xFFEFF47D); II<21>(B,C,D,A,m_M[ 1]+0x85845DD1); |
107 | 563 | II< 6>(A,B,C,D,m_M[ 8]+0x6FA87E4F); II<10>(D,A,B,C,m_M[15]+0xFE2CE6E0); |
108 | 563 | II<15>(C,D,A,B,m_M[ 6]+0xA3014314); II<21>(B,C,D,A,m_M[13]+0x4E0811A1); |
109 | 563 | II< 6>(A,B,C,D,m_M[ 4]+0xF7537E82); II<10>(D,A,B,C,m_M[11]+0xBD3AF235); |
110 | 563 | II<15>(C,D,A,B,m_M[ 2]+0x2AD7D2BB); II<21>(B,C,D,A,m_M[ 9]+0xEB86D391); |
111 | | |
112 | 563 | A = (m_digest[0] += A); |
113 | 563 | B = (m_digest[1] += B); |
114 | 563 | C = (m_digest[2] += C); |
115 | 563 | D = (m_digest[3] += D); |
116 | | |
117 | 563 | input += hash_block_size(); |
118 | 563 | } |
119 | 228 | } |
120 | | |
121 | | /* |
122 | | * Copy out the digest |
123 | | */ |
124 | | void MD5::copy_out(uint8_t output[]) |
125 | 113 | { |
126 | 113 | copy_out_vec_le(output, output_length(), m_digest); |
127 | 113 | } |
128 | | |
129 | | /* |
130 | | * Clear memory of sensitive data |
131 | | */ |
132 | | void MD5::clear() |
133 | 226 | { |
134 | 226 | MDx_HashFunction::clear(); |
135 | 226 | zeroise(m_M); |
136 | 226 | m_digest[0] = 0x67452301; |
137 | 226 | m_digest[1] = 0xEFCDAB89; |
138 | 226 | m_digest[2] = 0x98BADCFE; |
139 | 226 | m_digest[3] = 0x10325476; |
140 | 226 | } |
141 | | |
142 | | } |