Coverage Report

Created: 2026-01-22 06:19

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/nss/botan/src/lib/hash/md4/md4.cpp
Line
Count
Source
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
157k
{
21
157k
   A += choose(B, C, D) + M0;
22
157k
   A = rotl<3>(A);
23
24
157k
   D += choose(A, B, C) + M1;
25
157k
   D = rotl<7>(D);
26
27
157k
   C += choose(D, A, B) + M2;
28
157k
   C = rotl<11>(C);
29
30
157k
   B += choose(C, D, A) + M3;
31
157k
   B = rotl<19>(B);
32
157k
}
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
157k
{
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
157k
   A += ((B & C) | (D & (B | C))) + M0 + 0x5A827999;
44
157k
   A = rotl<3>(A);
45
46
157k
   D += ((A & B) | (C & (A | B))) + M1 + 0x5A827999;
47
157k
   D = rotl<5>(D);
48
49
157k
   C += ((D & A) | (B & (D | A))) + M2 + 0x5A827999;
50
157k
   C = rotl<9>(C);
51
52
157k
   B += ((C & D) | (A & (C | D))) + M3 + 0x5A827999;
53
157k
   B = rotl<13>(B);
54
157k
}
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
157k
{
59
157k
   A += (B ^ C ^ D) + M0 + 0x6ED9EBA1;
60
157k
   A = rotl<3>(A);
61
62
157k
   D += (A ^ B ^ C) + M1 + 0x6ED9EBA1;
63
157k
   D = rotl<9>(D);
64
65
157k
   C += (A ^ B ^ D) + M2 + 0x6ED9EBA1;
66
157k
   C = rotl<11>(C);
67
68
157k
   B += (A ^ C ^ D) + M3 + 0x6ED9EBA1;
69
157k
   B = rotl<15>(B);
70
157k
}
71
72
}  // namespace
73
74
/*
75
* MD4 Compression Function
76
*/
77
37.5k
void MD4::compress_n(digest_type& digest, std::span<const uint8_t> input, size_t blocks) {
78
37.5k
   uint32_t A = digest[0];
79
37.5k
   uint32_t B = digest[1];
80
37.5k
   uint32_t C = digest[2];
81
37.5k
   uint32_t D = digest[3];
82
83
37.5k
   BufferSlicer in(input);
84
85
37.5k
   std::array<uint32_t, 16> M{};
86
87
76.8k
   for(size_t i = 0; i != blocks; ++i) {
88
39.3k
      load_le(M, in.take<block_bytes>());
89
90
      // clang-format off
91
92
39.3k
      FF4(A, B, C, D, M[ 0], M[ 1], M[ 2], M[ 3]);
93
39.3k
      FF4(A, B, C, D, M[ 4], M[ 5], M[ 6], M[ 7]);
94
39.3k
      FF4(A, B, C, D, M[ 8], M[ 9], M[10], M[11]);
95
39.3k
      FF4(A, B, C, D, M[12], M[13], M[14], M[15]);
96
97
39.3k
      GG4(A, B, C, D, M[ 0], M[ 4], M[ 8], M[12]);
98
39.3k
      GG4(A, B, C, D, M[ 1], M[ 5], M[ 9], M[13]);
99
39.3k
      GG4(A, B, C, D, M[ 2], M[ 6], M[10], M[14]);
100
39.3k
      GG4(A, B, C, D, M[ 3], M[ 7], M[11], M[15]);
101
102
39.3k
      HH4(A, B, C, D, M[ 0], M[ 8], M[ 4], M[12]);
103
39.3k
      HH4(A, B, C, D, M[ 2], M[10], M[ 6], M[14]);
104
39.3k
      HH4(A, B, C, D, M[ 1], M[ 9], M[ 5], M[13]);
105
39.3k
      HH4(A, B, C, D, M[ 3], M[11], M[ 7], M[15]);
106
107
      // clang-format on
108
109
39.3k
      A = (digest[0] += A);
110
39.3k
      B = (digest[1] += B);
111
39.3k
      C = (digest[2] += C);
112
39.3k
      D = (digest[3] += D);
113
39.3k
   }
114
115
37.5k
   BOTAN_ASSERT_NOMSG(in.empty());
116
37.5k
}
117
118
16.4k
void MD4::init(digest_type& digest) {
119
16.4k
   digest.assign({0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476});
120
16.4k
}
121
122
53
std::unique_ptr<HashFunction> MD4::new_object() const {
123
53
   return std::make_unique<MD4>();
124
53
}
125
126
0
std::unique_ptr<HashFunction> MD4::copy_state() const {
127
0
   return std::make_unique<MD4>(*this);
128
0
}
129
130
55.4k
void MD4::add_data(std::span<const uint8_t> input) {
131
55.4k
   m_md.update(input);
132
55.4k
}
133
134
16.2k
void MD4::final_result(std::span<uint8_t> output) {
135
16.2k
   m_md.final(output);
136
16.2k
}
137
138
}  // namespace Botan