1*b756f940Schristos /* $NetBSD: md2.c,v 1.9 2024/01/26 21:34:01 christos Exp $ */
2b387889fSelad
3b387889fSelad /*
4b387889fSelad * Copyright (c) 2001 The NetBSD Foundation, Inc.
5b387889fSelad * All rights reserved.
6b387889fSelad *
7b387889fSelad * This code is derived from software contributed to The NetBSD Foundation
8b387889fSelad * by Andrew Brown.
9b387889fSelad *
10b387889fSelad * Redistribution and use in source and binary forms, with or without
11b387889fSelad * modification, are permitted provided that the following conditions
12b387889fSelad * are met:
13b387889fSelad * 1. Redistributions of source code must retain the above copyright
14b387889fSelad * notice, this list of conditions and the following disclaimer.
15b387889fSelad * 2. Redistributions in binary form must reproduce the above copyright
16b387889fSelad * notice, this list of conditions and the following disclaimer in the
17b387889fSelad * documentation and/or other materials provided with the distribution.
18b387889fSelad *
19b387889fSelad * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20b387889fSelad * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21b387889fSelad * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22b387889fSelad * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23b387889fSelad * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24b387889fSelad * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25b387889fSelad * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26b387889fSelad * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27b387889fSelad * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28b387889fSelad * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29b387889fSelad * POSSIBILITY OF SUCH DAMAGE.
30b387889fSelad */
31b387889fSelad
32b387889fSelad #include <sys/cdefs.h>
33b387889fSelad #if defined(LIBC_SCCS) && !defined(lint)
34*b756f940Schristos __RCSID("$NetBSD: md2.c,v 1.9 2024/01/26 21:34:01 christos Exp $");
35b387889fSelad #endif /* LIBC_SCCS and not lint */
36b387889fSelad
37b387889fSelad #include "namespace.h"
38b387889fSelad
39b387889fSelad #include <sys/types.h>
40b387889fSelad
41b387889fSelad #include <assert.h>
42b387889fSelad #include <md2.h>
43b387889fSelad #include <string.h>
44b387889fSelad
45b387889fSelad #if HAVE_NBTOOL_CONFIG_H
46b387889fSelad #include "nbtool_config.h"
47b387889fSelad #endif
48b387889fSelad
49b387889fSelad #if !HAVE_MD2_H
50b387889fSelad
51b387889fSelad /* cut-n-pasted from rfc1319 */
52b387889fSelad static unsigned char S[256] = {
53b387889fSelad 41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
54b387889fSelad 19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
55b387889fSelad 76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
56b387889fSelad 138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
57b387889fSelad 245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
58b387889fSelad 148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
59b387889fSelad 39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
60b387889fSelad 181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
61b387889fSelad 150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
62b387889fSelad 112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
63b387889fSelad 96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
64b387889fSelad 85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
65b387889fSelad 234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
66b387889fSelad 129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
67b387889fSelad 8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
68b387889fSelad 203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
69b387889fSelad 166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
70b387889fSelad 31, 26, 219, 153, 141, 51, 159, 17, 131, 20
71b387889fSelad };
72b387889fSelad
73b387889fSelad /* cut-n-pasted from rfc1319 */
7403256c6eSchristos static const unsigned char *pad[] = {
7503256c6eSchristos (const unsigned char *)"",
7603256c6eSchristos (const unsigned char *)"\001",
7703256c6eSchristos (const unsigned char *)"\002\002",
7803256c6eSchristos (const unsigned char *)"\003\003\003",
7903256c6eSchristos (const unsigned char *)"\004\004\004\004",
8003256c6eSchristos (const unsigned char *)"\005\005\005\005\005",
8103256c6eSchristos (const unsigned char *)"\006\006\006\006\006\006",
8203256c6eSchristos (const unsigned char *)"\007\007\007\007\007\007\007",
8303256c6eSchristos (const unsigned char *)"\010\010\010\010\010\010\010\010",
8403256c6eSchristos (const unsigned char *)"\011\011\011\011\011\011\011\011\011",
8503256c6eSchristos (const unsigned char *)"\012\012\012\012\012\012\012\012\012\012",
8603256c6eSchristos (const unsigned char *)"\013\013\013\013\013\013\013\013\013\013\013",
8703256c6eSchristos (const unsigned char *)
8803256c6eSchristos "\014\014\014\014\014\014\014\014\014\014\014\014",
8903256c6eSchristos (const unsigned char *)
90b387889fSelad "\015\015\015\015\015\015\015\015\015\015\015\015\015",
9103256c6eSchristos (const unsigned char *)
92b387889fSelad "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
9303256c6eSchristos (const unsigned char *)
94b387889fSelad "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
9503256c6eSchristos (const unsigned char *)
96b387889fSelad "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
97b387889fSelad };
98b387889fSelad
99b387889fSelad #ifdef __weak_alias
__weak_alias(MD2Init,_MD2Init)100b387889fSelad __weak_alias(MD2Init,_MD2Init)
101b387889fSelad __weak_alias(MD2Update,_MD2Update)
102b387889fSelad __weak_alias(MD2Final,_MD2Final)
103da7e4f73Selad __weak_alias(MD2Transform,_MD2Transform)
104b387889fSelad #endif
105b387889fSelad
106*b756f940Schristos /*
107*b756f940Schristos * XXX This should not be visible, but due to an accident, it is
108*b756f940Schristos * XXX so it must remain so.
109*b756f940Schristos */
110*b756f940Schristos /*static*/ void
111*b756f940Schristos MD2Transform(MD2_CTX *context)
112*b756f940Schristos {
113*b756f940Schristos uint32_t l, j, k, t;
114*b756f940Schristos
115*b756f940Schristos /* set block "3" and update "checksum" */
116*b756f940Schristos for (l = context->C[15], j = 0; j < 16; j++) {
117*b756f940Schristos context->X[32 + j] = context->X[j] ^ context->X[16 + j];
118*b756f940Schristos l = context->C[j] ^= S[context->X[16 + j] ^ l];
119*b756f940Schristos }
120*b756f940Schristos
121*b756f940Schristos /* mangle input block */
122*b756f940Schristos for (t = j = 0; j < 18; t = (t + j) % 256, j++)
123*b756f940Schristos for (k = 0; k < 48; k++)
124*b756f940Schristos t = context->X[k] = (context->X[k] ^ S[t]);
125*b756f940Schristos
126*b756f940Schristos /* reset input pointer */
127*b756f940Schristos context->i = 16;
128*b756f940Schristos }
129*b756f940Schristos
130b387889fSelad void
MD2Init(MD2_CTX * context)1319e66e6d7Sabs MD2Init(MD2_CTX *context)
132b387889fSelad {
133b387889fSelad _DIAGASSERT(context != 0);
134b387889fSelad
135b387889fSelad context->i = 16;
136b387889fSelad memset(&context->C[0], 0, sizeof(context->C));
137b387889fSelad memset(&context->X[0], 0, sizeof(context->X));
138b387889fSelad }
139b387889fSelad
140b387889fSelad void
MD2Update(MD2_CTX * context,const unsigned char * input,unsigned int inputLen)1419e66e6d7Sabs MD2Update(MD2_CTX *context, const unsigned char *input, unsigned int inputLen)
142b387889fSelad {
143b387889fSelad unsigned int idx, piece;
144b387889fSelad
145b387889fSelad _DIAGASSERT(context != 0);
146b387889fSelad _DIAGASSERT(input != 0);
147b387889fSelad
148b387889fSelad for (idx = 0; idx < inputLen; idx += piece) {
149b387889fSelad piece = 32 - context->i;
150b387889fSelad if ((inputLen - idx) < piece)
151b387889fSelad piece = inputLen - idx;
152b387889fSelad memcpy(&context->X[context->i], &input[idx], (size_t)piece);
153b387889fSelad if ((context->i += piece) == 32)
154b387889fSelad MD2Transform(context); /* resets i */
155b387889fSelad }
156b387889fSelad }
157b387889fSelad
158b387889fSelad void
MD2Final(unsigned char digest[16],MD2_CTX * context)1599e66e6d7Sabs MD2Final(unsigned char digest[16], MD2_CTX *context)
160b387889fSelad {
161b387889fSelad unsigned int padlen;
162b387889fSelad
163b387889fSelad _DIAGASSERT(digest != 0);
164b387889fSelad _DIAGASSERT(context != 0);
165b387889fSelad
166b387889fSelad /* padlen should be 1..16 */
167b387889fSelad padlen = 32 - context->i;
168b387889fSelad
169b387889fSelad /* add padding */
170b387889fSelad MD2Update(context, pad[padlen], padlen);
171b387889fSelad
172b387889fSelad /* add checksum */
173b387889fSelad MD2Update(context, &context->C[0], (unsigned int) sizeof(context->C));
174b387889fSelad
175b387889fSelad /* copy out final digest */
176b387889fSelad memcpy(digest, &context->X[0], (size_t)16);
177b387889fSelad
178b387889fSelad /* reset the context */
179b387889fSelad MD2Init(context);
180b387889fSelad }
181b387889fSelad
182b387889fSelad
183b387889fSelad #endif /* !HAVE_MD2_H */
184