OSDN Git Service

2013.10.24
[uclinux-h8/uClinux-dist.git] / freeswan / 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], 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, 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 unsigned char *PADDING[] = {
68   (unsigned char *)"",
69   (unsigned char *)"\001",
70   (unsigned char *)"\002\002",
71   (unsigned char *)"\003\003\003",
72   (unsigned char *)"\004\004\004\004",
73   (unsigned char *)"\005\005\005\005\005",
74   (unsigned char *)"\006\006\006\006\006\006",
75   (unsigned char *)"\007\007\007\007\007\007\007",
76   (unsigned char *)"\010\010\010\010\010\010\010\010",
77   (unsigned char *)"\011\011\011\011\011\011\011\011\011",
78   (unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
79   (unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
80   (unsigned char *)"\014\014\014\014\014\014\014\014\014\014\014\014",
81   (unsigned char *)
82     "\015\015\015\015\015\015\015\015\015\015\015\015\015",
83   (unsigned char *)
84     "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
85   (unsigned char *)
86     "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
87   (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 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], (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], (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 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, (POINTER)state, 16);
181   MD2_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   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