Linuxulator: Fix recent breakage, part II
[dragonfly.git] / lib / libmd / md2c.c
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.4 2008/09/30 16:57:05 swildner Exp $
4  */
5
6 /* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
7    rights reserved.
8
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
13    or this function.
14
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.
19
20    These notices must be retained in any copies of any part of this
21    documentation and/or software.
22  */
23
24 #include <sys/types.h>
25 #include <string.h>
26 #include "md2.h"
27
28
29 typedef unsigned char *POINTER;
30 typedef u_int16_t UINT2;
31 typedef u_int32_t UINT4;
32
33 #define PROTO_LIST(list) list
34
35 static void MD2Transform PROTO_LIST
36   ((unsigned char [16], unsigned char [16], const unsigned char [16]));
37
38 /* Permutation of 0..255 constructed from the digits of pi. It gives a
39    "random" nonlinear byte substitution operation.
40  */
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
60 };
61
62 static unsigned char *PADDING[] = {
63   (unsigned char *)"",
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",
76   (unsigned char *)
77     "\015\015\015\015\015\015\015\015\015\015\015\015\015",
78   (unsigned char *)
79     "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
80   (unsigned char *)
81     "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
82   (unsigned char *)
83     "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
84 };
85
86 /* MD2 initialization. Begins an MD2 operation, writing a new context.
87  */
88 void
89 MD2Init (MD2_CTX *context)
90 {
91   context->count = 0;
92   memset ((POINTER)context->state, 0, sizeof (context->state));
93   memset
94     ((POINTER)context->checksum, 0, sizeof (context->checksum));
95 }
96
97 /* MD2 block update operation. Continues an MD2 message-digest
98      operation, processing another message block, and updating the
99      context.
100  */
101 void
102 MD2Update (MD2_CTX *context, const void *in, unsigned int inputLen)
103 {
104   unsigned int i, idx, partLen;
105   const unsigned char *input = in;
106
107   /* Update number of bytes mod 16 */
108   idx = context->count;
109   context->count = (idx + inputLen) & 0xf;
110
111   partLen = 16 - idx;
112
113   /* Transform as many times as possible.
114     */
115   if (inputLen >= partLen) {
116     memcpy
117       ((POINTER)&context->buffer[idx], (POINTER)input, partLen);
118     MD2Transform (context->state, context->checksum, context->buffer);
119
120     for (i = partLen; i + 15 < inputLen; i += 16)
121       MD2Transform (context->state, context->checksum, &input[i]);
122
123     idx = 0;
124   }
125   else
126     i = 0;
127
128   /* Buffer remaining input */
129   memcpy
130     ((POINTER)&context->buffer[idx], (POINTER)&input[i],
131      inputLen-i);
132 }
133
134 /* MD2 padding.
135  */
136 void
137 MD2Pad (MD2_CTX *context)
138 {
139   unsigned int idx, padLen;
140
141   /* Pad out to multiple of 16.
142    */
143   idx = context->count;
144   padLen = 16 - idx;
145   MD2Update (context, PADDING[padLen], padLen);
146
147   /* Extend with checksum */
148   MD2Update (context, context->checksum, 16);
149 }
150
151 /* MD2 finalization. Ends an MD2 message-digest operation, writing the
152      message digest and zeroizing the context.
153  */
154 void
155 MD2Final (unsigned char digest[16], MD2_CTX *context)
156 {
157   /* Do padding */
158   MD2Pad (context);
159
160   /* Store state in digest */
161   memcpy ((POINTER)digest, (POINTER)context->state, 16);
162
163   /* Zeroize sensitive information.
164    */
165   memset ((POINTER)context, 0, sizeof (*context));
166 }
167
168 /* MD2 basic transformation. Transforms state and updates checksum
169      based on block.
170  */
171 static void
172 MD2Transform (unsigned char state[16], unsigned char checksum[16],
173     const unsigned char block[16])
174 {
175   unsigned int i, j, t;
176   unsigned char x[48];
177
178   /* Form encryption block from state, block, state ^ block.
179    */
180   memcpy ((POINTER)x, (POINTER)state, 16);
181   memcpy ((POINTER)x+16, (POINTER)block, 16);
182   for (i = 0; i < 16; i++)
183     x[i+32] = state[i] ^ block[i];
184
185   /* Encrypt block (18 rounds).
186    */
187   t = 0;
188   for (i = 0; i < 18; i++) {
189     for (j = 0; j < 48; j++)
190       t = x[j] ^= PI_SUBST[t];
191     t = (t + i) & 0xff;
192   }
193
194   /* Save new state */
195   memcpy ((POINTER)state, (POINTER)x, 16);
196
197   /* Update checksum.
198    */
199   t = checksum[15];
200   for (i = 0; i < 16; i++)
201     t = checksum[i] ^= PI_SUBST[block[i] ^ t];
202
203   /* Zeroize sensitive information.
204    */
205   memset ((POINTER)x, 0, sizeof (x));
206 }