More minor IPI work.
[dragonfly/vkernel-mp.git] / lib / libmd / md2c.c
blob8d0b9b2e8a6868079c4eaf1bf46a9c67835fafc4
1 /* MD2C.C - RSA Data Security, Inc., MD2 message-digest algorithm
2 * $FreeBSD: src/lib/libmd/md2c.c,v 1.7 1999/08/28 00:05:05 peter Exp $
3 * $DragonFly: src/lib/libmd/md2c.c,v 1.2 2003/06/17 06:26:50 dillon Exp $
4 */
6 /* Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
7 rights reserved.
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.
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 "md2.h"
25 #include <string.h>
26 #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[] = {
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"
86 /* MD2 initialization. Begins an MD2 operation, writing a new context.
88 void MD2Init (context)
89 MD2_CTX *context; /* context */
91 context->count = 0;
92 memset ((POINTER)context->state, 0, sizeof (context->state));
93 memset
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
99 context.
101 void MD2Update (context, input, inputLen)
102 MD2_CTX *context; /* context */
103 const unsigned char *input; /* input block */
104 unsigned int inputLen; /* length of input block */
106 unsigned int i, index, partLen;
108 /* Update number of bytes mod 16 */
109 index = context->count;
110 context->count = (index + inputLen) & 0xf;
112 partLen = 16 - index;
114 /* Transform as many times as possible.
116 if (inputLen >= partLen) {
117 memcpy
118 ((POINTER)&context->buffer[index], (POINTER)input, partLen);
119 MD2Transform (context->state, context->checksum, context->buffer);
121 for (i = partLen; i + 15 < inputLen; i += 16)
122 MD2Transform (context->state, context->checksum, &input[i]);
124 index = 0;
126 else
127 i = 0;
129 /* Buffer remaining input */
130 memcpy
131 ((POINTER)&context->buffer[index], (POINTER)&input[i],
132 inputLen-i);
135 /* MD2 padding.
137 void MD2Pad (context)
138 MD2_CTX *context; /* context */
140 unsigned int index, padLen;
142 /* Pad out to multiple of 16.
144 index = context->count;
145 padLen = 16 - index;
146 MD2Update (context, PADDING[padLen], padLen);
148 /* Extend with checksum */
149 MD2Update (context, context->checksum, 16);
152 /* MD2 finalization. Ends an MD2 message-digest operation, writing the
153 message digest and zeroizing the context.
155 void MD2Final (digest, context)
156 unsigned char digest[16]; /* message digest */
157 MD2_CTX *context; /* context */
159 /* Do padding */
160 MD2Pad (context);
162 /* Store state in digest */
163 memcpy ((POINTER)digest, (POINTER)context->state, 16);
165 /* Zeroize sensitive information.
167 memset ((POINTER)context, 0, sizeof (*context));
170 /* MD2 basic transformation. Transforms state and updates checksum
171 based on block.
173 static void MD2Transform (state, checksum, block)
174 unsigned char state[16];
175 unsigned char checksum[16];
176 const unsigned char block[16];
178 unsigned int i, j, t;
179 unsigned char x[48];
181 /* Form encryption block from state, block, state ^ block.
183 memcpy ((POINTER)x, (POINTER)state, 16);
184 memcpy ((POINTER)x+16, (POINTER)block, 16);
185 for (i = 0; i < 16; i++)
186 x[i+32] = state[i] ^ block[i];
188 /* Encrypt block (18 rounds).
190 t = 0;
191 for (i = 0; i < 18; i++) {
192 for (j = 0; j < 48; j++)
193 t = x[j] ^= PI_SUBST[t];
194 t = (t + i) & 0xff;
197 /* Save new state */
198 memcpy ((POINTER)state, (POINTER)x, 16);
200 /* Update checksum.
202 t = checksum[15];
203 for (i = 0; i < 16; i++)
204 t = checksum[i] ^= PI_SUBST[block[i] ^ t];
206 /* Zeroize sensitive information.
208 memset ((POINTER)x, 0, sizeof (x));