security/nss/lib/freebl/md2.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial