1ebfedea0SLionel Sambuc /* crypto/md2/md2_dgst.c */
2ebfedea0SLionel Sambuc /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3ebfedea0SLionel Sambuc * All rights reserved.
4ebfedea0SLionel Sambuc *
5ebfedea0SLionel Sambuc * This package is an SSL implementation written
6ebfedea0SLionel Sambuc * by Eric Young (eay@cryptsoft.com).
7ebfedea0SLionel Sambuc * The implementation was written so as to conform with Netscapes SSL.
8ebfedea0SLionel Sambuc *
9ebfedea0SLionel Sambuc * This library is free for commercial and non-commercial use as long as
10ebfedea0SLionel Sambuc * the following conditions are aheared to. The following conditions
11ebfedea0SLionel Sambuc * apply to all code found in this distribution, be it the RC4, RSA,
12ebfedea0SLionel Sambuc * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13ebfedea0SLionel Sambuc * included with this distribution is covered by the same copyright terms
14ebfedea0SLionel Sambuc * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15ebfedea0SLionel Sambuc *
16ebfedea0SLionel Sambuc * Copyright remains Eric Young's, and as such any Copyright notices in
17ebfedea0SLionel Sambuc * the code are not to be removed.
18ebfedea0SLionel Sambuc * If this package is used in a product, Eric Young should be given attribution
19ebfedea0SLionel Sambuc * as the author of the parts of the library used.
20ebfedea0SLionel Sambuc * This can be in the form of a textual message at program startup or
21ebfedea0SLionel Sambuc * in documentation (online or textual) provided with the package.
22ebfedea0SLionel Sambuc *
23ebfedea0SLionel Sambuc * Redistribution and use in source and binary forms, with or without
24ebfedea0SLionel Sambuc * modification, are permitted provided that the following conditions
25ebfedea0SLionel Sambuc * are met:
26ebfedea0SLionel Sambuc * 1. Redistributions of source code must retain the copyright
27ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer.
28ebfedea0SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
29ebfedea0SLionel Sambuc * notice, this list of conditions and the following disclaimer in the
30ebfedea0SLionel Sambuc * documentation and/or other materials provided with the distribution.
31ebfedea0SLionel Sambuc * 3. All advertising materials mentioning features or use of this software
32ebfedea0SLionel Sambuc * must display the following acknowledgement:
33ebfedea0SLionel Sambuc * "This product includes cryptographic software written by
34ebfedea0SLionel Sambuc * Eric Young (eay@cryptsoft.com)"
35ebfedea0SLionel Sambuc * The word 'cryptographic' can be left out if the rouines from the library
36ebfedea0SLionel Sambuc * being used are not cryptographic related :-).
37ebfedea0SLionel Sambuc * 4. If you include any Windows specific code (or a derivative thereof) from
38ebfedea0SLionel Sambuc * the apps directory (application code) you must include an acknowledgement:
39ebfedea0SLionel Sambuc * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40ebfedea0SLionel Sambuc *
41ebfedea0SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42ebfedea0SLionel Sambuc * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43ebfedea0SLionel Sambuc * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44ebfedea0SLionel Sambuc * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45ebfedea0SLionel Sambuc * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46ebfedea0SLionel Sambuc * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47ebfedea0SLionel Sambuc * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48ebfedea0SLionel Sambuc * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49ebfedea0SLionel Sambuc * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50ebfedea0SLionel Sambuc * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51ebfedea0SLionel Sambuc * SUCH DAMAGE.
52ebfedea0SLionel Sambuc *
53ebfedea0SLionel Sambuc * The licence and distribution terms for any publically available version or
54ebfedea0SLionel Sambuc * derivative of this code cannot be changed. i.e. this code cannot simply be
55ebfedea0SLionel Sambuc * copied and put under another distribution licence
56ebfedea0SLionel Sambuc * [including the GNU Public Licence.]
57ebfedea0SLionel Sambuc */
58ebfedea0SLionel Sambuc
59ebfedea0SLionel Sambuc #include <stdio.h>
60ebfedea0SLionel Sambuc #include <stdlib.h>
61ebfedea0SLionel Sambuc #include <string.h>
62ebfedea0SLionel Sambuc #include <openssl/md2.h>
63ebfedea0SLionel Sambuc #include <openssl/opensslv.h>
64ebfedea0SLionel Sambuc #include <openssl/crypto.h>
65ebfedea0SLionel Sambuc
66ebfedea0SLionel Sambuc const char MD2_version[] = "MD2" OPENSSL_VERSION_PTEXT;
67ebfedea0SLionel Sambuc
68*0a6a1f1dSLionel Sambuc /*
69*0a6a1f1dSLionel Sambuc * Implemented from RFC1319 The MD2 Message-Digest Algorithm
70ebfedea0SLionel Sambuc */
71ebfedea0SLionel Sambuc
72ebfedea0SLionel Sambuc #define UCHAR unsigned char
73ebfedea0SLionel Sambuc
74ebfedea0SLionel Sambuc static void md2_block(MD2_CTX *c, const unsigned char *d);
75*0a6a1f1dSLionel Sambuc /*
76*0a6a1f1dSLionel Sambuc * The magic S table - I have converted it to hex since it is basically just
77*0a6a1f1dSLionel Sambuc * a random byte string.
78*0a6a1f1dSLionel Sambuc */
79ebfedea0SLionel Sambuc static const MD2_INT S[256] = {
80ebfedea0SLionel Sambuc 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01,
81ebfedea0SLionel Sambuc 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13,
82ebfedea0SLionel Sambuc 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C,
83ebfedea0SLionel Sambuc 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA,
84ebfedea0SLionel Sambuc 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
85ebfedea0SLionel Sambuc 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12,
86ebfedea0SLionel Sambuc 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49,
87ebfedea0SLionel Sambuc 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A,
88ebfedea0SLionel Sambuc 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F,
89ebfedea0SLionel Sambuc 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
90ebfedea0SLionel Sambuc 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27,
91ebfedea0SLionel Sambuc 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03,
92ebfedea0SLionel Sambuc 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1,
93ebfedea0SLionel Sambuc 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6,
94ebfedea0SLionel Sambuc 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
95ebfedea0SLionel Sambuc 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1,
96ebfedea0SLionel Sambuc 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20,
97ebfedea0SLionel Sambuc 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02,
98ebfedea0SLionel Sambuc 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6,
99ebfedea0SLionel Sambuc 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
100ebfedea0SLionel Sambuc 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A,
101ebfedea0SLionel Sambuc 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26,
102ebfedea0SLionel Sambuc 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09,
103ebfedea0SLionel Sambuc 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52,
104ebfedea0SLionel Sambuc 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
105ebfedea0SLionel Sambuc 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A,
106ebfedea0SLionel Sambuc 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D,
107ebfedea0SLionel Sambuc 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39,
108ebfedea0SLionel Sambuc 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4,
109ebfedea0SLionel Sambuc 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
110ebfedea0SLionel Sambuc 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A,
111ebfedea0SLionel Sambuc 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14,
112ebfedea0SLionel Sambuc };
113ebfedea0SLionel Sambuc
MD2_options(void)114ebfedea0SLionel Sambuc const char *MD2_options(void)
115ebfedea0SLionel Sambuc {
116ebfedea0SLionel Sambuc if (sizeof(MD2_INT) == 1)
117ebfedea0SLionel Sambuc return ("md2(char)");
118ebfedea0SLionel Sambuc else
119ebfedea0SLionel Sambuc return ("md2(int)");
120ebfedea0SLionel Sambuc }
121ebfedea0SLionel Sambuc
fips_md_init(MD2)122ebfedea0SLionel Sambuc fips_md_init(MD2)
123ebfedea0SLionel Sambuc {
124ebfedea0SLionel Sambuc c->num = 0;
125ebfedea0SLionel Sambuc memset(c->state, 0, sizeof c->state);
126ebfedea0SLionel Sambuc memset(c->cksm, 0, sizeof c->cksm);
127ebfedea0SLionel Sambuc memset(c->data, 0, sizeof c->data);
128ebfedea0SLionel Sambuc return 1;
129ebfedea0SLionel Sambuc }
130ebfedea0SLionel Sambuc
MD2_Update(MD2_CTX * c,const unsigned char * data,size_t len)131ebfedea0SLionel Sambuc int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len)
132ebfedea0SLionel Sambuc {
133ebfedea0SLionel Sambuc register UCHAR *p;
134ebfedea0SLionel Sambuc
135*0a6a1f1dSLionel Sambuc if (len == 0)
136*0a6a1f1dSLionel Sambuc return 1;
137ebfedea0SLionel Sambuc
138ebfedea0SLionel Sambuc p = c->data;
139*0a6a1f1dSLionel Sambuc if (c->num != 0) {
140*0a6a1f1dSLionel Sambuc if ((c->num + len) >= MD2_BLOCK) {
141ebfedea0SLionel Sambuc memcpy(&(p[c->num]), data, MD2_BLOCK - c->num);
142ebfedea0SLionel Sambuc md2_block(c, c->data);
143ebfedea0SLionel Sambuc data += (MD2_BLOCK - c->num);
144ebfedea0SLionel Sambuc len -= (MD2_BLOCK - c->num);
145ebfedea0SLionel Sambuc c->num = 0;
146ebfedea0SLionel Sambuc /* drop through and do the rest */
147*0a6a1f1dSLionel Sambuc } else {
148ebfedea0SLionel Sambuc memcpy(&(p[c->num]), data, len);
149ebfedea0SLionel Sambuc /* data+=len; */
150ebfedea0SLionel Sambuc c->num += (int)len;
151ebfedea0SLionel Sambuc return 1;
152ebfedea0SLionel Sambuc }
153ebfedea0SLionel Sambuc }
154*0a6a1f1dSLionel Sambuc /*
155*0a6a1f1dSLionel Sambuc * we now can process the input data in blocks of MD2_BLOCK chars and
156*0a6a1f1dSLionel Sambuc * save the leftovers to c->data.
157*0a6a1f1dSLionel Sambuc */
158*0a6a1f1dSLionel Sambuc while (len >= MD2_BLOCK) {
159ebfedea0SLionel Sambuc md2_block(c, data);
160ebfedea0SLionel Sambuc data += MD2_BLOCK;
161ebfedea0SLionel Sambuc len -= MD2_BLOCK;
162ebfedea0SLionel Sambuc }
163ebfedea0SLionel Sambuc memcpy(p, data, len);
164ebfedea0SLionel Sambuc c->num = (int)len;
165ebfedea0SLionel Sambuc return 1;
166ebfedea0SLionel Sambuc }
167ebfedea0SLionel Sambuc
md2_block(MD2_CTX * c,const unsigned char * d)168ebfedea0SLionel Sambuc static void md2_block(MD2_CTX *c, const unsigned char *d)
169ebfedea0SLionel Sambuc {
170ebfedea0SLionel Sambuc register MD2_INT t, *sp1, *sp2;
171ebfedea0SLionel Sambuc register int i, j;
172ebfedea0SLionel Sambuc MD2_INT state[48];
173ebfedea0SLionel Sambuc
174ebfedea0SLionel Sambuc sp1 = c->state;
175ebfedea0SLionel Sambuc sp2 = c->cksm;
176ebfedea0SLionel Sambuc j = sp2[MD2_BLOCK - 1];
177*0a6a1f1dSLionel Sambuc for (i = 0; i < 16; i++) {
178ebfedea0SLionel Sambuc state[i] = sp1[i];
179ebfedea0SLionel Sambuc state[i + 16] = t = d[i];
180ebfedea0SLionel Sambuc state[i + 32] = (t ^ sp1[i]);
181ebfedea0SLionel Sambuc j = sp2[i] ^= S[t ^ j];
182ebfedea0SLionel Sambuc }
183ebfedea0SLionel Sambuc t = 0;
184*0a6a1f1dSLionel Sambuc for (i = 0; i < 18; i++) {
185*0a6a1f1dSLionel Sambuc for (j = 0; j < 48; j += 8) {
186ebfedea0SLionel Sambuc t = state[j + 0] ^= S[t];
187ebfedea0SLionel Sambuc t = state[j + 1] ^= S[t];
188ebfedea0SLionel Sambuc t = state[j + 2] ^= S[t];
189ebfedea0SLionel Sambuc t = state[j + 3] ^= S[t];
190ebfedea0SLionel Sambuc t = state[j + 4] ^= S[t];
191ebfedea0SLionel Sambuc t = state[j + 5] ^= S[t];
192ebfedea0SLionel Sambuc t = state[j + 6] ^= S[t];
193ebfedea0SLionel Sambuc t = state[j + 7] ^= S[t];
194ebfedea0SLionel Sambuc }
195ebfedea0SLionel Sambuc t = (t + i) & 0xff;
196ebfedea0SLionel Sambuc }
197ebfedea0SLionel Sambuc memcpy(sp1, state, 16 * sizeof(MD2_INT));
198ebfedea0SLionel Sambuc OPENSSL_cleanse(state, 48 * sizeof(MD2_INT));
199ebfedea0SLionel Sambuc }
200ebfedea0SLionel Sambuc
MD2_Final(unsigned char * md,MD2_CTX * c)201ebfedea0SLionel Sambuc int MD2_Final(unsigned char *md, MD2_CTX *c)
202ebfedea0SLionel Sambuc {
203ebfedea0SLionel Sambuc int i, v;
204ebfedea0SLionel Sambuc register UCHAR *cp;
205ebfedea0SLionel Sambuc register MD2_INT *p1, *p2;
206ebfedea0SLionel Sambuc
207ebfedea0SLionel Sambuc cp = c->data;
208ebfedea0SLionel Sambuc p1 = c->state;
209ebfedea0SLionel Sambuc p2 = c->cksm;
210ebfedea0SLionel Sambuc v = MD2_BLOCK - c->num;
211ebfedea0SLionel Sambuc for (i = c->num; i < MD2_BLOCK; i++)
212ebfedea0SLionel Sambuc cp[i] = (UCHAR) v;
213ebfedea0SLionel Sambuc
214ebfedea0SLionel Sambuc md2_block(c, cp);
215ebfedea0SLionel Sambuc
216ebfedea0SLionel Sambuc for (i = 0; i < MD2_BLOCK; i++)
217ebfedea0SLionel Sambuc cp[i] = (UCHAR) p2[i];
218ebfedea0SLionel Sambuc md2_block(c, cp);
219ebfedea0SLionel Sambuc
220ebfedea0SLionel Sambuc for (i = 0; i < 16; i++)
221ebfedea0SLionel Sambuc md[i] = (UCHAR) (p1[i] & 0xff);
222ebfedea0SLionel Sambuc memset((char *)&c, 0, sizeof(c));
223ebfedea0SLionel Sambuc return 1;
224ebfedea0SLionel Sambuc }
225