Blame nss/lib/freebl/md2.c

Packit 40b132
/* This Source Code Form is subject to the terms of the Mozilla Public
Packit 40b132
 * License, v. 2.0. If a copy of the MPL was not distributed with this
Packit 40b132
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
Packit 40b132
Packit 40b132
#ifdef FREEBL_NO_DEPEND
Packit 40b132
#include "stubs.h"
Packit 40b132
#endif
Packit 40b132
Packit 40b132
#include "prerr.h"
Packit 40b132
#include "secerr.h"
Packit 40b132
Packit 40b132
#include "prtypes.h"
Packit 40b132
Packit 40b132
#include "blapi.h"
Packit 40b132
Packit 40b132
#define MD2_DIGEST_LEN    16
Packit 40b132
#define MD2_BUFSIZE       16
Packit 40b132
#define MD2_X_SIZE        48  /* The X array, [CV | INPUT | TMP VARS] */
Packit 40b132
#define MD2_CV             0  /* index into X for chaining variables */
Packit 40b132
#define MD2_INPUT         16  /* index into X for input */
Packit 40b132
#define MD2_TMPVARS       32  /* index into X for temporary variables */
Packit 40b132
#define MD2_CHECKSUM_SIZE 16
Packit 40b132
Packit 40b132
struct MD2ContextStr {
Packit 40b132
	unsigned char checksum[MD2_BUFSIZE];
Packit 40b132
	unsigned char X[MD2_X_SIZE];
Packit 40b132
	PRUint8 unusedBuffer;
Packit 40b132
};
Packit 40b132
Packit 40b132
static const PRUint8 MD2S[256] = {
Packit 40b132
 0051, 0056, 0103, 0311, 0242, 0330, 0174, 0001,
Packit 40b132
 0075, 0066, 0124, 0241, 0354, 0360, 0006, 0023,
Packit 40b132
 0142, 0247, 0005, 0363, 0300, 0307, 0163, 0214,
Packit 40b132
 0230, 0223, 0053, 0331, 0274, 0114, 0202, 0312,
Packit 40b132
 0036, 0233, 0127, 0074, 0375, 0324, 0340, 0026,
Packit 40b132
 0147, 0102, 0157, 0030, 0212, 0027, 0345, 0022,
Packit 40b132
 0276, 0116, 0304, 0326, 0332, 0236, 0336, 0111,
Packit 40b132
 0240, 0373, 0365, 0216, 0273, 0057, 0356, 0172,
Packit 40b132
 0251, 0150, 0171, 0221, 0025, 0262, 0007, 0077,
Packit 40b132
 0224, 0302, 0020, 0211, 0013, 0042, 0137, 0041,
Packit 40b132
 0200, 0177, 0135, 0232, 0132, 0220, 0062, 0047,
Packit 40b132
 0065, 0076, 0314, 0347, 0277, 0367, 0227, 0003,
Packit 40b132
 0377, 0031, 0060, 0263, 0110, 0245, 0265, 0321,
Packit 40b132
 0327, 0136, 0222, 0052, 0254, 0126, 0252, 0306,
Packit 40b132
 0117, 0270, 0070, 0322, 0226, 0244, 0175, 0266,
Packit 40b132
 0166, 0374, 0153, 0342, 0234, 0164, 0004, 0361,
Packit 40b132
 0105, 0235, 0160, 0131, 0144, 0161, 0207, 0040,
Packit 40b132
 0206, 0133, 0317, 0145, 0346, 0055, 0250, 0002,
Packit 40b132
 0033, 0140, 0045, 0255, 0256, 0260, 0271, 0366,
Packit 40b132
 0034, 0106, 0141, 0151, 0064, 0100, 0176, 0017,
Packit 40b132
 0125, 0107, 0243, 0043, 0335, 0121, 0257, 0072,
Packit 40b132
 0303, 0134, 0371, 0316, 0272, 0305, 0352, 0046,
Packit 40b132
 0054, 0123, 0015, 0156, 0205, 0050, 0204, 0011,
Packit 40b132
 0323, 0337, 0315, 0364, 0101, 0201, 0115, 0122,
Packit 40b132
 0152, 0334, 0067, 0310, 0154, 0301, 0253, 0372,
Packit 40b132
 0044, 0341, 0173, 0010, 0014, 0275, 0261, 0112,
Packit 40b132
 0170, 0210, 0225, 0213, 0343, 0143, 0350, 0155,
Packit 40b132
 0351, 0313, 0325, 0376, 0073, 0000, 0035, 0071,
Packit 40b132
 0362, 0357, 0267, 0016, 0146, 0130, 0320, 0344,
Packit 40b132
 0246, 0167, 0162, 0370, 0353, 0165, 0113, 0012,
Packit 40b132
 0061, 0104, 0120, 0264, 0217, 0355, 0037, 0032,
Packit 40b132
 0333, 0231, 0215, 0063, 0237, 0021, 0203, 0024
Packit 40b132
};
Packit 40b132
Packit 40b132
SECStatus 
Packit 40b132
MD2_Hash(unsigned char *dest, const char *src)
Packit 40b132
{
Packit 40b132
	unsigned int len;
Packit 40b132
	MD2Context *cx = MD2_NewContext();
Packit 40b132
	if (!cx) {
Packit 40b132
		PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
Packit 40b132
		return SECFailure;
Packit 40b132
	}
Packit 40b132
	MD2_Begin(cx);
Packit 40b132
	MD2_Update(cx, (const unsigned char *)src, PORT_Strlen(src));
Packit 40b132
	MD2_End(cx, dest, &len, MD2_DIGEST_LEN);
Packit 40b132
	MD2_DestroyContext(cx, PR_TRUE);
Packit 40b132
	return SECSuccess;
Packit 40b132
}
Packit 40b132
Packit 40b132
MD2Context *
Packit 40b132
MD2_NewContext(void)
Packit 40b132
{
Packit 40b132
	MD2Context *cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context));
