4
// $Id: //poco/1.2/Foundation/src/MD2Engine.cpp#1 $
10
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
13
// Permission is hereby granted, free of charge, to any person or organization
14
// obtaining a copy of the software and accompanying documentation covered by
15
// this license (the "Software") to use, reproduce, display, distribute,
16
// execute, and transmit the Software, and to prepare derivative works of the
17
// Software, and to permit third-parties to whom the Software is furnished to
18
// do so, all subject to the following:
20
// The copyright notices in the Software and this entire statement, including
21
// the above license grant, this restriction and the following disclaimer,
22
// must be included in all copies of the Software, in whole or in part, and
23
// all derivative works of the Software, unless such copies or derivative
24
// works are solely in the form of machine-executable object code generated by
25
// a source language processor.
27
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
30
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
31
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
32
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
33
// DEALINGS IN THE SOFTWARE.
36
// MD2 (RFC 1319) algorithm:
37
// Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
40
// License to copy and use this software is granted for
41
// non-commercial Internet Privacy-Enhanced Mail provided that it is
42
// identified as the "RSA Data Security, Inc. MD2 Message Digest
43
// Algorithm" in all material mentioning or referencing this software
46
// RSA Data Security, Inc. makes no representations concerning either
47
// the merchantability of this software or the suitability of this
48
// software for any particular purpose. It is provided "as is"
49
// without express or implied warranty of any kind.
51
// These notices must be retained in any copies of any part of this
52
// documentation and/or software.
56
#include "Poco/MD2Engine.h"
63
MD2Engine::MD2Engine()
70
MD2Engine::~MD2Engine()
76
void MD2Engine::updateImpl(const void* input_, unsigned inputLen)
78
const unsigned char* input = (const unsigned char*) input_;
79
unsigned int i, index, partLen;
81
/* Update number of bytes mod 16 */
82
index = _context.count;
83
_context.count = (index + inputLen) & 0xf;
87
/* Transform as many times as possible. */
88
if (inputLen >= partLen)
90
memcpy(&_context.buffer[index], input, partLen);
91
transform(_context.state, _context.checksum, _context.buffer);
93
for (i = partLen; i + 15 < inputLen; i += 16)
94
transform(_context.state, _context.checksum, &input[i]);
100
/* Buffer remaining input */
101
memcpy(&_context.buffer[index], &input[i], inputLen-i);
105
unsigned MD2Engine::digestLength() const
111
void MD2Engine::reset()
113
memset(&_context, 0, sizeof(_context));
117
const DigestEngine::Digest& MD2Engine::digest()
119
static const unsigned char* PADDING[] =
122
(unsigned char*) "\001",
123
(unsigned char*) "\002\002",
124
(unsigned char*) "\003\003\003",
125
(unsigned char*) "\004\004\004\004",
126
(unsigned char*) "\005\005\005\005\005",
127
(unsigned char*) "\006\006\006\006\006\006",
128
(unsigned char*) "\007\007\007\007\007\007\007",
129
(unsigned char*) "\010\010\010\010\010\010\010\010",
130
(unsigned char*) "\011\011\011\011\011\011\011\011\011",
131
(unsigned char*) "\012\012\012\012\012\012\012\012\012\012",
132
(unsigned char*) "\013\013\013\013\013\013\013\013\013\013\013",
133
(unsigned char*) "\014\014\014\014\014\014\014\014\014\014\014\014",
134
(unsigned char*) "\015\015\015\015\015\015\015\015\015\015\015\015\015",
135
(unsigned char *) "\016\016\016\016\016\016\016\016\016\016\016\016\016\016",
136
(unsigned char *) "\017\017\017\017\017\017\017\017\017\017\017\017\017\017\017",
137
(unsigned char *) "\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020\020"
139
unsigned int index, padLen;
141
/* Pad out to multiple of 16. */
142
index = _context.count;
144
update((const char*) PADDING[padLen], padLen);
146
/* Extend with checksum */
147
update((const char*) _context.checksum, 16);
149
/* Store state in digest */
151
_digest.insert(_digest.begin(), _context.state, _context.state + 16);
153
/* Zeroize sensitive information. */
154
memset(&_context, 0, sizeof(_context));
160
void MD2Engine::transform(unsigned char state[16], unsigned char checksum[16], const unsigned char block[16])
162
// Permutation of 0..255 constructed from the digits of pi. It gives a
163
// "random" nonlinear byte substitution operation.
164
static const unsigned char PI_SUBST[256] =
166
41, 46, 67, 201, 162, 216, 124, 1, 61, 54, 84, 161, 236, 240, 6,
167
19, 98, 167, 5, 243, 192, 199, 115, 140, 152, 147, 43, 217, 188,
168
76, 130, 202, 30, 155, 87, 60, 253, 212, 224, 22, 103, 66, 111, 24,
169
138, 23, 229, 18, 190, 78, 196, 214, 218, 158, 222, 73, 160, 251,
170
245, 142, 187, 47, 238, 122, 169, 104, 121, 145, 21, 178, 7, 63,
171
148, 194, 16, 137, 11, 34, 95, 33, 128, 127, 93, 154, 90, 144, 50,
172
39, 53, 62, 204, 231, 191, 247, 151, 3, 255, 25, 48, 179, 72, 165,
173
181, 209, 215, 94, 146, 42, 172, 86, 170, 198, 79, 184, 56, 210,
174
150, 164, 125, 182, 118, 252, 107, 226, 156, 116, 4, 241, 69, 157,
175
112, 89, 100, 113, 135, 32, 134, 91, 207, 101, 230, 45, 168, 2, 27,
176
96, 37, 173, 174, 176, 185, 246, 28, 70, 97, 105, 52, 64, 126, 15,
177
85, 71, 163, 35, 221, 81, 175, 58, 195, 92, 249, 206, 186, 197,
178
234, 38, 44, 83, 13, 110, 133, 40, 132, 9, 211, 223, 205, 244, 65,
179
129, 77, 82, 106, 220, 55, 200, 108, 193, 171, 250, 36, 225, 123,
180
8, 12, 189, 177, 74, 120, 136, 149, 139, 227, 99, 232, 109, 233,
181
203, 213, 254, 59, 0, 29, 57, 242, 239, 183, 14, 102, 88, 208, 228,
182
166, 119, 114, 248, 235, 117, 75, 10, 49, 68, 80, 180, 143, 237,
183
31, 26, 219, 153, 141, 51, 159, 17, 131, 20
185
unsigned int i, j, t;
188
/* Form encryption block from state, block, state ^ block. */
189
memcpy(x, state, 16);
190
memcpy(x+16, block, 16);
191
for (i = 0; i < 16; i++)
192
x[i+32] = state[i] ^ block[i];
194
/* Encrypt block (18 rounds). */
196
for (i = 0; i < 18; i++)
198
for (j = 0; j < 48; j++)
199
t = x[j] ^= PI_SUBST[t];
204
memcpy(state, x, 16);
206
/* Update checksum. */
208
for (i = 0; i < 16; i++)
209
t = checksum[i] ^= PI_SUBST[block[i] ^ t];
211
/* Zeroize sensitive information. */
212
memset(x, 0, sizeof(x));