Botan  2.1.0
Crypto and TLS for C++11
md4.cpp
Go to the documentation of this file.
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/md4.h>
9 
10 namespace Botan {
11 
12 namespace {
13 
14 /*
15 * MD4 FF Function
16 */
17 inline void FF(uint32_t& A, uint32_t B, uint32_t C, uint32_t D, uint32_t M, uint8_t S)
18  {
19  A += (D ^ (B & (C ^ D))) + M;
20  A = rotate_left(A, S);
21  }
22 
23 /*
24 * MD4 GG Function
25 */
26 inline void GG(uint32_t& A, uint32_t B, uint32_t C, uint32_t D, uint32_t M, uint8_t S)
27  {
28  A += ((B & C) | (D & (B | C))) + M + 0x5A827999;
29  A = rotate_left(A, S);
30  }
31 
32 /*
33 * MD4 HH Function
34 */
35 inline void HH(uint32_t& A, uint32_t B, uint32_t C, uint32_t D, uint32_t M, uint8_t S)
36  {
37  A += (B ^ C ^ D) + M + 0x6ED9EBA1;
38  A = rotate_left(A, S);
39  }
40 
41 }
42 
43 /*
44 * MD4 Compression Function
45 */
46 void MD4::compress_n(const uint8_t input[], size_t blocks)
47  {
48  uint32_t A = m_digest[0], B = m_digest[1], C = m_digest[2], D = m_digest[3];
49 
50  for(size_t i = 0; i != blocks; ++i)
51  {
52  load_le(m_M.data(), input, m_M.size());
53 
54  FF(A,B,C,D,m_M[ 0], 3); FF(D,A,B,C,m_M[ 1], 7);
55  FF(C,D,A,B,m_M[ 2],11); FF(B,C,D,A,m_M[ 3],19);
56  FF(A,B,C,D,m_M[ 4], 3); FF(D,A,B,C,m_M[ 5], 7);
57  FF(C,D,A,B,m_M[ 6],11); FF(B,C,D,A,m_M[ 7],19);
58  FF(A,B,C,D,m_M[ 8], 3); FF(D,A,B,C,m_M[ 9], 7);
59  FF(C,D,A,B,m_M[10],11); FF(B,C,D,A,m_M[11],19);
60  FF(A,B,C,D,m_M[12], 3); FF(D,A,B,C,m_M[13], 7);
61  FF(C,D,A,B,m_M[14],11); FF(B,C,D,A,m_M[15],19);
62 
63  GG(A,B,C,D,m_M[ 0], 3); GG(D,A,B,C,m_M[ 4], 5);
64  GG(C,D,A,B,m_M[ 8], 9); GG(B,C,D,A,m_M[12],13);
65  GG(A,B,C,D,m_M[ 1], 3); GG(D,A,B,C,m_M[ 5], 5);
66  GG(C,D,A,B,m_M[ 9], 9); GG(B,C,D,A,m_M[13],13);
67  GG(A,B,C,D,m_M[ 2], 3); GG(D,A,B,C,m_M[ 6], 5);
68  GG(C,D,A,B,m_M[10], 9); GG(B,C,D,A,m_M[14],13);
69  GG(A,B,C,D,m_M[ 3], 3); GG(D,A,B,C,m_M[ 7], 5);
70  GG(C,D,A,B,m_M[11], 9); GG(B,C,D,A,m_M[15],13);
71 
72  HH(A,B,C,D,m_M[ 0], 3); HH(D,A,B,C,m_M[ 8], 9);
73  HH(C,D,A,B,m_M[ 4],11); HH(B,C,D,A,m_M[12],15);
74  HH(A,B,C,D,m_M[ 2], 3); HH(D,A,B,C,m_M[10], 9);
75  HH(C,D,A,B,m_M[ 6],11); HH(B,C,D,A,m_M[14],15);
76  HH(A,B,C,D,m_M[ 1], 3); HH(D,A,B,C,m_M[ 9], 9);
77  HH(C,D,A,B,m_M[ 5],11); HH(B,C,D,A,m_M[13],15);
78  HH(A,B,C,D,m_M[ 3], 3); HH(D,A,B,C,m_M[11], 9);
79  HH(C,D,A,B,m_M[ 7],11); HH(B,C,D,A,m_M[15],15);
80 
81  A = (m_digest[0] += A);
82  B = (m_digest[1] += B);
83  C = (m_digest[2] += C);
84  D = (m_digest[3] += D);
85 
86  input += hash_block_size();
87  }
88  }
89 
90 /*
91 * Copy out the digest
92 */
93 void MD4::copy_out(uint8_t output[])
94  {
95  copy_out_vec_le(output, output_length(), m_digest);
96  }
97 
98 /*
99 * Clear memory of sensitive data
100 */
102  {
104  zeroise(m_M);
105  m_digest[0] = 0x67452301;
106  m_digest[1] = 0xEFCDAB89;
107  m_digest[2] = 0x98BADCFE;
108  m_digest[3] = 0x10325476;
109  }
110 
111 }
void clear() override
Definition: mdx_hash.cpp:32
T rotate_left(T input, size_t rot)
Definition: rotate.h:21
size_t hash_block_size() const override
Definition: mdx_hash.h:32
size_t output_length() const override
Definition: md4.h:22
void clear() override
Definition: md4.cpp:101
void compress_n(const uint8_t input[], size_t blocks) override
Definition: md4.cpp:46
T load_le(const uint8_t in[], size_t off)
Definition: loadstor.h:129
Definition: alg_id.cpp:13
void copy_out(uint8_t[]) override
Definition: md4.cpp:93
void zeroise(std::vector< T, Alloc > &vec)
Definition: secmem.h:211
void copy_out_vec_le(uint8_t out[], size_t out_bytes, const std::vector< T, Alloc > &in)
Definition: loadstor.h:697