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