~ubuntu-branches/ubuntu/gutsy/poco/gutsy

« back to all changes in this revision

Viewing changes to Foundation/src/MD2Engine.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Krzysztof Burghardt
  • Date: 2007-04-27 18:33:48 UTC
  • Revision ID: james.westby@ubuntu.com-20070427183348-xgnpct0qd6a2ip34
Tags: upstream-1.2.9
ImportĀ upstreamĀ versionĀ 1.2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// MD2Engine.cpp
 
3
//
 
4
// $Id: //poco/1.2/Foundation/src/MD2Engine.cpp#1 $
 
5
//
 
6
// Library: Foundation
 
7
// Package: Crypt
 
8
// Module:  MD2Engine
 
9
//
 
10
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
 
11
// and Contributors.
 
12
//
 
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:
 
19
// 
 
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.
 
26
// 
 
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.
 
34
//
 
35
//
 
36
// MD2 (RFC 1319) algorithm:
 
37
// Copyright (C) 1990-2, RSA Data Security, Inc. Created 1990. All
 
38
// rights reserved.
 
39
//
 
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
 
44
// or this function.
 
45
//
 
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.
 
50
//
 
51
// These notices must be retained in any copies of any part of this
 
52
// documentation and/or software.
 
53
//
 
54
 
 
55
 
 
56
#include "Poco/MD2Engine.h"
 
57
#include <string.h>
 
58
 
 
59
 
 
60
namespace Poco {
 
61
 
 
62
 
 
63
MD2Engine::MD2Engine()
 
64
{
 
65
        _digest.reserve(16);
 
66
        reset();
 
67
}
 
68
 
 
69
 
 
70
MD2Engine::~MD2Engine()
 
71
{
 
72
        reset();
 
73
}
 
74
 
 
75
        
 
76
void MD2Engine::updateImpl(const void* input_, unsigned inputLen)
 
77
{
 
78
        const unsigned char* input = (const unsigned char*) input_;
 
79
        unsigned int i, index, partLen;
 
80
 
 
81
        /* Update number of bytes mod 16 */
 
82
        index = _context.count;
 
83
        _context.count = (index + inputLen) & 0xf;
 
84
 
 
85
        partLen = 16 - index;
 
86
 
 
87
        /* Transform as many times as possible. */
 
88
        if (inputLen >= partLen) 
 
89
        {
 
90
                memcpy(&_context.buffer[index], input, partLen);
 
91
                transform(_context.state, _context.checksum, _context.buffer);
 
92
 
 
93
                for (i = partLen; i + 15 < inputLen; i += 16)
 
94
                        transform(_context.state, _context.checksum, &input[i]);
 
95
 
 
96
                index = 0;
 
97
        }
 
98
        else i = 0;
 
99
 
 
100
        /* Buffer remaining input */
 
101
        memcpy(&_context.buffer[index], &input[i], inputLen-i);
 
102
}
 
103
 
 
104
 
 
105
unsigned MD2Engine::digestLength() const
 
106
{
 
107
        return DIGEST_SIZE;
 
108
}
 
109
 
 
110
 
 
111
void MD2Engine::reset()
 
112
{
 
113
        memset(&_context, 0, sizeof(_context));
 
114
}
 
115
 
 
116
 
 
117
const DigestEngine::Digest& MD2Engine::digest()
 
118
{
 
119
        static const unsigned char* PADDING[] = 
 
120
        {
 
121
                (unsigned char*) "",
 
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"
 
138
        };
 
139
        unsigned int index, padLen;
 
140
 
 
141
        /* Pad out to multiple of 16. */
 
142
        index = _context.count;
 
143
        padLen = 16 - index;
 
144
        update((const char*) PADDING[padLen], padLen);
 
145
 
 
146
        /* Extend with checksum */
 
147
        update((const char*) _context.checksum, 16);
 
148
 
 
149
        /* Store state in digest */
 
150
        _digest.clear();
 
151
        _digest.insert(_digest.begin(), _context.state, _context.state + 16);
 
152
 
 
153
        /* Zeroize sensitive information. */
 
154
        memset(&_context, 0, sizeof(_context));
 
155
        reset();
 
156
        return _digest;
 
157
}
 
158
 
 
159
 
 
160
void MD2Engine::transform(unsigned char state[16], unsigned char checksum[16], const unsigned char block[16])
 
161
{
 
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] = 
 
165
        {
 
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
 
184
        };
 
185
        unsigned int i, j, t;
 
186
        unsigned char x[48];
 
187
 
 
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];
 
193
 
 
194
        /* Encrypt block (18 rounds). */
 
195
        t = 0;
 
196
        for (i = 0; i < 18; i++) 
 
197
        {
 
198
                for (j = 0; j < 48; j++)
 
199
                        t = x[j] ^= PI_SUBST[t];
 
200
                t = (t + i) & 0xff;
 
201
        }
 
202
 
 
203
        /* Save new state */
 
204
        memcpy(state, x, 16);
 
205
 
 
206
        /* Update checksum. */
 
207
        t = checksum[15];
 
208
        for (i = 0; i < 16; i++)
 
209
        t = checksum[i] ^= PI_SUBST[block[i] ^ t];
 
210
 
 
211
        /* Zeroize sensitive information. */
 
212
        memset(x, 0, sizeof(x));
 
213
}
 
214
 
 
215
 
 
216
} // namespace Poco