Coverage Report

Created: 2021-02-21 07:20

/src/botan/src/lib/hash/md4/md4.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* MD4
3
* (C) 1999-2007 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/md4.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> MD4::copy_state() const
16
0
   {
17
0
   return std::unique_ptr<HashFunction>(new MD4(*this));
18
0
   }
19
20
namespace {
21
22
inline void FF4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D,
23
                uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
24
25
0
   {
26
0
   A += choose(B, C, D) + M0;
27
0
   A = rotl<3>(A);
28
29
0
   D += choose(A, B, C) + M1;
30
0
   D = rotl<7>(D);
31
32
0
   C += choose(D, A, B) + M2;
33
0
   C = rotl<11>(C);
34
35
0
   B += choose(C, D, A) + M3;
36
0
   B = rotl<19>(B);
37
0
   }
38
39
inline void GG4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D,
40
                uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
41
42
0
   {
43
   /*
44
   These are choose(D, B | C, B & C) but the below expression
45
   takes advantage of the fact that B & C is a subset of B | C
46
   to eliminate an and
47
   */
48
49
0
   A += ((B & C) | (D & (B | C))) + M0 + 0x5A827999;
50
0
   A = rotl<3>(A);
51
52
0
   D += ((A & B) | (C & (A | B))) + M1 + 0x5A827999;
53
0
   D = rotl<5>(D);
54
55
0
   C += ((D & A) | (B & (D | A))) + M2 + 0x5A827999;
56
0
   C = rotl<9>(C);
57
58
0
   B += ((C & D) | (A & (C | D))) + M3 + 0x5A827999;
59
0
   B = rotl<13>(B);
60
0
   }
61
62
inline void HH4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D,
63
                uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
64
65
0
   {
66
0
   A += (B ^ C ^ D) + M0 + 0x6ED9EBA1;
67
0
   A = rotl<3>(A);
68
69
0
   D += (A ^ B ^ C) + M1 + 0x6ED9EBA1;
70
0
   D = rotl<9>(D);
71
72
0
   C += (A ^ B ^ D) + M2 + 0x6ED9EBA1;
73
0
   C = rotl<11>(C);
74
75
0
   B += (A ^ C ^ D) + M3 + 0x6ED9EBA1;
76
0
   B = rotl<15>(B);
77
0
   }
78
79
}
80
81
/*
82
* MD4 Compression Function
83
*/
84
void MD4::compress_n(const uint8_t input[], size_t blocks)
85
0
   {
86
0
   uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3];
87
88
0
   for(size_t i = 0; i != blocks; ++i)
89
0
      {
90
0
      uint32_t M00 = load_le<uint32_t>(input, 0);
91
0
      uint32_t M01 = load_le<uint32_t>(input, 1);
92
0
      uint32_t M02 = load_le<uint32_t>(input, 2);
93
0
      uint32_t M03 = load_le<uint32_t>(input, 3);
94
0
      uint32_t M04 = load_le<uint32_t>(input, 4);
95
0
      uint32_t M05 = load_le<uint32_t>(input, 5);
96
0
      uint32_t M06 = load_le<uint32_t>(input, 6);
97
0
      uint32_t M07 = load_le<uint32_t>(input, 7);
98
0
      uint32_t M08 = load_le<uint32_t>(input, 8);
99
0
      uint32_t M09 = load_le<uint32_t>(input, 9);
100
0
      uint32_t M10 = load_le<uint32_t>(input, 10);
101
0
      uint32_t M11 = load_le<uint32_t>(input, 11);
102
0
      uint32_t M12 = load_le<uint32_t>(input, 12);
103
0
      uint32_t M13 = load_le<uint32_t>(input, 13);
104
0
      uint32_t M14 = load_le<uint32_t>(input, 14);
105
0
      uint32_t M15 = load_le<uint32_t>(input, 15);
106
107
0
      FF4(A, B, C, D, M00, M01, M02, M03);
108
0
      FF4(A, B, C, D, M04, M05, M06, M07);
109
0
      FF4(A, B, C, D, M08, M09, M10, M11);
110
0
      FF4(A, B, C, D, M12, M13, M14, M15);
111
112
0
      GG4(A, B, C, D, M00, M04, M08, M12);
113
0
      GG4(A, B, C, D, M01, M05, M09, M13);
114
0
      GG4(A, B, C, D, M02, M06, M10, M14);
115
0
      GG4(A, B, C, D, M03, M07, M11, M15);
116
117
0
      HH4(A, B, C, D, M00, M08, M04, M12);
118
0
      HH4(A, B, C, D, M02, M10, M06, M14);
119
0
      HH4(A, B, C, D, M01, M09, M05, M13);
120
0
      HH4(A, B, C, D, M03, M11, M07, M15);
121
122
0
      A = (m_digest[0] += A);
123
0
      B = (m_digest[1] += B);
124
0
      C = (m_digest[2] += C);
125
0
      D = (m_digest[3] += D);
126
127
0
      input += hash_block_size();
128
0
      }
129
0
   }
130
131
/*
132
* Copy out the digest
133
*/
134
void MD4::copy_out(uint8_t output[])
135
0
   {
136
0
   copy_out_vec_le(output, output_length(), m_digest);
137
0
   }
138
139
/*
140
* Clear memory of sensitive data
141
*/
142
void MD4::clear()
143
0
   {
144
0
   MDx_HashFunction::clear();
145
0
   m_digest[0] = 0x67452301;
146
0
   m_digest[1] = 0xEFCDAB89;
147
0
   m_digest[2] = 0x98BADCFE;
148
0
   m_digest[3] = 0x10325476;
149
0
   }
150
151
}