1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
44 #define MD2_DIGEST_LEN 16
45 #define MD2_BUFSIZE 16
46 #define MD2_X_SIZE 48 /* The X array, [CV | INPUT | TMP VARS] */
47 #define MD2_CV 0 /* index into X for chaining variables */
48 #define MD2_INPUT 16 /* index into X for input */
49 #define MD2_TMPVARS 32 /* index into X for temporary variables */
50 #define MD2_CHECKSUM_SIZE 16
52 struct MD2ContextStr
{
53 unsigned char checksum
[MD2_BUFSIZE
];
54 unsigned char X
[MD2_X_SIZE
];
58 static const PRUint8 MD2S
[256] = {
59 0051, 0056, 0103, 0311, 0242, 0330, 0174, 0001,
60 0075, 0066, 0124, 0241, 0354, 0360, 0006, 0023,
61 0142, 0247, 0005, 0363, 0300, 0307, 0163, 0214,
62 0230, 0223, 0053, 0331, 0274, 0114, 0202, 0312,
63 0036, 0233, 0127, 0074, 0375, 0324, 0340, 0026,
64 0147, 0102, 0157, 0030, 0212, 0027, 0345, 0022,
65 0276, 0116, 0304, 0326, 0332, 0236, 0336, 0111,
66 0240, 0373, 0365, 0216, 0273, 0057, 0356, 0172,
67 0251, 0150, 0171, 0221, 0025, 0262, 0007, 0077,
68 0224, 0302, 0020, 0211, 0013, 0042, 0137, 0041,
69 0200, 0177, 0135, 0232, 0132, 0220, 0062, 0047,
70 0065, 0076, 0314, 0347, 0277, 0367, 0227, 0003,
71 0377, 0031, 0060, 0263, 0110, 0245, 0265, 0321,
72 0327, 0136, 0222, 0052, 0254, 0126, 0252, 0306,
73 0117, 0270, 0070, 0322, 0226, 0244, 0175, 0266,
74 0166, 0374, 0153, 0342, 0234, 0164, 0004, 0361,
75 0105, 0235, 0160, 0131, 0144, 0161, 0207, 0040,
76 0206, 0133, 0317, 0145, 0346, 0055, 0250, 0002,
77 0033, 0140, 0045, 0255, 0256, 0260, 0271, 0366,
78 0034, 0106, 0141, 0151, 0064, 0100, 0176, 0017,
79 0125, 0107, 0243, 0043, 0335, 0121, 0257, 0072,
80 0303, 0134, 0371, 0316, 0272, 0305, 0352, 0046,
81 0054, 0123, 0015, 0156, 0205, 0050, 0204, 0011,
82 0323, 0337, 0315, 0364, 0101, 0201, 0115, 0122,
83 0152, 0334, 0067, 0310, 0154, 0301, 0253, 0372,
84 0044, 0341, 0173, 0010, 0014, 0275, 0261, 0112,
85 0170, 0210, 0225, 0213, 0343, 0143, 0350, 0155,
86 0351, 0313, 0325, 0376, 0073, 0000, 0035, 0071,
87 0362, 0357, 0267, 0016, 0146, 0130, 0320, 0344,
88 0246, 0167, 0162, 0370, 0353, 0165, 0113, 0012,
89 0061, 0104, 0120, 0264, 0217, 0355, 0037, 0032,
90 0333, 0231, 0215, 0063, 0237, 0021, 0203, 0024
94 MD2_Hash(unsigned char *dest
, const char *src
)
97 MD2Context
*cx
= MD2_NewContext();
99 PORT_SetError(PR_OUT_OF_MEMORY_ERROR
);
103 MD2_Update(cx
, (unsigned char *)src
, PL_strlen(src
));
104 MD2_End(cx
, dest
, &len
, MD2_DIGEST_LEN
);
105 MD2_DestroyContext(cx
, PR_TRUE
);
112 MD2Context
*cx
= (MD2Context
*)PORT_ZAlloc(sizeof(MD2Context
));
114 PORT_SetError(PR_OUT_OF_MEMORY_ERROR
);
121 MD2_DestroyContext(MD2Context
*cx
, PRBool freeit
)
124 PORT_ZFree(cx
, sizeof(*cx
));
128 MD2_Begin(MD2Context
*cx
)
130 memset(cx
, 0, sizeof(*cx
));
131 cx
->unusedBuffer
= MD2_BUFSIZE
;
135 md2_compress(MD2Context
*cx
)
139 P
= cx
->checksum
[MD2_CHECKSUM_SIZE
-1];
140 /* Compute the running checksum, and set the tmp variables to be
144 P = cx->checksum[n] ^ MD2S[cx->X[MD2_INPUT+n] ^ P]; \
145 cx->checksum[n] = P; \
146 cx->X[MD2_TMPVARS+n] = cx->X[n] ^ cx->X[MD2_INPUT+n];
163 /* The compression function. */
164 #define COMPRESS(n) \
165 P = cx->X[n] ^ MD2S[P]; \
168 for (j
=0; j
<18; j
++) {
219 cx
->unusedBuffer
= MD2_BUFSIZE
;
223 MD2_Update(MD2Context
*cx
, const unsigned char *input
, unsigned int inputLen
)
225 PRUint32 bytesToConsume
;
227 /* Fill the remaining input buffer. */
228 if (cx
->unusedBuffer
!= MD2_BUFSIZE
) {
229 bytesToConsume
= PR_MIN(inputLen
, cx
->unusedBuffer
);
230 memcpy(&cx
->X
[MD2_INPUT
+ (MD2_BUFSIZE
- cx
->unusedBuffer
)],
231 input
, bytesToConsume
);
232 if (cx
->unusedBuffer
+ bytesToConsume
>= MD2_BUFSIZE
)
234 inputLen
-= bytesToConsume
;
235 input
+= bytesToConsume
;
238 /* Iterate over 16-byte chunks of the input. */
239 while (inputLen
>= MD2_BUFSIZE
) {
240 memcpy(&cx
->X
[MD2_INPUT
], input
, MD2_BUFSIZE
);
242 inputLen
-= MD2_BUFSIZE
;
243 input
+= MD2_BUFSIZE
;
246 /* Copy any input that remains into the buffer. */
248 memcpy(&cx
->X
[MD2_INPUT
], input
, inputLen
);
249 cx
->unusedBuffer
= MD2_BUFSIZE
- inputLen
;
253 MD2_End(MD2Context
*cx
, unsigned char *digest
,
254 unsigned int *digestLen
, unsigned int maxDigestLen
)
257 if (maxDigestLen
< MD2_BUFSIZE
) {
258 PORT_SetError(SEC_ERROR_INVALID_ARGS
);
261 padStart
= MD2_BUFSIZE
- cx
->unusedBuffer
;
262 memset(&cx
->X
[MD2_INPUT
+ padStart
], cx
->unusedBuffer
,
265 memcpy(&cx
->X
[MD2_INPUT
], cx
->checksum
, MD2_BUFSIZE
);
267 *digestLen
= MD2_DIGEST_LEN
;
268 memcpy(digest
, &cx
->X
[MD2_CV
], MD2_DIGEST_LEN
);
272 MD2_FlattenSize(MD2Context
*cx
)
278 MD2_Flatten(MD2Context
*cx
, unsigned char *space
)
280 memcpy(space
, cx
, sizeof(*cx
));
285 MD2_Resurrect(unsigned char *space
, void *arg
)
287 MD2Context
*cx
= MD2_NewContext();
289 memcpy(cx
, space
, sizeof(*cx
));
293 void MD2_Clone(MD2Context
*dest
, MD2Context
*src
)
295 memcpy(dest
, src
, sizeof *dest
);