xref: /reactos/dll/3rdparty/mbedtls/md2.c (revision bbabe248)
1 /*
2  *  RFC 1115/1319 compliant MD2 implementation
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  *
7  *  This file is provided under the Apache License 2.0, or the
8  *  GNU General Public License v2.0 or later.
9  *
10  *  **********
11  *  Apache License 2.0:
12  *
13  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
14  *  not use this file except in compliance with the License.
15  *  You may obtain a copy of the License at
16  *
17  *  http://www.apache.org/licenses/LICENSE-2.0
18  *
19  *  Unless required by applicable law or agreed to in writing, software
20  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the License for the specific language governing permissions and
23  *  limitations under the License.
24  *
25  *  **********
26  *
27  *  **********
28  *  GNU General Public License v2.0 or later:
29  *
30  *  This program is free software; you can redistribute it and/or modify
31  *  it under the terms of the GNU General Public License as published by
32  *  the Free Software Foundation; either version 2 of the License, or
33  *  (at your option) any later version.
34  *
35  *  This program is distributed in the hope that it will be useful,
36  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
37  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  *  GNU General Public License for more details.
39  *
40  *  You should have received a copy of the GNU General Public License along
41  *  with this program; if not, write to the Free Software Foundation, Inc.,
42  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43  *
44  *  **********
45  */
46 /*
47  *  The MD2 algorithm was designed by Ron Rivest in 1989.
48  *
49  *  http://www.ietf.org/rfc/rfc1115.txt
50  *  http://www.ietf.org/rfc/rfc1319.txt
51  */
52 
53 #if !defined(MBEDTLS_CONFIG_FILE)
54 #include "mbedtls/config.h"
55 #else
56 #include MBEDTLS_CONFIG_FILE
57 #endif
58 
59 #if defined(MBEDTLS_MD2_C)
60 
61 #include "mbedtls/md2.h"
62 #include "mbedtls/platform_util.h"
63 
64 #include <string.h>
65 
66 #if defined(MBEDTLS_SELF_TEST)
67 #if defined(MBEDTLS_PLATFORM_C)
68 #include "mbedtls/platform.h"
69 #else
70 #include <stdio.h>
71 #define mbedtls_printf printf
72 #endif /* MBEDTLS_PLATFORM_C */
73 #endif /* MBEDTLS_SELF_TEST */
74 
75 #if !defined(MBEDTLS_MD2_ALT)
76 
77 static const unsigned char PI_SUBST[256] =
78 {
79     0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, 0x3D, 0x36,
80     0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, 0x62, 0xA7, 0x05, 0xF3,
81     0xC0, 0xC7, 0x73, 0x8C, 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C,
82     0x82, 0xCA, 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16,
83     0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, 0xBE, 0x4E,
84     0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, 0xA0, 0xFB, 0xF5, 0x8E,
85     0xBB, 0x2F, 0xEE, 0x7A, 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2,
86     0x07, 0x3F, 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21,
87     0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, 0x35, 0x3E,
88     0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, 0xFF, 0x19, 0x30, 0xB3,
89     0x48, 0xA5, 0xB5, 0xD1, 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56,
90     0xAA, 0xC6, 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6,
91     0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, 0x45, 0x9D,
92     0x70, 0x59, 0x64, 0x71, 0x87, 0x20, 0x86, 0x5B, 0xCF, 0x65,
93     0xE6, 0x2D, 0xA8, 0x02, 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0,
94     0xB9, 0xF6, 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F,
95     0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, 0xC3, 0x5C,
96     0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, 0x2C, 0x53, 0x0D, 0x6E,
97     0x85, 0x28, 0x84, 0x09, 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81,
98     0x4D, 0x52, 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA,
99     0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, 0x78, 0x88,
100     0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, 0xE9, 0xCB, 0xD5, 0xFE,
101     0x3B, 0x00, 0x1D, 0x39, 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58,
102     0xD0, 0xE4, 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A,
103     0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, 0xDB, 0x99,
104     0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14
105 };
106 
107 void mbedtls_md2_init( mbedtls_md2_context *ctx )
108 {
109     memset( ctx, 0, sizeof( mbedtls_md2_context ) );
110 }
111 
112 void mbedtls_md2_free( mbedtls_md2_context *ctx )
113 {
114     if( ctx == NULL )
115         return;
116 
117     mbedtls_platform_zeroize( ctx, sizeof( mbedtls_md2_context ) );
118 }
119 
120 void mbedtls_md2_clone( mbedtls_md2_context *dst,
121                         const mbedtls_md2_context *src )
122 {
123     *dst = *src;
124 }
125 
126 /*
127  * MD2 context setup
128  */
129 int mbedtls_md2_starts_ret( mbedtls_md2_context *ctx )
130 {
131     memset( ctx->cksum, 0, 16 );
132     memset( ctx->state, 0, 46 );
133     memset( ctx->buffer, 0, 16 );
134     ctx->left = 0;
135 
136     return( 0 );
137 }
138 
139 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
140 void mbedtls_md2_starts( mbedtls_md2_context *ctx )
141 {
142     mbedtls_md2_starts_ret( ctx );
143 }
144 #endif
145 
146 #if !defined(MBEDTLS_MD2_PROCESS_ALT)
147 int mbedtls_internal_md2_process( mbedtls_md2_context *ctx )
148 {
149     int i, j;
150     unsigned char t = 0;
151 
152     for( i = 0; i < 16; i++ )
153     {
154         ctx->state[i + 16] = ctx->buffer[i];
155         ctx->state[i + 32] =
156             (unsigned char)( ctx->buffer[i] ^ ctx->state[i]);
157     }
158 
159     for( i = 0; i < 18; i++ )
160     {
161         for( j = 0; j < 48; j++ )
162         {
163             ctx->state[j] = (unsigned char)
164                ( ctx->state[j] ^ PI_SUBST[t] );
165             t  = ctx->state[j];
166         }
167 
168         t = (unsigned char)( t + i );
169     }
170 
171     t = ctx->cksum[15];
172 
173     for( i = 0; i < 16; i++ )
174     {
175         ctx->cksum[i] = (unsigned char)
176            ( ctx->cksum[i] ^ PI_SUBST[ctx->buffer[i] ^ t] );
177         t  = ctx->cksum[i];
178     }
179 
180     /* Zeroise variables to clear sensitive data from memory. */
181     mbedtls_platform_zeroize( &t, sizeof( t ) );
182 
183     return( 0 );
184 }
185 
186 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
187 void mbedtls_md2_process( mbedtls_md2_context *ctx )
188 {
189     mbedtls_internal_md2_process( ctx );
190 }
191 #endif
192 #endif /* !MBEDTLS_MD2_PROCESS_ALT */
193 
194 /*
195  * MD2 process buffer
196  */
197 int mbedtls_md2_update_ret( mbedtls_md2_context *ctx,
198                             const unsigned char *input,
199                             size_t ilen )
200 {
201     int ret;
202     size_t fill;
203 
204     while( ilen > 0 )
205     {
206         if( ilen > 16 - ctx->left )
207             fill = 16 - ctx->left;
208         else
209             fill = ilen;
210 
211         memcpy( ctx->buffer + ctx->left, input, fill );
212 
213         ctx->left += fill;
214         input += fill;
215         ilen  -= fill;
216 
217         if( ctx->left == 16 )
218         {
219             ctx->left = 0;
220             if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
221                 return( ret );
222         }
223     }
224 
225     return( 0 );
226 }
227 
228 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
229 void mbedtls_md2_update( mbedtls_md2_context *ctx,
230                          const unsigned char *input,
231                          size_t ilen )
232 {
233     mbedtls_md2_update_ret( ctx, input, ilen );
234 }
235 #endif
236 
237 /*
238  * MD2 final digest
239  */
240 int mbedtls_md2_finish_ret( mbedtls_md2_context *ctx,
241                             unsigned char output[16] )
242 {
243     int ret;
244     size_t i;
245     unsigned char x;
246 
247     x = (unsigned char)( 16 - ctx->left );
248 
249     for( i = ctx->left; i < 16; i++ )
250         ctx->buffer[i] = x;
251 
252     if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
253         return( ret );
254 
255     memcpy( ctx->buffer, ctx->cksum, 16 );
256     if( ( ret = mbedtls_internal_md2_process( ctx ) ) != 0 )
257         return( ret );
258 
259     memcpy( output, ctx->state, 16 );
260 
261     return( 0 );
262 }
263 
264 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
265 void mbedtls_md2_finish( mbedtls_md2_context *ctx,
266                          unsigned char output[16] )
267 {
268     mbedtls_md2_finish_ret( ctx, output );
269 }
270 #endif
271 
272 #endif /* !MBEDTLS_MD2_ALT */
273 
274 /*
275  * output = MD2( input buffer )
276  */
277 int mbedtls_md2_ret( const unsigned char *input,
278                      size_t ilen,
279                      unsigned char output[16] )
280 {
281     int ret;
282     mbedtls_md2_context ctx;
283 
284     mbedtls_md2_init( &ctx );
285 
286     if( ( ret = mbedtls_md2_starts_ret( &ctx ) ) != 0 )
287         goto exit;
288 
289     if( ( ret = mbedtls_md2_update_ret( &ctx, input, ilen ) ) != 0 )
290         goto exit;
291 
292     if( ( ret = mbedtls_md2_finish_ret( &ctx, output ) ) != 0 )
293         goto exit;
294 
295 exit:
296     mbedtls_md2_free( &ctx );
297 
298     return( ret );
299 }
300 
301 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
302 void mbedtls_md2( const unsigned char *input,
303                   size_t ilen,
304                   unsigned char output[16] )
305 {
306     mbedtls_md2_ret( input, ilen, output );
307 }
308 #endif
309 
310 #if defined(MBEDTLS_SELF_TEST)
311 
312 /*
313  * RFC 1319 test vectors
314  */
315 static const unsigned char md2_test_str[7][81] =
316 {
317     { "" },
318     { "a" },
319     { "abc" },
320     { "message digest" },
321     { "abcdefghijklmnopqrstuvwxyz" },
322     { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" },
323     { "12345678901234567890123456789012345678901234567890123456789012"
324       "345678901234567890" }
325 };
326 
327 static const size_t md2_test_strlen[7] =
328 {
329     0, 1, 3, 14, 26, 62, 80
330 };
331 
332 static const unsigned char md2_test_sum[7][16] =
333 {
334     { 0x83, 0x50, 0xE5, 0xA3, 0xE2, 0x4C, 0x15, 0x3D,
335       0xF2, 0x27, 0x5C, 0x9F, 0x80, 0x69, 0x27, 0x73 },
336     { 0x32, 0xEC, 0x01, 0xEC, 0x4A, 0x6D, 0xAC, 0x72,
337       0xC0, 0xAB, 0x96, 0xFB, 0x34, 0xC0, 0xB5, 0xD1 },
338     { 0xDA, 0x85, 0x3B, 0x0D, 0x3F, 0x88, 0xD9, 0x9B,
339       0x30, 0x28, 0x3A, 0x69, 0xE6, 0xDE, 0xD6, 0xBB },
340     { 0xAB, 0x4F, 0x49, 0x6B, 0xFB, 0x2A, 0x53, 0x0B,
341       0x21, 0x9F, 0xF3, 0x30, 0x31, 0xFE, 0x06, 0xB0 },
342     { 0x4E, 0x8D, 0xDF, 0xF3, 0x65, 0x02, 0x92, 0xAB,
343       0x5A, 0x41, 0x08, 0xC3, 0xAA, 0x47, 0x94, 0x0B },
344     { 0xDA, 0x33, 0xDE, 0xF2, 0xA4, 0x2D, 0xF1, 0x39,
345       0x75, 0x35, 0x28, 0x46, 0xC3, 0x03, 0x38, 0xCD },
346     { 0xD5, 0x97, 0x6F, 0x79, 0xD8, 0x3D, 0x3A, 0x0D,
347       0xC9, 0x80, 0x6C, 0x3C, 0x66, 0xF3, 0xEF, 0xD8 }
348 };
349 
350 /*
351  * Checkup routine
352  */
353 int mbedtls_md2_self_test( int verbose )
354 {
355     int i, ret = 0;
356     unsigned char md2sum[16];
357 
358     for( i = 0; i < 7; i++ )
359     {
360         if( verbose != 0 )
361             mbedtls_printf( "  MD2 test #%d: ", i + 1 );
362 
363         ret = mbedtls_md2_ret( md2_test_str[i], md2_test_strlen[i], md2sum );
364         if( ret != 0 )
365             goto fail;
366 
367         if( memcmp( md2sum, md2_test_sum[i], 16 ) != 0 )
368         {
369             ret = 1;
370             goto fail;
371         }
372 
373         if( verbose != 0 )
374             mbedtls_printf( "passed\n" );
375     }
376 
377     if( verbose != 0 )
378         mbedtls_printf( "\n" );
379 
380     return( 0 );
381 
382 fail:
383     if( verbose != 0 )
384         mbedtls_printf( "failed\n" );
385 
386     return( ret );
387 }
388 
389 #endif /* MBEDTLS_SELF_TEST */
390 
391 #endif /* MBEDTLS_MD2_C */
392