| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 | |
| 5 #ifdef FREEBL_NO_DEPEND | |
| 6 #include "stubs.h" | |
| 7 #endif | |
| 8 | |
| 9 #include "prerr.h" | |
| 10 #include "secerr.h" | |
| 11 | |
| 12 #include "prtypes.h" | |
| 13 | |
| 14 #include "blapi.h" | |
| 15 | |
| 16 #define MD2_DIGEST_LEN 16 | |
| 17 #define MD2_BUFSIZE 16 | |
| 18 #define MD2_X_SIZE 48 /* The X array, [CV | INPUT | TMP VARS] */ | |
| 19 #define MD2_CV 0 /* index into X for chaining variables */ | |
| 20 #define MD2_INPUT 16 /* index into X for input */ | |
| 21 #define MD2_TMPVARS 32 /* index into X for temporary variables */ | |
| 22 #define MD2_CHECKSUM_SIZE 16 | |
| 23 | |
| 24 struct MD2ContextStr { | |
| 25 unsigned char checksum[MD2_BUFSIZE]; | |
| 26 unsigned char X[MD2_X_SIZE]; | |
| 27 PRUint8 unusedBuffer; | |
| 28 }; | |
| 29 | |
| 30 static const PRUint8 MD2S[256] = { | |
| 31 0051, 0056, 0103, 0311, 0242, 0330, 0174, 0001, | |
| 32 0075, 0066, 0124, 0241, 0354, 0360, 0006, 0023, | |
| 33 0142, 0247, 0005, 0363, 0300, 0307, 0163, 0214, | |
| 34 0230, 0223, 0053, 0331, 0274, 0114, 0202, 0312, | |
| 35 0036, 0233, 0127, 0074, 0375, 0324, 0340, 0026, | |
| 36 0147, 0102, 0157, 0030, 0212, 0027, 0345, 0022, | |
| 37 0276, 0116, 0304, 0326, 0332, 0236, 0336, 0111, | |
| 38 0240, 0373, 0365, 0216, 0273, 0057, 0356, 0172, | |
| 39 0251, 0150, 0171, 0221, 0025, 0262, 0007, 0077, | |
| 40 0224, 0302, 0020, 0211, 0013, 0042, 0137, 0041, | |
| 41 0200, 0177, 0135, 0232, 0132, 0220, 0062, 0047, | |
| 42 0065, 0076, 0314, 0347, 0277, 0367, 0227, 0003, | |
| 43 0377, 0031, 0060, 0263, 0110, 0245, 0265, 0321, | |
| 44 0327, 0136, 0222, 0052, 0254, 0126, 0252, 0306, | |
| 45 0117, 0270, 0070, 0322, 0226, 0244, 0175, 0266, | |
| 46 0166, 0374, 0153, 0342, 0234, 0164, 0004, 0361, | |
| 47 0105, 0235, 0160, 0131, 0144, 0161, 0207, 0040, | |
| 48 0206, 0133, 0317, 0145, 0346, 0055, 0250, 0002, | |
| 49 0033, 0140, 0045, 0255, 0256, 0260, 0271, 0366, | |
| 50 0034, 0106, 0141, 0151, 0064, 0100, 0176, 0017, | |
| 51 0125, 0107, 0243, 0043, 0335, 0121, 0257, 0072, | |
| 52 0303, 0134, 0371, 0316, 0272, 0305, 0352, 0046, | |
| 53 0054, 0123, 0015, 0156, 0205, 0050, 0204, 0011, | |
| 54 0323, 0337, 0315, 0364, 0101, 0201, 0115, 0122, | |
| 55 0152, 0334, 0067, 0310, 0154, 0301, 0253, 0372, | |
| 56 0044, 0341, 0173, 0010, 0014, 0275, 0261, 0112, | |
| 57 0170, 0210, 0225, 0213, 0343, 0143, 0350, 0155, | |
| 58 0351, 0313, 0325, 0376, 0073, 0000, 0035, 0071, | |
| 59 0362, 0357, 0267, 0016, 0146, 0130, 0320, 0344, | |
| 60 0246, 0167, 0162, 0370, 0353, 0165, 0113, 0012, | |
| 61 0061, 0104, 0120, 0264, 0217, 0355, 0037, 0032, | |
| 62 0333, 0231, 0215, 0063, 0237, 0021, 0203, 0024 | |
| 63 }; | |
| 64 | |
| 65 SECStatus | |
| 66 MD2_Hash(unsigned char *dest, const char *src) | |
| 67 { | |
| 68 unsigned int len; | |
| 69 MD2Context *cx = MD2_NewContext(); | |
| 70 if (!cx) { | |
| 71 PORT_SetError(PR_OUT_OF_MEMORY_ERROR); | |
| 72 return SECFailure; | |
| 73 } | |
| 74 MD2_Begin(cx); | |
| 75 MD2_Update(cx, (const unsigned char *)src, PORT_Strlen(src)); | |
| 76 MD2_End(cx, dest, &len, MD2_DIGEST_LEN); | |
| 77 MD2_DestroyContext(cx, PR_TRUE); | |
| 78 return SECSuccess; | |
| 79 } | |
| 80 | |
| 81 MD2Context * | |
| 82 MD2_NewContext(void) | |
| 83 { | |
| 84 MD2Context *cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context)); | |
| 85 if (cx == NULL) { | |
| 86 PORT_SetError(PR_OUT_OF_MEMORY_ERROR); | |
| 87 return NULL; | |
| 88 } | |
| 89 return cx; | |
| 90 } | |
| 91 | |
| 92 void | |
| 93 MD2_DestroyContext(MD2Context *cx, PRBool freeit) | |
| 94 { | |
| 95 if (freeit) | |
| 96 PORT_ZFree(cx, sizeof(*cx)); | |
| 97 } | |
| 98 | |
| 99 void | |
| 100 MD2_Begin(MD2Context *cx) | |
| 101 { | |
| 102 memset(cx, 0, sizeof(*cx)); | |
| 103 cx->unusedBuffer = MD2_BUFSIZE; | |
| 104 } | |
| 105 | |
| 106 static void | |
| 107 md2_compress(MD2Context *cx) | |
| 108 { | |
| 109 int j; | |
| 110 unsigned char P; | |
| 111 P = cx->checksum[MD2_CHECKSUM_SIZE-1]; | |
| 112 /* Compute the running checksum, and set the tmp variables to be | |
| 113 * CV[i] XOR input[i] | |
| 114 */ | |
| 115 #define CKSUMFN(n) \ | |
| 116 P = cx->checksum[n] ^ MD2S[cx->X[MD2_INPUT+n] ^ P]; \ | |
| 117 cx->checksum[n] = P; \ | |
| 118 cx->X[MD2_TMPVARS+n] = cx->X[n] ^ cx->X[MD2_INPUT+n]; | |
| 119 CKSUMFN(0); | |
| 120 CKSUMFN(1); | |
| 121 CKSUMFN(2); | |
| 122 CKSUMFN(3); | |
| 123 CKSUMFN(4); | |
| 124 CKSUMFN(5); | |
| 125 CKSUMFN(6); | |
| 126 CKSUMFN(7); | |
| 127 CKSUMFN(8); | |
| 128 CKSUMFN(9); | |
| 129 CKSUMFN(10); | |
| 130 CKSUMFN(11); | |
| 131 CKSUMFN(12); | |
| 132 CKSUMFN(13); | |
| 133 CKSUMFN(14); | |
| 134 CKSUMFN(15); | |
| 135 /* The compression function. */ | |
| 136 #define COMPRESS(n) \ | |
| 137 P = cx->X[n] ^ MD2S[P]; \ | |
| 138 cx->X[n] = P; | |
| 139 P = 0x00; | |
| 140 for (j=0; j<18; j++) { | |
| 141 COMPRESS(0); | |
| 142 COMPRESS(1); | |
| 143 COMPRESS(2); | |
| 144 COMPRESS(3); | |
| 145 COMPRESS(4); | |
| 146 COMPRESS(5); | |
| 147 COMPRESS(6); | |
| 148 COMPRESS(7); | |
| 149 COMPRESS(8); | |
| 150 COMPRESS(9); | |
| 151 COMPRESS(10); | |
| 152 COMPRESS(11); | |
| 153 COMPRESS(12); | |
| 154 COMPRESS(13); | |
| 155 COMPRESS(14); | |
| 156 COMPRESS(15); | |
| 157 COMPRESS(16); | |
| 158 COMPRESS(17); | |
| 159 COMPRESS(18); | |
| 160 COMPRESS(19); | |
| 161 COMPRESS(20); | |
| 162 COMPRESS(21); | |
| 163 COMPRESS(22); | |
| 164 COMPRESS(23); | |
| 165 COMPRESS(24); | |
| 166 COMPRESS(25); | |
| 167 COMPRESS(26); | |
| 168 COMPRESS(27); | |
| 169 COMPRESS(28); | |
| 170 COMPRESS(29); | |
| 171 COMPRESS(30); | |
| 172 COMPRESS(31); | |
| 173 COMPRESS(32); | |
| 174 COMPRESS(33); | |
| 175 COMPRESS(34); | |
| 176 COMPRESS(35); | |
| 177 COMPRESS(36); | |
| 178 COMPRESS(37); | |
| 179 COMPRESS(38); | |
| 180 COMPRESS(39); | |
| 181 COMPRESS(40); | |
| 182 COMPRESS(41); | |
| 183 COMPRESS(42); | |
| 184 COMPRESS(43); | |
| 185 COMPRESS(44); | |
| 186 COMPRESS(45); | |
| 187 COMPRESS(46); | |
| 188 COMPRESS(47); | |
| 189 P = (P + j) % 256; | |
| 190 } | |
| 191 cx->unusedBuffer = MD2_BUFSIZE; | |
| 192 } | |
| 193 | |
| 194 void | |
| 195 MD2_Update(MD2Context *cx, const unsigned char *input, unsigned int inputLen) | |
| 196 { | |
| 197 PRUint32 bytesToConsume; | |
| 198 | |
| 199 /* Fill the remaining input buffer. */ | |
| 200 if (cx->unusedBuffer != MD2_BUFSIZE) { | |
| 201 bytesToConsume = PR_MIN(inputLen, cx->unusedBuffer); | |
| 202 memcpy(&cx->X[MD2_INPUT + (MD2_BUFSIZE - cx->unusedBuffer)], | |
| 203 input, bytesToConsume); | |
| 204 if (cx->unusedBuffer + bytesToConsume >= MD2_BUFSIZE) | |
| 205 md2_compress(cx); | |
| 206 inputLen -= bytesToConsume; | |
| 207 input += bytesToConsume; | |
| 208 } | |
| 209 | |
| 210 /* Iterate over 16-byte chunks of the input. */ | |
| 211 while (inputLen >= MD2_BUFSIZE) { | |
| 212 memcpy(&cx->X[MD2_INPUT], input, MD2_BUFSIZE); | |
| 213 md2_compress(cx); | |
| 214 inputLen -= MD2_BUFSIZE; | |
| 215 input += MD2_BUFSIZE; | |
| 216 } | |
| 217 | |
| 218 /* Copy any input that remains into the buffer. */ | |
| 219 if (inputLen) | |
| 220 memcpy(&cx->X[MD2_INPUT], input, inputLen); | |
| 221 cx->unusedBuffer = MD2_BUFSIZE - inputLen; | |
| 222 } | |
| 223 | |
| 224 void | |
| 225 MD2_End(MD2Context *cx, unsigned char *digest, | |
| 226 unsigned int *digestLen, unsigned int maxDigestLen) | |
| 227 { | |
| 228 PRUint8 padStart; | |
| 229 if (maxDigestLen < MD2_BUFSIZE) { | |
| 230 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
| 231 return; | |
| 232 } | |
| 233 padStart = MD2_BUFSIZE - cx->unusedBuffer; | |
| 234 memset(&cx->X[MD2_INPUT + padStart], cx->unusedBuffer, | |
| 235 cx->unusedBuffer); | |
| 236 md2_compress(cx); | |
| 237 memcpy(&cx->X[MD2_INPUT], cx->checksum, MD2_BUFSIZE); | |
| 238 md2_compress(cx); | |
| 239 *digestLen = MD2_DIGEST_LEN; | |
| 240 memcpy(digest, &cx->X[MD2_CV], MD2_DIGEST_LEN); | |
| 241 } | |
| 242 | |
| 243 unsigned int | |
| 244 MD2_FlattenSize(MD2Context *cx) | |
| 245 { | |
| 246 return sizeof(*cx); | |
| 247 } | |
| 248 | |
| 249 SECStatus | |
| 250 MD2_Flatten(MD2Context *cx, unsigned char *space) | |
| 251 { | |
| 252 memcpy(space, cx, sizeof(*cx)); | |
| 253 return SECSuccess; | |
| 254 } | |
| 255 | |
| 256 MD2Context * | |
| 257 MD2_Resurrect(unsigned char *space, void *arg) | |
| 258 { | |
| 259 MD2Context *cx = MD2_NewContext(); | |
| 260 if (cx) | |
| 261 memcpy(cx, space, sizeof(*cx)); | |
| 262 return cx; | |
| 263 } | |
| 264 | |
| 265 void MD2_Clone(MD2Context *dest, MD2Context *src) | |
| 266 { | |
| 267 memcpy(dest, src, sizeof *dest); | |
| 268 } | |
| OLD | NEW |