md2.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:7k
源码类别:

CA认证

开发平台:

WINDOWS

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