Coverage Report

Created: 2024-02-25 06:16

/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
10
#include <botan/internal/bit_ops.h>
11
#include <botan/internal/loadstor.h>
12
#include <botan/internal/rotate.h>
13
14
namespace Botan {
15
16
namespace {
17
18
inline void FF4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D, uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
19
20
1.30M
{
21
1.30M
   A += choose(B, C, D) + M0;
22
1.30M
   A = rotl<3>(A);
23
24
1.30M
   D += choose(A, B, C) + M1;
25
1.30M
   D = rotl<7>(D);
26
27
1.30M
   C += choose(D, A, B) + M2;
28
1.30M
   C = rotl<11>(C);
29
30
1.30M
   B += choose(C, D, A) + M3;
31
1.30M
   B = rotl<19>(B);
32
1.30M
}
33
34
inline void GG4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D, uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
35
36
1.30M
{
37
   /*
38
   These are choose(D, B | C, B & C) but the below expression
39
   takes advantage of the fact that B & C is a subset of B | C
40
   to eliminate an and
41
   */
42
43
1.30M
   A += ((B & C) | (D & (B | C))) + M0 + 0x5A827999;
44
1.30M
   A = rotl<3>(A);
45
46
1.30M
   D += ((A & B) | (C & (A | B))) + M1 + 0x5A827999;
47
1.30M
   D = rotl<5>(D);
48
49
1.30M
   C += ((D & A) | (B & (D | A))) + M2 + 0x5A827999;
50
1.30M
   C = rotl<9>(C);
51
52
1.30M
   B += ((C & D) | (A & (C | D))) + M3 + 0x5A827999;
53
1.30M
   B = rotl<13>(B);
54
1.30M
}
55
56
inline void HH4(uint32_t& A, uint32_t& B, uint32_t& C, uint32_t& D, uint32_t M0, uint32_t M1, uint32_t M2, uint32_t M3)
57
58
1.30M
{
59
1.30M
   A += (B ^ C ^ D) + M0 + 0x6ED9EBA1;
60
1.30M
   A = rotl<3>(A);
61
62
1.30M
   D += (A ^ B ^ C) + M1 + 0x6ED9EBA1;
63
1.30M
   D = rotl<9>(D);
64
65
1.30M
   C += (A ^ B ^ D) + M2 + 0x6ED9EBA1;
66
1.30M
   C = rotl<11>(C);
67
68
1.30M
   B += (A ^ C ^ D) + M3 + 0x6ED9EBA1;
69
1.30M
   B = rotl<15>(B);
70
1.30M
}
71
72
}  // namespace
73
74
/*
75
* MD4 Compression Function
76
*/
77
299k
void MD4::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
78
299k
   uint32_t A = digest[0], B = digest[1], C = digest[2], D = digest[3];
79
80
299k
   BufferSlicer in(input);
81
82
624k
   for(size_t i = 0; i != blocks; ++i) {
83
325k
      const auto block = in.take(block_bytes).data();
84
85
325k
      uint32_t M00 = load_le<uint32_t>(block, 0);
86
325k
      uint32_t M01 = load_le<uint32_t>(block, 1);
87
325k
      uint32_t M02 = load_le<uint32_t>(block, 2);
88
325k
      uint32_t M03 = load_le<uint32_t>(block, 3);
89
325k
      uint32_t M04 = load_le<uint32_t>(block, 4);
90
325k
      uint32_t M05 = load_le<uint32_t>(block, 5);
91
325k
      uint32_t M06 = load_le<uint32_t>(block, 6);
92
325k
      uint32_t M07 = load_le<uint32_t>(block, 7);
93
325k
      uint32_t M08 = load_le<uint32_t>(block, 8);
94
325k
      uint32_t M09 = load_le<uint32_t>(block, 9);
95
325k
      uint32_t M10 = load_le<uint32_t>(block, 10);
96
325k
      uint32_t M11 = load_le<uint32_t>(block, 11);
97
325k
      uint32_t M12 = load_le<uint32_t>(block, 12);
98
325k
      uint32_t M13 = load_le<uint32_t>(block, 13);
99
325k
      uint32_t M14 = load_le<uint32_t>(block, 14);
100
325k
      uint32_t M15 = load_le<uint32_t>(block, 15);
101
102
325k
      FF4(A, B, C, D, M00, M01, M02, M03);
103
325k
      FF4(A, B, C, D, M04, M05, M06, M07);
104
325k
      FF4(A, B, C, D, M08, M09, M10, M11);
105
325k
      FF4(A, B, C, D, M12, M13, M14, M15);
106
107
325k
      GG4(A, B, C, D, M00, M04, M08, M12);
108
325k
      GG4(A, B, C, D, M01, M05, M09, M13);
109
325k
      GG4(A, B, C, D, M02, M06, M10, M14);
110
325k
      GG4(A, B, C, D, M03, M07, M11, M15);
111
112
325k
      HH4(A, B, C, D, M00, M08, M04, M12);
113
325k
      HH4(A, B, C, D, M02, M10, M06, M14);
114
325k
      HH4(A, B, C, D, M01, M09, M05, M13);
115
325k
      HH4(A, B, C, D, M03, M11, M07, M15);
116
117
325k
      A = (digest[0] += A);
118
325k
      B = (digest[1] += B);
119
325k
      C = (digest[2] += C);
120
325k
      D = (digest[3] += D);
121
325k
   }
122
123
299k
   BOTAN_ASSERT_NOMSG(in.empty());
124
299k
}
125
126
146k
void MD4::init(digest_type& digest) {
127
146k
   digest.assign({0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476});
128
146k
}
129
130
71
std::unique_ptr<HashFunction> MD4::new_object() const {
131
71
   return std::make_unique<MD4>();
132
71
}
133
134
0
std::unique_ptr<HashFunction> MD4::copy_state() const {
135
0
   return std::make_unique<MD4>(*this);
136
0
}
137
138
485k
void MD4::add_data(std::span<const uint8_t> input) {
139
485k
   m_md.update(input);
140
485k
}
141
142
146k
void MD4::final_result(std::span<uint8_t> output) {
143
146k
   m_md.final(output);
144
146k
}
145
146
}  // namespace Botan