diff options
author | mcgreer%netscape.com <devnull@localhost> | 2000-05-12 23:35:06 +0000 |
---|---|---|
committer | mcgreer%netscape.com <devnull@localhost> | 2000-05-12 23:35:06 +0000 |
commit | 65c22c5b4579c756676c8724cedc97f3f7682aba (patch) | |
tree | 31e19168ef2654bc20057deb8241e83531973a51 | |
parent | 56490c41b6068923651588bd2589223e4bb1bfc6 (diff) | |
download | nss-hg-65c22c5b4579c756676c8724cedc97f3f7682aba.tar.gz |
Initial checkin of implementations of MD2 and MD5. An empty definition of Diffie-Hellman to allow for building, more later. Changes to Makefile for building with BSAFE.
-rw-r--r-- | security/nss/lib/freebl/Makefile | 11 | ||||
-rw-r--r-- | security/nss/lib/freebl/dh.c | 82 | ||||
-rw-r--r-- | security/nss/lib/freebl/manifest.mn | 11 | ||||
-rw-r--r-- | security/nss/lib/freebl/md2.c | 288 | ||||
-rw-r--r-- | security/nss/lib/freebl/md5.c | 519 |
5 files changed, 911 insertions, 0 deletions
diff --git a/security/nss/lib/freebl/Makefile b/security/nss/lib/freebl/Makefile index 08b7137d5..712a0516a 100644 --- a/security/nss/lib/freebl/Makefile +++ b/security/nss/lib/freebl/Makefile @@ -74,3 +74,14 @@ include $(CORE_DEPTH)/coreconf/rules.mk export:: private_export +ifdef MOZILLA_BSAFE_BUILD +ifeq ($(OS_ARCH),WINNT) +libbsafe=bsafe41.lib +else +libbsafe=libbsafe.a +endif + +private_export:: + $(NSINSTALL) -m 777 $(libbsafe) $(DIST)/lib; \ + +endif diff --git a/security/nss/lib/freebl/dh.c b/security/nss/lib/freebl/dh.c new file mode 100644 index 000000000..f366363bf --- /dev/null +++ b/security/nss/lib/freebl/dh.c @@ -0,0 +1,82 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1994-2000 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +#include "prerr.h" +#include "secerr.h" + +#include "blapi.h" + +SECStatus +DH_GenParam(int primeLen, DHParams ** params) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return SECFailure; +} + +SECStatus +DH_NewKey(DHParams * params, + DHPrivateKey ** privKey) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return SECFailure; +} + +SECStatus +DH_Derive(SECItem * publicValue, + SECItem * prime, + SECItem * privateValue, + SECItem * derivedSecret, + unsigned int maxOutBytes) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return SECFailure; +} + +SECStatus +KEA_Derive(SECItem *prime, + SECItem *public1, + SECItem *public2, + SECItem *private1, + SECItem *private2, + SECItem *derivedSecret) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return SECFailure; +} + +PRBool +KEA_Verify(SECItem *Y, SECItem *prime, SECItem *subPrime) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); + return PR_FALSE; +} diff --git a/security/nss/lib/freebl/manifest.mn b/security/nss/lib/freebl/manifest.mn index a8df2bc49..2e910744c 100644 --- a/security/nss/lib/freebl/manifest.mn +++ b/security/nss/lib/freebl/manifest.mn @@ -46,7 +46,18 @@ EXPORTS = \ PRIVATE_EXPORTS = \ $(NULL) +ifdef MOZILLA_BSAFE_BUILD CSRCS = \ + fblstdlib.c \ sha_fast.c \ + md2.c \ + md5.c \ + dh.c \ + blapi_bsf.c \ $(NULL) +else +CSRCS = \ + sha_fast.c \ + $(NULL) +endif diff --git a/security/nss/lib/freebl/md2.c b/security/nss/lib/freebl/md2.c new file mode 100644 index 000000000..e1a5fe0f4 --- /dev/null +++ b/security/nss/lib/freebl/md2.c @@ -0,0 +1,288 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1994-2000 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +#include "prerr.h" +#include "secerr.h" + +#include "prtypes.h" + +#include "blapi.h" + +#define MD2_DIGEST_LEN 16 +#define MD2_BUFSIZE 16 +#define MD2_X_SIZE 48 /* The X array, [CV | INPUT | TMP VARS] */ +#define MD2_CV 0 /* index into X for chaining variables */ +#define MD2_INPUT 16 /* index into X for input */ +#define MD2_TMPVARS 32 /* index into X for temporary variables */ +#define MD2_CHECKSUM_SIZE 16 + +struct MD2ContextStr { + unsigned char checksum[MD2_BUFSIZE]; + unsigned char X[MD2_X_SIZE]; + PRUint8 unusedBuffer; +}; + +static const PRUint8 MD2S[256] = { + 0051, 0056, 0103, 0311, 0242, 0330, 0174, 0001, + 0075, 0066, 0124, 0241, 0354, 0360, 0006, 0023, + 0142, 0247, 0005, 0363, 0300, 0307, 0163, 0214, + 0230, 0223, 0053, 0331, 0274, 0114, 0202, 0312, + 0036, 0233, 0127, 0074, 0375, 0324, 0340, 0026, + 0147, 0102, 0157, 0030, 0212, 0027, 0345, 0022, + 0276, 0116, 0304, 0326, 0332, 0236, 0336, 0111, + 0240, 0373, 0365, 0216, 0273, 0057, 0356, 0172, + 0251, 0150, 0171, 0221, 0025, 0262, 0007, 0077, + 0224, 0302, 0020, 0211, 0013, 0042, 0137, 0041, + 0200, 0177, 0135, 0232, 0132, 0220, 0062, 0047, + 0065, 0076, 0314, 0347, 0277, 0367, 0227, 0003, + 0377, 0031, 0060, 0263, 0110, 0245, 0265, 0321, + 0327, 0136, 0222, 0052, 0254, 0126, 0252, 0306, + 0117, 0270, 0070, 0322, 0226, 0244, 0175, 0266, + 0166, 0374, 0153, 0342, 0234, 0164, 0004, 0361, + 0105, 0235, 0160, 0131, 0144, 0161, 0207, 0040, + 0206, 0133, 0317, 0145, 0346, 0055, 0250, 0002, + 0033, 0140, 0045, 0255, 0256, 0260, 0271, 0366, + 0034, 0106, 0141, 0151, 0064, 0100, 0176, 0017, + 0125, 0107, 0243, 0043, 0335, 0121, 0257, 0072, + 0303, 0134, 0371, 0316, 0272, 0305, 0352, 0046, + 0054, 0123, 0015, 0156, 0205, 0050, 0204, 0011, + 0323, 0337, 0315, 0364, 0101, 0201, 0115, 0122, + 0152, 0334, 0067, 0310, 0154, 0301, 0253, 0372, + 0044, 0341, 0173, 0010, 0014, 0275, 0261, 0112, + 0170, 0210, 0225, 0213, 0343, 0143, 0350, 0155, + 0351, 0313, 0325, 0376, 0073, 0000, 0035, 0071, + 0362, 0357, 0267, 0016, 0146, 0130, 0320, 0344, + 0246, 0167, 0162, 0370, 0353, 0165, 0113, 0012, + 0061, 0104, 0120, 0264, 0217, 0355, 0037, 0032, + 0333, 0231, 0215, 0063, 0237, 0021, 0203, 0024 +}; + +SECStatus +MD2_Hash(unsigned char *dest, const char *src) +{ + unsigned int len; + MD2Context *cx = MD2_NewContext(); + if (!cx) { + PORT_SetError(PR_OUT_OF_MEMORY_ERROR); + return SECFailure; + } + MD2_Begin(cx); + MD2_Update(cx, (unsigned char *)src, PL_strlen(src)); + MD2_End(cx, dest, &len, MD2_DIGEST_LEN); + MD2_DestroyContext(cx, PR_TRUE); + return SECSuccess; +} + +MD2Context * +MD2_NewContext(void) +{ + MD2Context *cx = (MD2Context *)PORT_ZAlloc(sizeof(MD2Context)); + if (cx == NULL) { + PORT_SetError(PR_OUT_OF_MEMORY_ERROR); + return NULL; + } + return cx; +} + +void +MD2_DestroyContext(MD2Context *cx, PRBool freeit) +{ + if (freeit) + PORT_ZFree(cx, sizeof(*cx)); +} + +void +MD2_Begin(MD2Context *cx) +{ + memset(cx, 0, sizeof(*cx)); + cx->unusedBuffer = MD2_BUFSIZE; +} + +static void +md2_compress(MD2Context *cx) +{ + int j, k, l; + unsigned char P; + P = cx->checksum[MD2_CHECKSUM_SIZE-1]; + /* Compute the running checksum, and set the tmp variables to be + * CV[i] XOR input[i] + */ +#define CKSUMFN(n) \ + P = cx->checksum[n] ^ MD2S[cx->X[MD2_INPUT+n] ^ P]; \ + cx->checksum[n] = P; \ + cx->X[MD2_TMPVARS+n] = cx->X[n] ^ cx->X[MD2_INPUT+n]; + CKSUMFN(0); + CKSUMFN(1); + CKSUMFN(2); + CKSUMFN(3); + CKSUMFN(4); + CKSUMFN(5); + CKSUMFN(6); + CKSUMFN(7); + CKSUMFN(8); + CKSUMFN(9); + CKSUMFN(10); + CKSUMFN(11); + CKSUMFN(12); + CKSUMFN(13); + CKSUMFN(14); + CKSUMFN(15); + /* The compression function. */ +#define COMPRESS(n) \ + P = cx->X[n] ^ MD2S[P]; \ + cx->X[n] = P; + P = 0x00; + for (j=0; j<18; j++) { + COMPRESS(0); + COMPRESS(1); + COMPRESS(2); + COMPRESS(3); + COMPRESS(4); + COMPRESS(5); + COMPRESS(6); + COMPRESS(7); + COMPRESS(8); + COMPRESS(9); + COMPRESS(10); + COMPRESS(11); + COMPRESS(12); + COMPRESS(13); + COMPRESS(14); + COMPRESS(15); + COMPRESS(16); + COMPRESS(17); + COMPRESS(18); + COMPRESS(19); + COMPRESS(20); + COMPRESS(21); + COMPRESS(22); + COMPRESS(23); + COMPRESS(24); + COMPRESS(25); + COMPRESS(26); + COMPRESS(27); + COMPRESS(28); + COMPRESS(29); + COMPRESS(30); + COMPRESS(31); + COMPRESS(32); + COMPRESS(33); + COMPRESS(34); + COMPRESS(35); + COMPRESS(36); + COMPRESS(37); + COMPRESS(38); + COMPRESS(39); + COMPRESS(40); + COMPRESS(41); + COMPRESS(42); + COMPRESS(43); + COMPRESS(44); + COMPRESS(45); + COMPRESS(46); + COMPRESS(47); + P = (P + j) % 256; + } + cx->unusedBuffer = MD2_BUFSIZE; +} + +void +MD2_Update(MD2Context *cx, const unsigned char *input, unsigned int inputLen) +{ + PRUint32 bytesToConsume; + + /* Fill the remaining input buffer. */ + if (cx->unusedBuffer != MD2_BUFSIZE) { + bytesToConsume = PR_MIN(inputLen, cx->unusedBuffer); + memcpy(&cx->X[MD2_INPUT + (MD2_BUFSIZE - cx->unusedBuffer)], + input, bytesToConsume); + if (cx->unusedBuffer + bytesToConsume >= MD2_BUFSIZE) + md2_compress(cx); + inputLen -= bytesToConsume; + input += bytesToConsume; + } + + /* Iterate over 16-byte chunks of the input. */ + while (inputLen >= MD2_BUFSIZE) { + memcpy(&cx->X[MD2_INPUT], input, MD2_BUFSIZE); + md2_compress(cx); + inputLen -= MD2_BUFSIZE; + input += MD2_BUFSIZE; + } + + /* Copy any input that remains into the buffer. */ + if (inputLen) + memcpy(&cx->X[MD2_INPUT], input, inputLen); + cx->unusedBuffer = MD2_BUFSIZE - inputLen; +} + +void +MD2_End(MD2Context *cx, unsigned char *digest, + unsigned int *digestLen, unsigned int maxDigestLen) +{ + PRUint8 padStart; + if (maxDigestLen < MD2_BUFSIZE) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return; + } + padStart = MD2_BUFSIZE - cx->unusedBuffer; + memset(&cx->X[MD2_INPUT + padStart], cx->unusedBuffer, + cx->unusedBuffer); + md2_compress(cx); + memcpy(&cx->X[MD2_INPUT], cx->checksum, MD2_BUFSIZE); + md2_compress(cx); + *digestLen = MD2_DIGEST_LEN; + memcpy(digest, &cx->X[MD2_CV], MD2_DIGEST_LEN); +} + +unsigned int +MD2_FlattenSize(MD2Context *cx) +{ + return sizeof(*cx); +} + +SECStatus +MD2_Flatten(MD2Context *cx, unsigned char *space) +{ + memcpy(space, cx, sizeof(*cx)); + return SECSuccess; +} + +MD2Context * +MD2_Resurrect(unsigned char *space, void *arg) +{ + MD2Context *cx = MD2_NewContext(); + if (cx) + memcpy(cx, space, sizeof(*cx)); + return cx; +} diff --git a/security/nss/lib/freebl/md5.c b/security/nss/lib/freebl/md5.c new file mode 100644 index 000000000..3ebd3d8db --- /dev/null +++ b/security/nss/lib/freebl/md5.c @@ -0,0 +1,519 @@ +/* + * The contents of this file are subject to the Mozilla Public + * License Version 1.1 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS + * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or + * implied. See the License for the specific language governing + * rights and limitations under the License. + * + * The Original Code is the Netscape security libraries. + * + * The Initial Developer of the Original Code is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1994-2000 Netscape Communications Corporation. All + * Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License Version 2 or later (the + * "GPL"), in which case the provisions of the GPL are applicable + * instead of those above. If you wish to allow use of your + * version of this file only under the terms of the GPL and not to + * allow others to use your version of this file under the MPL, + * indicate your decision by deleting the provisions above and + * replace them with the notice and other provisions required by + * the GPL. If you do not delete the provisions above, a recipient + * may use your version of this file under either the MPL or the + * GPL. + */ + +#include "prerr.h" +#include "secerr.h" + +#include "prtypes.h" +#include "prlong.h" + +#include "blapi.h" + +#define MD5_HASH_LEN 16 +#define MD5_BUFFER_SIZE 64 +#define MD5_END_BUFFER (MD5_BUFFER_SIZE - 8) + +#define CV0_1 0x67452301 +#define CV0_2 0xefcdab89 +#define CV0_3 0x98badcfe +#define CV0_4 0x10325476 + +#define T1_0 0xd76aa478 +#define T1_1 0xe8c7b756 +#define T1_2 0x242070db +#define T1_3 0xc1bdceee +#define T1_4 0xf57c0faf +#define T1_5 0x4787c62a +#define T1_6 0xa8304613 +#define T1_7 0xfd469501 +#define T1_8 0x698098d8 +#define T1_9 0x8b44f7af +#define T1_10 0xffff5bb1 +#define T1_11 0x895cd7be +#define T1_12 0x6b901122 +#define T1_13 0xfd987193 +#define T1_14 0xa679438e +#define T1_15 0x49b40821 + +#define T2_0 0xf61e2562 +#define T2_1 0xc040b340 +#define T2_2 0x265e5a51 +#define T2_3 0xe9b6c7aa +#define T2_4 0xd62f105d +#define T2_5 0x02441453 +#define T2_6 0xd8a1e681 +#define T2_7 0xe7d3fbc8 +#define T2_8 0x21e1cde6 +#define T2_9 0xc33707d6 +#define T2_10 0xf4d50d87 +#define T2_11 0x455a14ed +#define T2_12 0xa9e3e905 +#define T2_13 0xfcefa3f8 +#define T2_14 0x676f02d9 +#define T2_15 0x8d2a4c8a + +#define T3_0 0xfffa3942 +#define T3_1 0x8771f681 +#define T3_2 0x6d9d6122 +#define T3_3 0xfde5380c +#define T3_4 0xa4beea44 +#define T3_5 0x4bdecfa9 +#define T3_6 0xf6bb4b60 +#define T3_7 0xbebfbc70 +#define T3_8 0x289b7ec6 +#define T3_9 0xeaa127fa +#define T3_10 0xd4ef3085 +#define T3_11 0x04881d05 +#define T3_12 0xd9d4d039 +#define T3_13 0xe6db99e5 +#define T3_14 0x1fa27cf8 +#define T3_15 0xc4ac5665 + +#define T4_0 0xf4292244 +#define T4_1 0x432aff97 +#define T4_2 0xab9423a7 +#define T4_3 0xfc93a039 +#define T4_4 0x655b59c3 +#define T4_5 0x8f0ccc92 +#define T4_6 0xffeff47d +#define T4_7 0x85845dd1 +#define T4_8 0x6fa87e4f +#define T4_9 0xfe2ce6e0 +#define T4_10 0xa3014314 +#define T4_11 0x4e0811a1 +#define T4_12 0xf7537e82 +#define T4_13 0xbd3af235 +#define T4_14 0x2ad7d2bb +#define T4_15 0xeb86d391 + +#define R1B0 0 +#define R1B1 1 +#define R1B2 2 +#define R1B3 3 +#define R1B4 4 +#define R1B5 5 +#define R1B6 6 +#define R1B7 7 +#define R1B8 8 +#define R1B9 9 +#define R1B10 10 +#define R1B11 11 +#define R1B12 12 +#define R1B13 13 +#define R1B14 14 +#define R1B15 15 + +#define R2B0 1 +#define R2B1 6 +#define R2B2 11 +#define R2B3 0 +#define R2B4 5 +#define R2B5 10 +#define R2B6 15 +#define R2B7 4 +#define R2B8 9 +#define R2B9 14 +#define R2B10 3 +#define R2B11 8 +#define R2B12 13 +#define R2B13 2 +#define R2B14 7 +#define R2B15 12 + +#define R3B0 5 +#define R3B1 8 +#define R3B2 11 +#define R3B3 14 +#define R3B4 1 +#define R3B5 4 +#define R3B6 7 +#define R3B7 10 +#define R3B8 13 +#define R3B9 0 +#define R3B10 3 +#define R3B11 6 +#define R3B12 9 +#define R3B13 12 +#define R3B14 15 +#define R3B15 2 + +#define R4B0 0 +#define R4B1 7 +#define R4B2 14 +#define R4B3 5 +#define R4B4 12 +#define R4B5 3 +#define R4B6 10 +#define R4B7 1 +#define R4B8 8 +#define R4B9 15 +#define R4B10 6 +#define R4B11 13 +#define R4B12 4 +#define R4B13 11 +#define R4B14 2 +#define R4B15 9 + +#define S1_0 7 +#define S1_1 12 +#define S1_2 17 +#define S1_3 22 + +#define S2_0 5 +#define S2_1 9 +#define S2_2 14 +#define S2_3 20 + +#define S3_0 4 +#define S3_1 11 +#define S3_2 16 +#define S3_3 23 + +#define S4_0 6 +#define S4_1 10 +#define S4_2 15 +#define S4_3 21 + +struct MD5ContextStr { + PRUint32 lsbInput; + PRUint32 msbInput; + PRUint32 inBufIndex; + PRUint32 cv[4]; + union { + PRUint8 b[64]; + PRUint32 w[16]; + } u; +}; + +#define inBuf u.b + +SECStatus +MD5_Hash(unsigned char *dest, const char *src) +{ + return MD5_HashBuf(dest, (unsigned char *)src, PL_strlen(src)); +} + +SECStatus +MD5_HashBuf(unsigned char *dest, const unsigned char *src, uint32 src_length) +{ + unsigned int len; + MD5Context *cx = MD5_NewContext(); + if (cx == NULL) { + PORT_SetError(PR_OUT_OF_MEMORY_ERROR); + return SECFailure; + } + MD5_Begin(cx); + MD5_Update(cx, src, src_length); + MD5_End(cx, dest, &len, MD5_HASH_LEN); + MD5_DestroyContext(cx, PR_TRUE); + return SECSuccess; +} + +MD5Context * +MD5_NewContext(void) +{ + MD5Context *cx = (MD5Context *)PORT_ZAlloc(sizeof(MD5Context)); + if (cx == NULL) { + PORT_SetError(PR_OUT_OF_MEMORY_ERROR); + return NULL; + } + return cx; +} + +void +MD5_DestroyContext(MD5Context *cx, PRBool freeit) +{ + if (freeit) { + PORT_ZFree(cx, sizeof(MD5Context)); + } +} + +void +MD5_Begin(MD5Context *cx) +{ + cx->lsbInput = 0; + cx->msbInput = 0; + cx->inBufIndex = 0; + memset(cx->inBuf, 0, sizeof(cx->inBuf)); + cx->cv[0] = CV0_1; + cx->cv[1] = CV0_2; + cx->cv[2] = CV0_3; + cx->cv[3] = CV0_4; +} + +#define cls(i32, s) (tmp = i32, tmp << s | tmp >> (32 - s)) + +#define MASK 0x00ff00ff +#ifdef IS_LITTLE_ENDIAN +#define lendian(i32) \ + (i32) +#else +#define lendian(i32) \ + (tmp = i32 >> 16 | i32 << 16, (tmp & MASK) << 8 | tmp >> 8 & MASK) +#endif + +#if defined(SOLARIS) || defined(HPUX) +#define addto64(sumhigh, sumlow, addend) \ + sumlow += addend; sumhigh += (sumlow < addend); +#else +#define addto64(sumhigh, sumlow, addend) \ + sumlow += addend; if (sumlow < addend) ++sumhigh; +#endif + +#define F(X, Y, Z) \ + ((X & Y) | ((~X) & Z)) + +#define G(X, Y, Z) \ + ((X & Z) | (Y & (~Z))) + +#define H(X, Y, Z) \ + (X ^ Y ^ Z) + +#define I(X, Y, Z) \ + (Y ^ (X | (~Z))) + +#define FF(a, b, c, d, bufint, s, ti) \ + a = b + cls(a + F(b, c, d) + bufint + ti, s) + +#define GG(a, b, c, d, bufint, s, ti) \ + a = b + cls(a + G(b, c, d) + bufint + ti, s) + +#define HH(a, b, c, d, bufint, s, ti) \ + a = b + cls(a + H(b, c, d) + bufint + ti, s) + +#define II(a, b, c, d, bufint, s, ti) \ + a = b + cls(a + I(b, c, d) + bufint + ti, s) + +static void +md5_compress(MD5Context *cx) +{ + int i; + PRUint32 a, b, c, d; + PRUint32 tmp; + a = cx->cv[0]; + b = cx->cv[1]; + c = cx->cv[2]; + d = cx->cv[3]; +#ifndef IS_LITTLE_ENDIAN + for (i=0; i<16; ++i) + cx->u.w[i] = lendian(cx->u.w[i]); +#endif + FF(a, b, c, d, cx->u.w[R1B0 ], S1_0, T1_0); + FF(d, a, b, c, cx->u.w[R1B1 ], S1_1, T1_1); + FF(c, d, a, b, cx->u.w[R1B2 ], S1_2, T1_2); + FF(b, c, d, a, cx->u.w[R1B3 ], S1_3, T1_3); + FF(a, b, c, d, cx->u.w[R1B4 ], S1_0, T1_4); + FF(d, a, b, c, cx->u.w[R1B5 ], S1_1, T1_5); + FF(c, d, a, b, cx->u.w[R1B6 ], S1_2, T1_6); + FF(b, c, d, a, cx->u.w[R1B7 ], S1_3, T1_7); + FF(a, b, c, d, cx->u.w[R1B8 ], S1_0, T1_8); + FF(d, a, b, c, cx->u.w[R1B9 ], S1_1, T1_9); + FF(c, d, a, b, cx->u.w[R1B10], S1_2, T1_10); + FF(b, c, d, a, cx->u.w[R1B11], S1_3, T1_11); + FF(a, b, c, d, cx->u.w[R1B12], S1_0, T1_12); + FF(d, a, b, c, cx->u.w[R1B13], S1_1, T1_13); + FF(c, d, a, b, cx->u.w[R1B14], S1_2, T1_14); + FF(b, c, d, a, cx->u.w[R1B15], S1_3, T1_15); + GG(a, b, c, d, cx->u.w[R2B0 ], S2_0, T2_0); + GG(d, a, b, c, cx->u.w[R2B1 ], S2_1, T2_1); + GG(c, d, a, b, cx->u.w[R2B2 ], S2_2, T2_2); + GG(b, c, d, a, cx->u.w[R2B3 ], S2_3, T2_3); + GG(a, b, c, d, cx->u.w[R2B4 ], S2_0, T2_4); + GG(d, a, b, c, cx->u.w[R2B5 ], S2_1, T2_5); + GG(c, d, a, b, cx->u.w[R2B6 ], S2_2, T2_6); + GG(b, c, d, a, cx->u.w[R2B7 ], S2_3, T2_7); + GG(a, b, c, d, cx->u.w[R2B8 ], S2_0, T2_8); + GG(d, a, b, c, cx->u.w[R2B9 ], S2_1, T2_9); + GG(c, d, a, b, cx->u.w[R2B10], S2_2, T2_10); + GG(b, c, d, a, cx->u.w[R2B11], S2_3, T2_11); + GG(a, b, c, d, cx->u.w[R2B12], S2_0, T2_12); + GG(d, a, b, c, cx->u.w[R2B13], S2_1, T2_13); + GG(c, d, a, b, cx->u.w[R2B14], S2_2, T2_14); + GG(b, c, d, a, cx->u.w[R2B15], S2_3, T2_15); + HH(a, b, c, d, cx->u.w[R3B0 ], S3_0, T3_0); + HH(d, a, b, c, cx->u.w[R3B1 ], S3_1, T3_1); + HH(c, d, a, b, cx->u.w[R3B2 ], S3_2, T3_2); + HH(b, c, d, a, cx->u.w[R3B3 ], S3_3, T3_3); + HH(a, b, c, d, cx->u.w[R3B4 ], S3_0, T3_4); + HH(d, a, b, c, cx->u.w[R3B5 ], S3_1, T3_5); + HH(c, d, a, b, cx->u.w[R3B6 ], S3_2, T3_6); + HH(b, c, d, a, cx->u.w[R3B7 ], S3_3, T3_7); + HH(a, b, c, d, cx->u.w[R3B8 ], S3_0, T3_8); + HH(d, a, b, c, cx->u.w[R3B9 ], S3_1, T3_9); + HH(c, d, a, b, cx->u.w[R3B10], S3_2, T3_10); + HH(b, c, d, a, cx->u.w[R3B11], S3_3, T3_11); + HH(a, b, c, d, cx->u.w[R3B12], S3_0, T3_12); + HH(d, a, b, c, cx->u.w[R3B13], S3_1, T3_13); + HH(c, d, a, b, cx->u.w[R3B14], S3_2, T3_14); + HH(b, c, d, a, cx->u.w[R3B15], S3_3, T3_15); + II(a, b, c, d, cx->u.w[R4B0 ], S4_0, T4_0); + II(d, a, b, c, cx->u.w[R4B1 ], S4_1, T4_1); + II(c, d, a, b, cx->u.w[R4B2 ], S4_2, T4_2); + II(b, c, d, a, cx->u.w[R4B3 ], S4_3, T4_3); + II(a, b, c, d, cx->u.w[R4B4 ], S4_0, T4_4); + II(d, a, b, c, cx->u.w[R4B5 ], S4_1, T4_5); + II(c, d, a, b, cx->u.w[R4B6 ], S4_2, T4_6); + II(b, c, d, a, cx->u.w[R4B7 ], S4_3, T4_7); + II(a, b, c, d, cx->u.w[R4B8 ], S4_0, T4_8); + II(d, a, b, c, cx->u.w[R4B9 ], S4_1, T4_9); + II(c, d, a, b, cx->u.w[R4B10], S4_2, T4_10); + II(b, c, d, a, cx->u.w[R4B11], S4_3, T4_11); + II(a, b, c, d, cx->u.w[R4B12], S4_0, T4_12); + II(d, a, b, c, cx->u.w[R4B13], S4_1, T4_13); + II(c, d, a, b, cx->u.w[R4B14], S4_2, T4_14); + II(b, c, d, a, cx->u.w[R4B15], S4_3, T4_15); + cx->cv[0] += a; + cx->cv[1] += b; + cx->cv[2] += c; + cx->cv[3] += d; + cx->inBufIndex = 0; +} + +void +MD5_Update(MD5Context *cx, const unsigned char *input, unsigned int inputLen) +{ + PRUint32 bytesToConsume; + + /* Add the number of input bytes to the 64-bit input counter. */ + addto64(cx->msbInput, cx->lsbInput, inputLen); + if (cx->inBufIndex) { + /* There is already data in the buffer. Fill with input. */ + bytesToConsume = PR_MIN(inputLen, MD5_BUFFER_SIZE - cx->inBufIndex); + memcpy(&cx->inBuf[cx->inBufIndex], input, bytesToConsume); + if (cx->inBufIndex + bytesToConsume >= MD5_BUFFER_SIZE) + /* The buffer is filled. Run the compression function. */ + md5_compress(cx); + /* Remaining input. */ + inputLen -= bytesToConsume; + input += bytesToConsume; + } + + /* Iterate over 64-byte chunks of the message. */ + while (inputLen >= MD5_BUFFER_SIZE) { + memcpy(cx->inBuf, input, MD5_BUFFER_SIZE); + md5_compress(cx); + inputLen -= MD5_BUFFER_SIZE; + input += MD5_BUFFER_SIZE; + } + + /* Tail of message (message bytes mod 64). */ + if (inputLen) + memcpy(cx->inBuf, input, inputLen); + cx->inBufIndex = inputLen; +} + +static const unsigned char padbytes[] = { + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + +void +MD5_End(MD5Context *cx, unsigned char *digest, + unsigned int *digestLen, unsigned int maxDigestLen) +{ + PRUint32 tmp; + PRUint32 lowInput, highInput; + int i; + + if (maxDigestLen < MD5_HASH_LEN) { + PORT_SetError(SEC_ERROR_INVALID_ARGS); + return; + } + + /* Copy out the length of bits input before padding. */ + lowInput = cx->lsbInput; + highInput = (cx->msbInput << 3) | (lowInput >> 29); + lowInput <<= 3; + + if (cx->inBufIndex < MD5_END_BUFFER) { + MD5_Update(cx, padbytes, MD5_END_BUFFER - cx->inBufIndex); + } else { + MD5_Update(cx, padbytes, + MD5_END_BUFFER + MD5_BUFFER_SIZE - cx->inBufIndex); + } + + /* Store the number of bytes input (before padding) in final 64 bits. */ + cx->u.w[14] = lendian(lowInput); + cx->u.w[15] = lendian(highInput); + + /* Final call to compress. */ + md5_compress(cx); + + /* Copy the resulting values out of the chain variables into return buf. */ + *digestLen = MD5_HASH_LEN; +#ifndef IS_LITTLE_ENDIAN + cx->cv[0] = lendian(cx->cv[0]); + cx->cv[1] = lendian(cx->cv[1]); + cx->cv[2] = lendian(cx->cv[2]); + cx->cv[3] = lendian(cx->cv[3]); +#endif + memcpy(digest, cx->cv, MD5_HASH_LEN); +} + +unsigned int +MD5_FlattenSize(MD5Context *cx) +{ + return sizeof(*cx); +} + +SECStatus +MD5_Flatten(MD5Context *cx, unsigned char *space) +{ + memcpy(space, cx, sizeof(*cx)); + return SECSuccess; +} + +MD5Context * +MD5_Resurrect(unsigned char *space, void *arg) +{ + MD5Context *cx = MD5_NewContext(); + if (cx) + memcpy(cx, space, sizeof(*cx)); + return cx; +} + +void +MD5_TraceState(MD5Context *cx) +{ + PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); +} |