OLD | NEW |
---|---|
1 // This is mozilla/security/manager/ssl/src/md4.c, CVS rev. 1.1, with trivial | 1 // This is mozilla/security/manager/ssl/src/md4.c, CVS rev. 1.1, with trivial |
2 // changes to port it to our source tree. | 2 // changes to port it to our source tree. |
Ryan Sleevi
2017/07/12 17:56:38
The style formatting means much larger changes.
P
zentaro
2017/07/13 17:10:19
Done.
| |
3 // | 3 // |
4 // WARNING: MD4 is cryptographically weak. Do not use MD4 except in NTLM | 4 // WARNING: MD4 is cryptographically weak. Do not use MD4 except in NTLM |
5 // authentication. | 5 // authentication. |
6 | 6 |
7 /* vim:set ts=2 sw=2 et cindent: */ | 7 /* vim:set ts=2 sw=2 et cindent: */ |
8 /* ***** BEGIN LICENSE BLOCK ***** | 8 /* ***** BEGIN LICENSE BLOCK ***** |
9 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 9 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
10 * | 10 * |
11 * The contents of this file are subject to the Mozilla Public License Version | 11 * The contents of this file are subject to the Mozilla Public License Version |
12 * 1.1 (the "License"); you may not use this file except in compliance with | 12 * 1.1 (the "License"); you may not use this file except in compliance with |
(...skipping 25 matching lines...) Expand all Loading... | |
38 * and other provisions required by the GPL or the LGPL. If you do not delete | 38 * and other provisions required by the GPL or the LGPL. If you do not delete |
39 * the provisions above, a recipient may use your version of this file under | 39 * the provisions above, a recipient may use your version of this file under |
40 * the terms of any one of the MPL, the GPL or the LGPL. | 40 * the terms of any one of the MPL, the GPL or the LGPL. |
41 * | 41 * |
42 * ***** END LICENSE BLOCK ***** */ | 42 * ***** END LICENSE BLOCK ***** */ |
43 | 43 |
44 /* | 44 /* |
45 * "clean room" MD4 implementation (see RFC 1320) | 45 * "clean room" MD4 implementation (see RFC 1320) |
46 */ | 46 */ |
47 | 47 |
48 #include "net/http/md4.h" | 48 #include "net/ntlm/md4.h" |
49 | 49 |
50 #include <string.h> | 50 #include <string.h> |
51 | 51 |
52 typedef uint32_t Uint32; | 52 typedef uint32_t Uint32; |
53 typedef uint8_t Uint8; | 53 typedef uint8_t Uint8; |
54 | 54 |
55 /* the "conditional" function */ | 55 /* the "conditional" function */ |
56 #define F(x,y,z) (((x) & (y)) | (~(x) & (z))) | 56 #define F(x, y, z) (((x) & (y)) | (~(x) & (z))) |
57 | 57 |
58 /* the "majority" function */ | 58 /* the "majority" function */ |
59 #define G(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) | 59 #define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) |
60 | 60 |
61 /* the "parity" function */ | 61 /* the "parity" function */ |
62 #define H(x,y,z) ((x) ^ (y) ^ (z)) | 62 #define H(x, y, z) ((x) ^ (y) ^ (z)) |
63 | 63 |
64 /* rotate n-bits to the left */ | 64 /* rotate n-bits to the left */ |
65 #define ROTL(x,n) (((x) << (n)) | ((x) >> (0x20 - n))) | 65 #define ROTL(x, n) (((x) << (n)) | ((x) >> (0x20 - n))) |
66 | 66 |
67 /* round 1: [abcd k s]: a = (a + F(b,c,d) + X[k]) <<< s */ | 67 /* round 1: [abcd k s]: a = (a + F(b,c,d) + X[k]) <<< s */ |
68 #define RD1(a,b,c,d,k,s) a += F(b,c,d) + X[k]; a = ROTL(a,s) | 68 #define RD1(a, b, c, d, k, s) \ |
69 a += F(b, c, d) + X[k]; \ | |
70 a = ROTL(a, s) | |
69 | 71 |
70 /* round 2: [abcd k s]: a = (a + G(b,c,d) + X[k] + MAGIC) <<< s */ | 72 /* round 2: [abcd k s]: a = (a + G(b,c,d) + X[k] + MAGIC) <<< s */ |
71 #define RD2(a,b,c,d,k,s) a += G(b,c,d) + X[k] + 0x5A827999; a = ROTL(a,s) | 73 #define RD2(a, b, c, d, k, s) \ |
74 a += G(b, c, d) + X[k] + 0x5A827999; \ | |
75 a = ROTL(a, s) | |
72 | 76 |
73 /* round 3: [abcd k s]: a = (a + H(b,c,d) + X[k] + MAGIC) <<< s */ | 77 /* round 3: [abcd k s]: a = (a + H(b,c,d) + X[k] + MAGIC) <<< s */ |
74 #define RD3(a,b,c,d,k,s) a += H(b,c,d) + X[k] + 0x6ED9EBA1; a = ROTL(a,s) | 78 #define RD3(a, b, c, d, k, s) \ |
79 a += H(b, c, d) + X[k] + 0x6ED9EBA1; \ | |
80 a = ROTL(a, s) | |
75 | 81 |
76 /* converts from word array to byte array, len is number of bytes */ | 82 /* converts from word array to byte array, len is number of bytes */ |
77 static void w2b(Uint8 *out, const Uint32 *in, Uint32 len) | 83 static void w2b(Uint8* out, const Uint32* in, Uint32 len) { |
78 { | 84 Uint8* bp; |
79 Uint8 *bp; const Uint32 *wp, *wpend; | 85 const Uint32 *wp, *wpend; |
80 | 86 |
81 bp = out; | 87 bp = out; |
82 wp = in; | 88 wp = in; |
83 wpend = wp + (len >> 2); | 89 wpend = wp + (len >> 2); |
84 | 90 |
85 for (; wp != wpend; ++wp, bp += 4) | 91 for (; wp != wpend; ++wp, bp += 4) { |
86 { | 92 bp[0] = (Uint8)((*wp) & 0xFF); |
87 bp[0] = (Uint8) ((*wp ) & 0xFF); | 93 bp[1] = (Uint8)((*wp >> 8) & 0xFF); |
88 bp[1] = (Uint8) ((*wp >> 8) & 0xFF); | 94 bp[2] = (Uint8)((*wp >> 16) & 0xFF); |
89 bp[2] = (Uint8) ((*wp >> 16) & 0xFF); | 95 bp[3] = (Uint8)((*wp >> 24) & 0xFF); |
90 bp[3] = (Uint8) ((*wp >> 24) & 0xFF); | |
91 } | 96 } |
92 } | 97 } |
93 | 98 |
94 /* converts from byte array to word array, len is number of bytes */ | 99 /* converts from byte array to word array, len is number of bytes */ |
95 static void b2w(Uint32 *out, const Uint8 *in, Uint32 len) | 100 static void b2w(Uint32* out, const Uint8* in, Uint32 len) { |
96 { | 101 Uint32* wp; |
97 Uint32 *wp; const Uint8 *bp, *bpend; | 102 const Uint8 *bp, *bpend; |
98 | 103 |
99 wp = out; | 104 wp = out; |
100 bp = in; | 105 bp = in; |
101 bpend = in + len; | 106 bpend = in + len; |
102 | 107 |
103 for (; bp != bpend; bp += 4, ++wp) | 108 for (; bp != bpend; bp += 4, ++wp) { |
104 { | 109 *wp = (Uint32)(bp[0]) | (Uint32)(bp[1] << 8) | (Uint32)(bp[2] << 16) | |
105 *wp = (Uint32) (bp[0] ) | | 110 (Uint32)(bp[3] << 24); |
106 (Uint32) (bp[1] << 8) | | |
107 (Uint32) (bp[2] << 16) | | |
108 (Uint32) (bp[3] << 24); | |
109 } | 111 } |
110 } | 112 } |
111 | 113 |
112 /* update state: data is 64 bytes in length */ | 114 /* update state: data is 64 bytes in length */ |
113 static void md4step(Uint32 state[4], const Uint8 *data) | 115 static void md4step(Uint32 state[4], const Uint8* data) { |
114 { | |
115 Uint32 A, B, C, D, X[16]; | 116 Uint32 A, B, C, D, X[16]; |
116 | 117 |
117 b2w(X, data, 64); | 118 b2w(X, data, 64); |
118 | 119 |
119 A = state[0]; | 120 A = state[0]; |
120 B = state[1]; | 121 B = state[1]; |
121 C = state[2]; | 122 C = state[2]; |
122 D = state[3]; | 123 D = state[3]; |
123 | 124 |
124 RD1(A,B,C,D, 0,3); RD1(D,A,B,C, 1,7); RD1(C,D,A,B, 2,11); RD1(B,C,D,A, 3,19); | 125 RD1(A, B, C, D, 0, 3); |
125 RD1(A,B,C,D, 4,3); RD1(D,A,B,C, 5,7); RD1(C,D,A,B, 6,11); RD1(B,C,D,A, 7,19); | 126 RD1(D, A, B, C, 1, 7); |
126 RD1(A,B,C,D, 8,3); RD1(D,A,B,C, 9,7); RD1(C,D,A,B,10,11); RD1(B,C,D,A,11,19); | 127 RD1(C, D, A, B, 2, 11); |
127 RD1(A,B,C,D,12,3); RD1(D,A,B,C,13,7); RD1(C,D,A,B,14,11); RD1(B,C,D,A,15,19); | 128 RD1(B, C, D, A, 3, 19); |
129 RD1(A, B, C, D, 4, 3); | |
130 RD1(D, A, B, C, 5, 7); | |
131 RD1(C, D, A, B, 6, 11); | |
132 RD1(B, C, D, A, 7, 19); | |
133 RD1(A, B, C, D, 8, 3); | |
134 RD1(D, A, B, C, 9, 7); | |
135 RD1(C, D, A, B, 10, 11); | |
136 RD1(B, C, D, A, 11, 19); | |
137 RD1(A, B, C, D, 12, 3); | |
138 RD1(D, A, B, C, 13, 7); | |
139 RD1(C, D, A, B, 14, 11); | |
140 RD1(B, C, D, A, 15, 19); | |
128 | 141 |
129 RD2(A,B,C,D, 0,3); RD2(D,A,B,C, 4,5); RD2(C,D,A,B, 8, 9); RD2(B,C,D,A,12,13); | 142 RD2(A, B, C, D, 0, 3); |
130 RD2(A,B,C,D, 1,3); RD2(D,A,B,C, 5,5); RD2(C,D,A,B, 9, 9); RD2(B,C,D,A,13,13); | 143 RD2(D, A, B, C, 4, 5); |
131 RD2(A,B,C,D, 2,3); RD2(D,A,B,C, 6,5); RD2(C,D,A,B,10, 9); RD2(B,C,D,A,14,13); | 144 RD2(C, D, A, B, 8, 9); |
132 RD2(A,B,C,D, 3,3); RD2(D,A,B,C, 7,5); RD2(C,D,A,B,11, 9); RD2(B,C,D,A,15,13); | 145 RD2(B, C, D, A, 12, 13); |
146 RD2(A, B, C, D, 1, 3); | |
147 RD2(D, A, B, C, 5, 5); | |
148 RD2(C, D, A, B, 9, 9); | |
149 RD2(B, C, D, A, 13, 13); | |
150 RD2(A, B, C, D, 2, 3); | |
151 RD2(D, A, B, C, 6, 5); | |
152 RD2(C, D, A, B, 10, 9); | |
153 RD2(B, C, D, A, 14, 13); | |
154 RD2(A, B, C, D, 3, 3); | |
155 RD2(D, A, B, C, 7, 5); | |
156 RD2(C, D, A, B, 11, 9); | |
157 RD2(B, C, D, A, 15, 13); | |
133 | 158 |
134 RD3(A,B,C,D, 0,3); RD3(D,A,B,C, 8,9); RD3(C,D,A,B, 4,11); RD3(B,C,D,A,12,15); | 159 RD3(A, B, C, D, 0, 3); |
135 RD3(A,B,C,D, 2,3); RD3(D,A,B,C,10,9); RD3(C,D,A,B, 6,11); RD3(B,C,D,A,14,15); | 160 RD3(D, A, B, C, 8, 9); |
136 RD3(A,B,C,D, 1,3); RD3(D,A,B,C, 9,9); RD3(C,D,A,B, 5,11); RD3(B,C,D,A,13,15); | 161 RD3(C, D, A, B, 4, 11); |
137 RD3(A,B,C,D, 3,3); RD3(D,A,B,C,11,9); RD3(C,D,A,B, 7,11); RD3(B,C,D,A,15,15); | 162 RD3(B, C, D, A, 12, 15); |
163 RD3(A, B, C, D, 2, 3); | |
164 RD3(D, A, B, C, 10, 9); | |
165 RD3(C, D, A, B, 6, 11); | |
166 RD3(B, C, D, A, 14, 15); | |
167 RD3(A, B, C, D, 1, 3); | |
168 RD3(D, A, B, C, 9, 9); | |
169 RD3(C, D, A, B, 5, 11); | |
170 RD3(B, C, D, A, 13, 15); | |
171 RD3(A, B, C, D, 3, 3); | |
172 RD3(D, A, B, C, 11, 9); | |
173 RD3(C, D, A, B, 7, 11); | |
174 RD3(B, C, D, A, 15, 15); | |
138 | 175 |
139 state[0] += A; | 176 state[0] += A; |
140 state[1] += B; | 177 state[1] += B; |
141 state[2] += C; | 178 state[2] += C; |
142 state[3] += D; | 179 state[3] += D; |
143 } | 180 } |
144 | 181 |
145 namespace net { | 182 namespace net { |
146 namespace weak_crypto { | 183 namespace weak_crypto { |
147 | 184 |
148 void MD4Sum(const Uint8 *input, Uint32 inputLen, Uint8 *result) | 185 void MD4Sum(const Uint8* input, Uint32 inputLen, Uint8* result) { |
149 { | |
150 Uint8 final[128]; | 186 Uint8 final[128]; |
151 Uint32 i, n, m, state[4]; | 187 Uint32 i, n, m, state[4]; |
152 | 188 |
153 /* magic initial states */ | 189 /* magic initial states */ |
154 state[0] = 0x67452301; | 190 state[0] = 0x67452301; |
155 state[1] = 0xEFCDAB89; | 191 state[1] = 0xEFCDAB89; |
156 state[2] = 0x98BADCFE; | 192 state[2] = 0x98BADCFE; |
157 state[3] = 0x10325476; | 193 state[3] = 0x10325476; |
158 | 194 |
159 /* compute number of complete 64-byte segments contained in input */ | 195 /* compute number of complete 64-byte segments contained in input */ |
160 m = inputLen >> 6; | 196 m = inputLen >> 6; |
161 | 197 |
162 /* digest first m segments */ | 198 /* digest first m segments */ |
163 for (i=0; i<m; ++i) | 199 for (i = 0; i < m; ++i) |
164 md4step(state, (input + (i << 6))); | 200 md4step(state, (input + (i << 6))); |
165 | 201 |
166 /* build final buffer */ | 202 /* build final buffer */ |
167 n = inputLen % 64; | 203 n = inputLen % 64; |
168 memcpy(final, input + (m << 6), n); | 204 memcpy(final, input + (m << 6), n); |
169 final[n] = 0x80; | 205 final[n] = 0x80; |
170 memset(final + n + 1, 0, 120 - (n + 1)); | 206 memset(final + n + 1, 0, 120 - (n + 1)); |
171 | 207 |
172 inputLen = inputLen << 3; | 208 inputLen = inputLen << 3; |
173 w2b(final + (n >= 56 ? 120 : 56), &inputLen, 4); | 209 w2b(final + (n >= 56 ? 120 : 56), &inputLen, 4); |
174 | 210 |
175 md4step(state, final); | 211 md4step(state, final); |
176 if (n >= 56) | 212 if (n >= 56) |
177 md4step(state, final + 64); | 213 md4step(state, final + 64); |
178 | 214 |
179 /* copy state to result */ | 215 /* copy state to result */ |
180 w2b(result, state, 16); | 216 w2b(result, state, 16); |
181 } | 217 } |
182 | 218 |
183 } // namespace weak_crypto | 219 } // namespace weak_crypto |
184 } // namespace net | 220 } // namespace net |
OLD | NEW |