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