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