1 /* md4.c
2
3 The MD4 hash function, described in RFC 1320.
4
5 Copyright (C) 2003 Niels Möller, Marcus Comstedt
6
7 This file is part of GNU Nettle.
8
9 GNU Nettle is free software: you can redistribute it and/or
10 modify it under the terms of either:
11
12 * the GNU Lesser General Public License as published by the Free
13 Software Foundation; either version 3 of the License, or (at your
14 option) any later version.
15
16 or
17
18 * the GNU General Public License as published by the Free
19 Software Foundation; either version 2 of the License, or (at your
20 option) any later version.
21
22 or both in parallel, as here.
23
24 GNU Nettle is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 General Public License for more details.
28
29 You should have received copies of the GNU General Public License and
30 the GNU Lesser General Public License along with this program. If
31 not, see http://www.gnu.org/licenses/.
32 */
33
34 /* Based on the public domain md5 code, and modified by Marcus
35 Comstedt */
36
37 #if HAVE_CONFIG_H
38 # include "config.h"
39 #endif
40
41 #include <assert.h>
42 #include <string.h>
43
44 #include "md4.h"
45
46 #include "macros.h"
47 #include "nettle-write.h"
48
49 /* A block, treated as a sequence of 32-bit words. */
50 #define MD4_DATA_LENGTH 16
51
52 static void
53 md4_transform(uint32_t *digest, const uint32_t *data);
54
55 static void
56 md4_compress(struct md4_ctx *ctx, const uint8_t *block);
57
58 /* FIXME: Could be an alias for md5_init */
59 void
md4_init(struct md4_ctx * ctx)60 md4_init(struct md4_ctx *ctx)
61 {
62 /* Same constants as for md5. */
63 const uint32_t iv[_MD4_DIGEST_LENGTH] =
64 {
65 0x67452301,
66 0xefcdab89,
67 0x98badcfe,
68 0x10325476,
69 };
70 memcpy(ctx->state, iv, sizeof(ctx->state));
71
72 ctx->count = 0;
73 ctx->index = 0;
74 }
75
76 void
md4_update(struct md4_ctx * ctx,size_t length,const uint8_t * data)77 md4_update(struct md4_ctx *ctx,
78 size_t length,
79 const uint8_t *data)
80 {
81 MD_UPDATE(ctx, length, data, md4_compress, ctx->count++);
82 }
83
84 void
md4_digest(struct md4_ctx * ctx,size_t length,uint8_t * digest)85 md4_digest(struct md4_ctx *ctx,
86 size_t length,
87 uint8_t *digest)
88 {
89 uint64_t bit_count;
90 uint32_t data[MD4_DATA_LENGTH];
91 unsigned i;
92
93 assert(length <= MD4_DIGEST_SIZE);
94
95 MD_PAD(ctx, 8, md4_compress);
96 for (i = 0; i < MD4_DATA_LENGTH - 2; i++)
97 data[i] = LE_READ_UINT32(ctx->block + 4*i);
98
99 /* There are 512 = 2^9 bits in one block
100 * Little-endian order => Least significant word first */
101 bit_count = (ctx->count << 9) | (ctx->index << 3);
102 data[MD4_DATA_LENGTH-2] = bit_count;
103 data[MD4_DATA_LENGTH-1] = bit_count >> 32;
104 md4_transform(ctx->state, data);
105
106 _nettle_write_le32(length, digest, ctx->state);
107 md4_init(ctx);
108 }
109
110 /* MD4 functions */
111 #define F(x, y, z) (((y) & (x)) | ((z) & ~(x)))
112 #define G(x, y, z) (((y) & (x)) | ((z) & (x)) | ((y) & (z)))
113 #define H(x, y, z) ((x) ^ (y) ^ (z))
114
115 #define ROUND(f, w, x, y, z, data, s) \
116 ( w += f(x, y, z) + data, w = w<<s | w>>(32-s) )
117
118 /* Perform the MD4 transformation on one full block of 16 32-bit words. */
119
120 static void
md4_transform(uint32_t * digest,const uint32_t * data)121 md4_transform(uint32_t *digest, const uint32_t *data)
122 {
123 uint32_t a, b, c, d;
124 a = digest[0];
125 b = digest[1];
126 c = digest[2];
127 d = digest[3];
128
129 ROUND(F, a, b, c, d, data[ 0], 3);
130 ROUND(F, d, a, b, c, data[ 1], 7);
131 ROUND(F, c, d, a, b, data[ 2], 11);
132 ROUND(F, b, c, d, a, data[ 3], 19);
133 ROUND(F, a, b, c, d, data[ 4], 3);
134 ROUND(F, d, a, b, c, data[ 5], 7);
135 ROUND(F, c, d, a, b, data[ 6], 11);
136 ROUND(F, b, c, d, a, data[ 7], 19);
137 ROUND(F, a, b, c, d, data[ 8], 3);
138 ROUND(F, d, a, b, c, data[ 9], 7);
139 ROUND(F, c, d, a, b, data[10], 11);
140 ROUND(F, b, c, d, a, data[11], 19);
141 ROUND(F, a, b, c, d, data[12], 3);
142 ROUND(F, d, a, b, c, data[13], 7);
143 ROUND(F, c, d, a, b, data[14], 11);
144 ROUND(F, b, c, d, a, data[15], 19);
145
146 ROUND(G, a, b, c, d, data[ 0] + 0x5a827999, 3);
147 ROUND(G, d, a, b, c, data[ 4] + 0x5a827999, 5);
148 ROUND(G, c, d, a, b, data[ 8] + 0x5a827999, 9);
149 ROUND(G, b, c, d, a, data[12] + 0x5a827999, 13);
150 ROUND(G, a, b, c, d, data[ 1] + 0x5a827999, 3);
151 ROUND(G, d, a, b, c, data[ 5] + 0x5a827999, 5);
152 ROUND(G, c, d, a, b, data[ 9] + 0x5a827999, 9);
153 ROUND(G, b, c, d, a, data[13] + 0x5a827999, 13);
154 ROUND(G, a, b, c, d, data[ 2] + 0x5a827999, 3);
155 ROUND(G, d, a, b, c, data[ 6] + 0x5a827999, 5);
156 ROUND(G, c, d, a, b, data[10] + 0x5a827999, 9);
157 ROUND(G, b, c, d, a, data[14] + 0x5a827999, 13);
158 ROUND(G, a, b, c, d, data[ 3] + 0x5a827999, 3);
159 ROUND(G, d, a, b, c, data[ 7] + 0x5a827999, 5);
160 ROUND(G, c, d, a, b, data[11] + 0x5a827999, 9);
161 ROUND(G, b, c, d, a, data[15] + 0x5a827999, 13);
162
163 ROUND(H, a, b, c, d, data[ 0] + 0x6ed9eba1, 3);
164 ROUND(H, d, a, b, c, data[ 8] + 0x6ed9eba1, 9);
165 ROUND(H, c, d, a, b, data[ 4] + 0x6ed9eba1, 11);
166 ROUND(H, b, c, d, a, data[12] + 0x6ed9eba1, 15);
167 ROUND(H, a, b, c, d, data[ 2] + 0x6ed9eba1, 3);
168 ROUND(H, d, a, b, c, data[10] + 0x6ed9eba1, 9);
169 ROUND(H, c, d, a, b, data[ 6] + 0x6ed9eba1, 11);
170 ROUND(H, b, c, d, a, data[14] + 0x6ed9eba1, 15);
171 ROUND(H, a, b, c, d, data[ 1] + 0x6ed9eba1, 3);
172 ROUND(H, d, a, b, c, data[ 9] + 0x6ed9eba1, 9);
173 ROUND(H, c, d, a, b, data[ 5] + 0x6ed9eba1, 11);
174 ROUND(H, b, c, d, a, data[13] + 0x6ed9eba1, 15);
175 ROUND(H, a, b, c, d, data[ 3] + 0x6ed9eba1, 3);
176 ROUND(H, d, a, b, c, data[11] + 0x6ed9eba1, 9);
177 ROUND(H, c, d, a, b, data[ 7] + 0x6ed9eba1, 11);
178 ROUND(H, b, c, d, a, data[15] + 0x6ed9eba1, 15);
179
180 digest[0] += a;
181 digest[1] += b;
182 digest[2] += c;
183 digest[3] += d;
184 }
185
186 static void
md4_compress(struct md4_ctx * ctx,const uint8_t * block)187 md4_compress(struct md4_ctx *ctx, const uint8_t *block)
188 {
189 uint32_t data[MD4_DATA_LENGTH];
190 unsigned i;
191
192 /* Endian independent conversion */
193 for (i = 0; i<16; i++, block += 4)
194 data[i] = LE_READ_UINT32(block);
195
196 md4_transform(ctx->state, data);
197 }
198