1 /*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10 #include <openssl/md4.h>
11
12 #include <stdlib.h>
13 #include <string.h>
14
15 #include "../fipsmodule/digest/md32_common.h"
16 #include "../internal.h"
17
18
MD4(const uint8_t * data,size_t len,uint8_t out[MD4_DIGEST_LENGTH])19 uint8_t *MD4(const uint8_t *data, size_t len, uint8_t out[MD4_DIGEST_LENGTH]) {
20 MD4_CTX ctx;
21 MD4_Init(&ctx);
22 MD4_Update(&ctx, data, len);
23 MD4_Final(out, &ctx);
24
25 return out;
26 }
27
28 // Implemented from RFC 1186 The MD4 Message-Digest Algorithm.
29
MD4_Init(MD4_CTX * md4)30 int MD4_Init(MD4_CTX *md4) {
31 OPENSSL_memset(md4, 0, sizeof(MD4_CTX));
32 md4->h[0] = 0x67452301UL;
33 md4->h[1] = 0xefcdab89UL;
34 md4->h[2] = 0x98badcfeUL;
35 md4->h[3] = 0x10325476UL;
36 return 1;
37 }
38
39 static void md4_block_data_order(uint32_t *state, const uint8_t *data,
40 size_t num);
41
MD4_Transform(MD4_CTX * c,const uint8_t data[MD4_CBLOCK])42 void MD4_Transform(MD4_CTX *c, const uint8_t data[MD4_CBLOCK]) {
43 md4_block_data_order(c->h, data, 1);
44 }
45
MD4_Update(MD4_CTX * c,const void * data,size_t len)46 int MD4_Update(MD4_CTX *c, const void *data, size_t len) {
47 crypto_md32_update(&md4_block_data_order, c->h, c->data, MD4_CBLOCK, &c->num,
48 &c->Nh, &c->Nl, reinterpret_cast<const uint8_t *>(data),
49 len);
50 return 1;
51 }
52
MD4_Final(uint8_t out[MD4_DIGEST_LENGTH],MD4_CTX * c)53 int MD4_Final(uint8_t out[MD4_DIGEST_LENGTH], MD4_CTX *c) {
54 crypto_md32_final(&md4_block_data_order, c->h, c->data, MD4_CBLOCK, &c->num,
55 c->Nh, c->Nl, /*is_big_endian=*/0);
56
57 CRYPTO_store_u32_le(out, c->h[0]);
58 CRYPTO_store_u32_le(out + 4, c->h[1]);
59 CRYPTO_store_u32_le(out + 8, c->h[2]);
60 CRYPTO_store_u32_le(out + 12, c->h[3]);
61 return 1;
62 }
63
64 // As pointed out by Wei Dai <weidai@eskimo.com>, the above can be
65 // simplified to the code below. Wei attributes these optimizations
66 // to Peter Gutmann's SHS code, and he attributes it to Rich Schroeppel.
67 #define F(b, c, d) ((((c) ^ (d)) & (b)) ^ (d))
68 #define G(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
69 #define H(b, c, d) ((b) ^ (c) ^ (d))
70
71 #define R0(a, b, c, d, k, s, t) \
72 do { \
73 (a) += ((k) + (t) + F((b), (c), (d))); \
74 (a) = CRYPTO_rotl_u32(a, s); \
75 } while (0)
76
77 #define R1(a, b, c, d, k, s, t) \
78 do { \
79 (a) += ((k) + (t) + G((b), (c), (d))); \
80 (a) = CRYPTO_rotl_u32(a, s); \
81 } while (0)
82
83 #define R2(a, b, c, d, k, s, t) \
84 do { \
85 (a) += ((k) + (t) + H((b), (c), (d))); \
86 (a) = CRYPTO_rotl_u32(a, s); \
87 } while (0)
88
md4_block_data_order(uint32_t * state,const uint8_t * data,size_t num)89 static void md4_block_data_order(uint32_t *state, const uint8_t *data,
90 size_t num) {
91 uint32_t A, B, C, D;
92 uint32_t X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15;
93
94 A = state[0];
95 B = state[1];
96 C = state[2];
97 D = state[3];
98
99 for (; num--;) {
100 X0 = CRYPTO_load_u32_le(data);
101 data += 4;
102 X1 = CRYPTO_load_u32_le(data);
103 data += 4;
104 // Round 0
105 R0(A, B, C, D, X0, 3, 0);
106 X2 = CRYPTO_load_u32_le(data);
107 data += 4;
108 R0(D, A, B, C, X1, 7, 0);
109 X3 = CRYPTO_load_u32_le(data);
110 data += 4;
111 R0(C, D, A, B, X2, 11, 0);
112 X4 = CRYPTO_load_u32_le(data);
113 data += 4;
114 R0(B, C, D, A, X3, 19, 0);
115 X5 = CRYPTO_load_u32_le(data);
116 data += 4;
117 R0(A, B, C, D, X4, 3, 0);
118 X6 = CRYPTO_load_u32_le(data);
119 data += 4;
120 R0(D, A, B, C, X5, 7, 0);
121 X7 = CRYPTO_load_u32_le(data);
122 data += 4;
123 R0(C, D, A, B, X6, 11, 0);
124 X8 = CRYPTO_load_u32_le(data);
125 data += 4;
126 R0(B, C, D, A, X7, 19, 0);
127 X9 = CRYPTO_load_u32_le(data);
128 data += 4;
129 R0(A, B, C, D, X8, 3, 0);
130 X10 = CRYPTO_load_u32_le(data);
131 data += 4;
132 R0(D, A, B, C, X9, 7, 0);
133 X11 = CRYPTO_load_u32_le(data);
134 data += 4;
135 R0(C, D, A, B, X10, 11, 0);
136 X12 = CRYPTO_load_u32_le(data);
137 data += 4;
138 R0(B, C, D, A, X11, 19, 0);
139 X13 = CRYPTO_load_u32_le(data);
140 data += 4;
141 R0(A, B, C, D, X12, 3, 0);
142 X14 = CRYPTO_load_u32_le(data);
143 data += 4;
144 R0(D, A, B, C, X13, 7, 0);
145 X15 = CRYPTO_load_u32_le(data);
146 data += 4;
147 R0(C, D, A, B, X14, 11, 0);
148 R0(B, C, D, A, X15, 19, 0);
149 // Round 1
150 R1(A, B, C, D, X0, 3, 0x5A827999L);
151 R1(D, A, B, C, X4, 5, 0x5A827999L);
152 R1(C, D, A, B, X8, 9, 0x5A827999L);
153 R1(B, C, D, A, X12, 13, 0x5A827999L);
154 R1(A, B, C, D, X1, 3, 0x5A827999L);
155 R1(D, A, B, C, X5, 5, 0x5A827999L);
156 R1(C, D, A, B, X9, 9, 0x5A827999L);
157 R1(B, C, D, A, X13, 13, 0x5A827999L);
158 R1(A, B, C, D, X2, 3, 0x5A827999L);
159 R1(D, A, B, C, X6, 5, 0x5A827999L);
160 R1(C, D, A, B, X10, 9, 0x5A827999L);
161 R1(B, C, D, A, X14, 13, 0x5A827999L);
162 R1(A, B, C, D, X3, 3, 0x5A827999L);
163 R1(D, A, B, C, X7, 5, 0x5A827999L);
164 R1(C, D, A, B, X11, 9, 0x5A827999L);
165 R1(B, C, D, A, X15, 13, 0x5A827999L);
166 // Round 2
167 R2(A, B, C, D, X0, 3, 0x6ED9EBA1L);
168 R2(D, A, B, C, X8, 9, 0x6ED9EBA1L);
169 R2(C, D, A, B, X4, 11, 0x6ED9EBA1L);
170 R2(B, C, D, A, X12, 15, 0x6ED9EBA1L);
171 R2(A, B, C, D, X2, 3, 0x6ED9EBA1L);
172 R2(D, A, B, C, X10, 9, 0x6ED9EBA1L);
173 R2(C, D, A, B, X6, 11, 0x6ED9EBA1L);
174 R2(B, C, D, A, X14, 15, 0x6ED9EBA1L);
175 R2(A, B, C, D, X1, 3, 0x6ED9EBA1L);
176 R2(D, A, B, C, X9, 9, 0x6ED9EBA1L);
177 R2(C, D, A, B, X5, 11, 0x6ED9EBA1L);
178 R2(B, C, D, A, X13, 15, 0x6ED9EBA1L);
179 R2(A, B, C, D, X3, 3, 0x6ED9EBA1L);
180 R2(D, A, B, C, X11, 9, 0x6ED9EBA1L);
181 R2(C, D, A, B, X7, 11, 0x6ED9EBA1L);
182 R2(B, C, D, A, X15, 15, 0x6ED9EBA1L);
183
184 A = state[0] += A;
185 B = state[1] += B;
186 C = state[2] += C;
187 D = state[3] += D;
188 }
189 }
190