Branching 3.2/3.3
[dragonfly.git] / lib / libmd / md2c.c
blob61f94daf91bb4f573176af8d436a1c051bbcd16f
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 */
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 <sys/types.h>
25 #include <string.h>
26 #include "md2.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
89 MD2Init (MD2_CTX *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
102 MD2Update (MD2_CTX *context, const void *in, unsigned int inputLen)
104 unsigned int i, idx, partLen;
105 const unsigned char *input = in;
107 /* Update number of bytes mod 16 */
108 idx = context->count;
109 context->count = (idx + inputLen) & 0xf;
111 partLen = 16 - idx;
113 /* Transform as many times as possible.
115 if (inputLen >= partLen) {
116 memcpy
117 ((POINTER)&context->buffer[idx], (POINTER)input, partLen);
118 MD2Transform (context->state, context->checksum, context->buffer);
120 for (i = partLen; i + 15 < inputLen; i += 16)
121 MD2Transform (context->state, context->checksum, &input[i]);
123 idx = 0;
125 else
126 i = 0;
128 /* Buffer remaining input */
129 memcpy
130 ((POINTER)&context->buffer[idx], (POINTER)&input[i],
131 inputLen-i);
134 /* MD2 padding.
136 void
137 MD2Pad (MD2_CTX *context)
139 unsigned int idx, padLen;
141 /* Pad out to multiple of 16.
143 idx = context->count;
144 padLen = 16 - idx;
145 MD2Update (context, PADDING[padLen], padLen);
147 /* Extend with checksum */
148 MD2Update (context, context->checksum, 16);
151 /* MD2 finalization. Ends an MD2 message-digest operation, writing the
152 message digest and zeroizing the context.
154 void
155 MD2Final (unsigned char digest[16], MD2_CTX *context)
157 /* Do padding */
158 MD2Pad (context);
160 /* Store state in digest */
161 memcpy ((POINTER)digest, (POINTER)context->state, 16);
163 /* Zeroize sensitive information.
165 memset ((POINTER)context, 0, sizeof (*context));
168 /* MD2 basic transformation. Transforms state and updates checksum
169 based on block.
171 static void
172 MD2Transform (unsigned char state[16], unsigned char checksum[16],
173 const unsigned char block[16])
175 unsigned int i, j, t;
176 unsigned char x[48];
178 /* Form encryption block from state, block, state ^ block.
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];
185 /* Encrypt block (18 rounds).
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;
194 /* Save new state */
195 memcpy ((POINTER)state, (POINTER)x, 16);
197 /* Update checksum.
199 t = checksum[15];
200 for (i = 0; i < 16; i++)
201 t = checksum[i] ^= PI_SUBST[block[i] ^ t];
203 /* Zeroize sensitive information.
205 memset ((POINTER)x, 0, sizeof (x));