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