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