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