Packit 40b132
	if (cx == NULL) {
Packit 40b132
		PORT_SetError(PR_OUT_OF_MEMORY_ERROR);
Packit 40b132
		return NULL;
Packit 40b132
	}
Packit 40b132
	return cx;
Packit 40b132
}
Packit 40b132
Packit 40b132
void 
Packit 40b132
MD2_DestroyContext(MD2Context *cx, PRBool freeit)
Packit 40b132
{
Packit 40b132
	if (freeit)
Packit 40b132
		PORT_ZFree(cx, sizeof(*cx));
Packit 40b132
}
Packit 40b132
Packit 40b132
void 
Packit 40b132
MD2_Begin(MD2Context *cx)
Packit 40b132
{
Packit 40b132
	memset(cx, 0, sizeof(*cx));
Packit 40b132
	cx->unusedBuffer = MD2_BUFSIZE;
Packit 40b132
}
Packit 40b132
Packit 40b132
static void
Packit 40b132
md2_compress(MD2Context *cx)
Packit 40b132
{
Packit 40b132
	int j;
Packit 40b132
	unsigned char P;
Packit 40b132
	P = cx->checksum[MD2_CHECKSUM_SIZE-1];
Packit 40b132
	/* Compute the running checksum, and set the tmp variables to be 
Packit 40b132
	 * CV[i] XOR input[i] 
Packit 40b132
	 */
Packit 40b132
#define CKSUMFN(n) \
Packit 40b132
	P = cx->checksum[n] ^ MD2S[cx->X[MD2_INPUT+n] ^ P]; \
Packit 40b132
	cx->checksum[n] = P; \
Packit 40b132
	cx->X[MD2_TMPVARS+n] = cx->X[n] ^ cx->X[MD2_INPUT+n];
Packit 40b132
	CKSUMFN(0);
Packit 40b132
	CKSUMFN(1);
Packit 40b132
	CKSUMFN(2);
Packit 40b132
	CKSUMFN(3);
Packit 40b132
	CKSUMFN(4);
Packit 40b132
	CKSUMFN(5);
Packit 40b132
	CKSUMFN(6);
Packit 40b132
	CKSUMFN(7);
Packit 40b132
	CKSUMFN(8);
Packit 40b132
	CKSUMFN(9);
Packit 40b132
	CKSUMFN(10);
Packit 40b132
	CKSUMFN(11);
Packit 40b132
	CKSUMFN(12);
Packit 40b132
	CKSUMFN(13);
Packit 40b132
	CKSUMFN(14);
Packit 40b132
	CKSUMFN(15);
Packit 40b132
	/* The compression function. */
Packit 40b132
#define COMPRESS(n) \
Packit 40b132
	P = cx->X[n] ^ MD2S[P]; \
Packit 40b132
	cx->X[n] = P;
Packit 40b132
	P = 0x00;
Packit 40b132
	for (j=0; j<18; j++) {
Packit 40b132
		COMPRESS(0);
Packit 40b132
		COMPRESS(1);
Packit 40b132
		COMPRESS(2);
Packit 40b132
		COMPRESS(3);
Packit 40b132
		COMPRESS(4);
Packit 40b132
		COMPRESS(5);
Packit 40b132
		COMPRESS(6);
Packit 40b132
		COMPRESS(7);
Packit 40b132
		COMPRESS(8);
Packit 40b132
		COMPRESS(9);
Packit 40b132
		COMPRESS(10);
Packit 40b132
		COMPRESS(11);
Packit 40b132
		COMPRESS(12);
Packit 40b132
		COMPRESS(13);
Packit 40b132
		COMPRESS(14);
Packit 40b132
		COMPRESS(15);
Packit 40b132
		COMPRESS(16);
Packit 40b132
		COMPRESS(17);
Packit 40b132
		COMPRESS(18);
Packit 40b132
		COMPRESS(19);
Packit 40b132
		COMPRESS(20);
Packit 40b132
		COMPRESS(21);
Packit 40b132
		COMPRESS(22);
Packit 40b132
		COMPRESS(23);
Packit 40b132
		COMPRESS(24);
Packit 40b132
		COMPRESS(25);
Packit 40b132
		COMPRESS(26);
Packit 40b132
		COMPRESS(27);
Packit 40b132
		COMPRESS(28);
Packit 40b132
		COMPRESS(29);
Packit 40b132
		COMPRESS(30);
Packit 40b132
		COMPRESS(31);
Packit 40b132
		COMPRESS(32);
Packit 40b132
		COMPRESS(33);
Packit 40b132
		COMPRESS(34);
Packit 40b132
		COMPRESS(35);
Packit 40b132
		COMPRESS(36);
Packit 40b132
		COMPRESS(37);
Packit 40b132
		COMPRESS(38);
Packit 40b132
		COMPRESS(39);
Packit 40b132
		COMPRESS(40);
Packit 40b132
		COMPRESS(41);
Packit 40b132
		COMPRESS(42);
Packit 40b132
		COMPRESS(43);
Packit 40b132
		COMPRESS(44);
Packit 40b132
		COMPRESS(45);
Packit 40b132
		COMPRESS(46);
Packit 40b132
		COMPRESS(47);
Packit 40b132
		P = (P + j) % 256;
Packit 40b132
	}
Packit 40b132
	cx->unusedBuffer = MD2_BUFSIZE;
Packit 40b132
}
Packit 40b132
Packit 40b132
void 
Packit 40b132
MD2_Update(MD2Context *cx, const unsigned char *input, unsigned int inputLen)
Packit 40b132
{
Packit 40b132
	PRUint32 bytesToConsume;
Packit 40b132
	
Packit 40b132
	/* Fill the remaining input buffer. */
Packit 40b132
	if (cx->unusedBuffer != MD2_BUFSIZE) {
Packit 40b132
		bytesToConsume = PR_MIN(inputLen, cx->unusedBuffer);
Packit 40b132
		memcpy(&cx->X[MD2_INPUT + (MD2_BUFSIZE - cx->unusedBuffer)],
Packit 40b132
		            input, bytesToConsume);
Packit 40b132
		if (cx->unusedBuffer + bytesToConsume >= MD2_BUFSIZE)
Packit 40b132
			md2_compress(cx);
Packit 40b132
		inputLen -= bytesToConsume;
Packit 40b132
		input += bytesToConsume;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	/* Iterate over 16-byte chunks of the input. */
Packit 40b132
	while (inputLen >= MD2_BUFSIZE) {
Packit 40b132
		memcpy(&cx->X[MD2_INPUT], input, MD2_BUFSIZE);
Packit 40b132
		md2_compress(cx);
Packit 40b132
		inputLen -= MD2_BUFSIZE;
Packit 40b132
		input += MD2_BUFSIZE;
Packit 40b132
	}
Packit 40b132
Packit 40b132
	/* Copy any input that remains into the buffer. */
Packit 40b132
	if (inputLen)
Packit 40b132
		memcpy(&cx->X[MD2_INPUT], input, inputLen);
Packit 40b132
	cx->unusedBuffer = MD2_BUFSIZE - inputLen;
Packit 40b132
}
Packit 40b132
Packit 40b132
void 
Packit 40b132
MD2_End(MD2Context *cx, unsigned char *digest,
Packit 40b132
        unsigned int *digestLen, unsigned int maxDigestLen)
Packit 40b132
{
Packit 40b132
	PRUint8 padStart;
Packit 40b132
	if (maxDigestLen < MD2_BUFSIZE) {
Packit 40b132
		PORT_SetError(SEC_ERROR_INVALID_ARGS);
Packit 40b132
		return;
Packit 40b132
	}
Packit 40b132
	padStart = MD2_BUFSIZE - cx->unusedBuffer;
Packit 40b132
	memset(&cx->X[MD2_INPUT + padStart], cx->unusedBuffer, 
Packit 40b132
	            cx->unusedBuffer);
Packit 40b132
	md2_compress(cx);
Packit 40b132
	memcpy(&cx->X[MD2_INPUT], cx->checksum, MD2_BUFSIZE);
Packit 40b132
	md2_compress(cx);
Packit 40b132
	*digestLen = MD2_DIGEST_LEN;
Packit 40b132
	memcpy(digest, &cx->X[MD2_CV], MD2_DIGEST_LEN);
Packit 40b132
}
Packit 40b132
Packit 40b132
unsigned int 
Packit 40b132
MD2_FlattenSize(MD2Context *cx)
Packit 40b132
{
Packit 40b132
	return sizeof(*cx);
Packit 40b132
}
Packit 40b132
Packit 40b132
SECStatus 
Packit 40b132
MD2_Flatten(MD2Context *cx, unsigned char *space)
Packit 40b132
{
Packit 40b132
	memcpy(space, cx, sizeof(*cx));
Packit 40b132
	return SECSuccess;
Packit 40b132
}
Packit 40b132
Packit 40b132
MD2Context * 
Packit 40b132
MD2_Resurrect(unsigned char *space, void *arg)
Packit 40b132
{
Packit 40b132
	MD2Context *cx = MD2_NewContext();
Packit 40b132
	if (cx)
Packit 40b132
		memcpy(cx, space, sizeof(*cx));
Packit 40b132
	return cx;
Packit 40b132
}
Packit 40b132
Packit 40b132
void MD2_Clone(MD2Context *dest, MD2Context *src) 
Packit 40b132
{
Packit 40b132
	memcpy(dest, src, sizeof *dest);
Packit 40b132
}