1c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// This is mozilla/security/manager/ssl/src/md4.c, CVS rev. 1.1, with trivial
2c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// changes to port it to our source tree.
3c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott//
4c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// WARNING: MD4 is cryptographically weak.  Do not use MD4 except in NTLM
5c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott// authentication.
6c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
7c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* vim:set ts=2 sw=2 et cindent: */
8c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* ***** BEGIN LICENSE BLOCK *****
9c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Version: MPL 1.1/GPL 2.0/LGPL 2.1
10c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
11c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * The contents of this file are subject to the Mozilla Public License Version
12c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * 1.1 (the "License"); you may not use this file except in compliance with
13c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the License. You may obtain a copy of the License at
14c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * http://www.mozilla.org/MPL/
15c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
16c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Software distributed under the License is distributed on an "AS IS" basis,
17c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
18c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * for the specific language governing rights and limitations under the
19c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * License.
20c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
21c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * The Original Code is Mozilla.
22c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
23c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * The Initial Developer of the Original Code is IBM Corporation.
24c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Portions created by IBM Corporation are Copyright (C) 2003
25c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * IBM Corporation. All Rights Reserved.
26c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
27c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Contributor(s):
28c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *   Darin Fisher <darin@meer.net>
29c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
30c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * Alternatively, the contents of this file may be used under the terms of
31c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * either the GNU General Public License Version 2 or later (the "GPL"), or
32c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
33c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * in which case the provisions of the GPL or the LGPL are applicable instead
34c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * of those above. If you wish to allow use of your version of this file only
35c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * under the terms of either the GPL or the LGPL, and not to allow others to
36c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * use your version of this file under the terms of the MPL, indicate your
37c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * decision by deleting the provisions above and replace them with the notice
38c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * and other provisions required by the GPL or the LGPL. If you do not delete
39c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the provisions above, a recipient may use your version of this file under
40c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * the terms of any one of the MPL, the GPL or the LGPL.
41c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott *
42c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * ***** END LICENSE BLOCK ***** */
43c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
44c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/*
45c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott * "clean room" MD4 implementation (see RFC 1320)
46c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott */
47c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
48c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include "net/http/md4.h"
49c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
50c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#include <string.h>
51c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
52c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef uint32 Uint32;
53c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scotttypedef uint8 Uint8;
54c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
55c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* the "conditional" function */
56c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define F(x,y,z) (((x) & (y)) | (~(x) & (z)))
57c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
58c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* the "majority" function */
59c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define G(x,y,z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
60c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
61c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* the "parity" function */
62c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define H(x,y,z) ((x) ^ (y) ^ (z))
63c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
64c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* rotate n-bits to the left */
65c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define ROTL(x,n) (((x) << (n)) | ((x) >> (0x20 - n)))
66c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
67c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* round 1: [abcd k s]: a = (a + F(b,c,d) + X[k]) <<< s */
68c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define RD1(a,b,c,d,k,s) a += F(b,c,d) + X[k]; a = ROTL(a,s)
69c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
70c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* round 2: [abcd k s]: a = (a + G(b,c,d) + X[k] + MAGIC) <<< s */
71c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define RD2(a,b,c,d,k,s) a += G(b,c,d) + X[k] + 0x5A827999; a = ROTL(a,s)
72c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
73c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* round 3: [abcd k s]: a = (a + H(b,c,d) + X[k] + MAGIC) <<< s */
74c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott#define RD3(a,b,c,d,k,s) a += H(b,c,d) + X[k] + 0x6ED9EBA1; a = ROTL(a,s)
75c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
76c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* converts from word array to byte array, len is number of bytes */
77c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void w2b(Uint8 *out, const Uint32 *in, Uint32 len)
78c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
79c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Uint8 *bp; const Uint32 *wp, *wpend;
80c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
81c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bp = out;
82c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  wp = in;
83c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  wpend = wp + (len >> 2);
84c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
85c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (; wp != wpend; ++wp, bp += 4)
86c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
87c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bp[0] = (Uint8) ((*wp      ) & 0xFF);
88c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bp[1] = (Uint8) ((*wp >>  8) & 0xFF);
89c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bp[2] = (Uint8) ((*wp >> 16) & 0xFF);
90c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    bp[3] = (Uint8) ((*wp >> 24) & 0xFF);
91c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
92c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
93c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
94c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* converts from byte array to word array, len is number of bytes */
95c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void b2w(Uint32 *out, const Uint8 *in, Uint32 len)
96c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
97c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Uint32 *wp; const Uint8 *bp, *bpend;
98c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
99c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  wp = out;
100c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bp = in;
101c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  bpend = in + len;
102c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
103c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (; bp != bpend; bp += 4, ++wp)
104c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  {
105c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    *wp = (Uint32) (bp[0]      ) |
106c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          (Uint32) (bp[1] <<  8) |
107c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          (Uint32) (bp[2] << 16) |
108c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott          (Uint32) (bp[3] << 24);
109c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  }
110c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
111c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
112c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott/* update state: data is 64 bytes in length */
113c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottstatic void md4step(Uint32 state[4], const Uint8 *data)
114c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
115c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Uint32 A, B, C, D, X[16];
116c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
117c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  b2w(X, data, 64);
118c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
119c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  A = state[0];
120c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  B = state[1];
121c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  C = state[2];
122c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  D = state[3];
123c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
124c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
125c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
126c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
127c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
128c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
129c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
130c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
131c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
132c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
133c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
134c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
135c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
136c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
137c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  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);
138c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
139c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[0] += A;
140c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[1] += B;
141c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[2] += C;
142c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[3] += D;
143c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
144c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
145c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace net {
146c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottnamespace weak_crypto {
147c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
148c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scottvoid MD4Sum(const Uint8 *input, Uint32 inputLen, Uint8 *result)
149c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott{
150c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Uint8 final[128];
151c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  Uint32 i, n, m, state[4];
152c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
153c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  /* magic initial states */
154c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[0] = 0x67452301;
155c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[1] = 0xEFCDAB89;
156c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[2] = 0x98BADCFE;
157c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  state[3] = 0x10325476;
158c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
159c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  /* compute number of complete 64-byte segments contained in input */
160c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  m = inputLen >> 6;
161c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
162c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  /* digest first m segments */
163c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  for (i=0; i<m; ++i)
164c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    md4step(state, (input + (i << 6)));
165c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
166c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  /* build final buffer */
167c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  n = inputLen % 64;
168c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memcpy(final, input + (m << 6), n);
169c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  final[n] = 0x80;
170c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  memset(final + n + 1, 0, 120 - (n + 1));
171c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
172c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  inputLen = inputLen << 3;
173c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  w2b(final + (n >= 56 ? 120 : 56), &inputLen, 4);
174c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
175c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  md4step(state, final);
176c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  if (n >= 56)
177c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott    md4step(state, final + 64);
178c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
179c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  /* copy state to result */
180c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott  w2b(result, state, 16);
181c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}
182c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott
183c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net::weak_crypto
184c7f5f8508d98d5952d42ed7648c2a8f30a4da156Patrick Scott}  // namespace net
185