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