source: trunk/third/moira/util/rsaref/md2c.c @ 23095

Revision 23095, 6.9 KB checked in by ghudson, 16 years ago (diff)
Import the moira package from SIPB Debathena.
Line 
1/* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm
2 */
3
4/* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
5   rights reserved.
6
7   License to copy and use this software is granted for
8   non-commercial Internet Privacy-Enhanced Mail provided that it is
9   identified as the "RSA Data Security, Inc. MD2 Message Digest
10   Algorithm" in all material mentioning or referencing this software
11   or this function.
12
13   RSA Data Security, Inc. makes no representations concerning either
14   the merchantability of this software or the suitability of this
15   software for any particular purpose. It is provided "as is"
16   without express or implied warranty of any kind.
17
18   These notices must be retained in any copies of any part of this
19   documentation and/or software. 
20 */
21
22#include "global.h"
23#include "md2.h"
24
25static void MD2Transform PROTO_LIST
26  ((unsigned char [16], unsigned char [16], unsigned char [16]));
27static void MD2_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
28static void MD2_memset PROTO_LIST ((POINTER, int, unsigned int));
29
30/* Permutation of 0..255 constructed from the digits of pi. It gives a
31   "random" nonlinear byte substitution operation.
32 */
33static unsigned char PI_SUBST[256] = {
34  41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
35  19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
36  76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
37  138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
38  245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
39  148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
40  39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
41  181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
42  150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
43  112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
44  96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
45  85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
46  234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
47  129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
48  8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
49  203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
50  166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
51  31, 26, 219, 153, 141, 51, 159, 17, 131, 20
52};
53
54static unsigned char *PADDING[] = {
55  (unsigned char *)"",
56  (unsigned char *)"\001",
57  (unsigned char *)"\002\002",
58  (unsigned char *)"\003\003\003",
59  (unsigned char *)"\004\004\004\004",
60  (unsigned char *)"\005\005\005\005\005",
61  (unsigned char *)"\006\006\006\006\006\006",
62  (unsigned char *)"\007\007\007\007\007\007\007",
63  (unsigned char *)"\010\010\010\010\010\010\010\010",
64  (unsigned char *)"\011\011\011\011\011\011\011\011\011",
65  (unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
66  (unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
67  (unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
68  (unsigned char *)
69    "\015\015\015\015\015\015\015\015\015\015\015\015\015",
70  (unsigned char *)
71    "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
72  (unsigned char *)
73    "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
74  (unsigned char *)
75    "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
76};
77
78/* MD2 initialization. Begins an MD2 operation, writing a new context.
79 */
80void MD2Init (context)
81MD2_CTX *context;                                        /* context */
82{
83  context->count = 0;
84  MD2_memset ((POINTER)context->state, 0, sizeof (context->state));
85  MD2_memset
86    ((POINTER)context->checksum, 0, sizeof (context->checksum));
87}
88
89/* MD2 block update operation. Continues an MD2 message-digest
90     operation, processing another message block, and updating the
91     context.
92 */
93void MD2Update (context, input, inputLen)
94MD2_CTX *context;                                        /* context */
95unsigned char *input;                                /* input block */
96unsigned int inputLen;                     /* length of input block */
97{
98  unsigned int i, index, partLen;
99 
100  /* Update number of bytes mod 16 */
101  index = context->count;
102  context->count = (index + inputLen) & 0xf;
103 
104  partLen = 16 - index;
105 
106  /* Transform as many times as possible.
107    */
108  if (inputLen >= partLen) {
109    MD2_memcpy
110      ((POINTER)&context->buffer[index], (POINTER)input, partLen);
111    MD2Transform (context->state, context->checksum, context->buffer);
112
113    for (i = partLen; i + 15 < inputLen; i += 16)
114      MD2Transform (context->state, context->checksum, &input[i]);
115   
116    index = 0;
117  }
118  else
119    i = 0;
120 
121  /* Buffer remaining input */
122  MD2_memcpy
123    ((POINTER)&context->buffer[index], (POINTER)&input[i],
124     inputLen-i);
125}
126
127/* MD2 finalization. Ends an MD2 message-digest operation, writing the
128     message digest and zeroizing the context.
129 */
130void MD2Final (digest, context)
131unsigned char digest[16];                         /* message digest */
132MD2_CTX *context;                                        /* context */
133{
134  unsigned int index, padLen;
135
136  /* Pad out to multiple of 16.
137   */
138  index = context->count;
139  padLen = 16 - index;
140  MD2Update (context, PADDING[padLen], padLen);
141
142  /* Extend with checksum */
143  MD2Update (context, context->checksum, 16);
144 
145  /* Store state in digest */
146  MD2_memcpy ((POINTER)digest, (POINTER)context->state, 16);
147 
148  /* Zeroize sensitive information.
149   */
150  MD2_memset ((POINTER)context, 0, sizeof (*context));
151}
152
153/* MD2 basic transformation. Transforms state and updates checksum
154     based on block.
155 */
156static void MD2Transform (state, checksum, block)
157unsigned char state[16];
158unsigned char checksum[16];
159unsigned char block[16];
160{
161  unsigned int i, j, t;
162  unsigned char x[48];
163 
164  /* Form encryption block from state, block, state ^ block.
165   */
166  MD2_memcpy ((POINTER)x, (POINTER)state, 16);
167  MD2_memcpy ((POINTER)x+16, (POINTER)block, 16);
168  for (i = 0; i < 16; i++)
169    x[i+32] = state[i] ^ block[i];
170 
171  /* Encrypt block (18 rounds).
172   */
173  t = 0;
174  for (i = 0; i < 18; i++) {
175    for (j = 0; j < 48; j++)
176      t = x[j] ^= PI_SUBST[t];
177    t = (t + i) & 0xff;
178  }
179   
180  /* Save new state */
181  MD2_memcpy ((POINTER)state, (POINTER)x, 16);
182   
183  /* Update checksum.
184   */
185  t = checksum[15];
186  for (i = 0; i < 16; i++)
187    t = checksum[i] ^= PI_SUBST[block[i] ^ t];
188
189  /* Zeroize sensitive information.
190   */
191  MD2_memset ((POINTER)x, 0, sizeof (x));
192}
193
194/* Note: Replace "for loop" with standard memcpy if possible.
195 */
196static void MD2_memcpy (output, input, len)
197POINTER output;
198POINTER input;
199unsigned int len;
200{
201  unsigned int i;
202 
203  for (i = 0; i < len; i++)
204    output[i] = input[i];
205}
206
207/* Note: Replace "for loop" with standard memset if possible.
208 */
209static void MD2_memset (output, value, len)
210POINTER output;
211int value;
212unsigned int len;
213{
214  unsigned int i;
215 
216  for (i = 0; i < len; i++)
217    ((char *)output)[i] = (char)value;
218}
Note: See TracBrowser for help on using the repository browser.