VirtualBox

source: vbox/trunk/src/libs/curl-7.87.0/lib/md4.c@ 98704

最後變更 在這個檔案從98704是 98326,由 vboxsync 提交於 2 年 前

curl-7.87.0: Applied and adjusted our curl changes to 7.83.1. bugref:10356

  • 屬性 svn:eol-style 設為 native
檔案大小: 14.1 KB
 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 1998 - 2022, Daniel Stenberg, <[email protected]>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24
25#include "curl_setup.h"
26
27#if !defined(CURL_DISABLE_CRYPTO_AUTH)
28
29#include <string.h>
30
31#include "curl_md4.h"
32#include "warnless.h"
33
34#ifdef USE_OPENSSL
35#include <openssl/opensslconf.h>
36#if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) && \
37 !defined(USE_AMISSL)
38/* OpenSSL 3.0.0 marks the MD4 functions as deprecated */
39#define OPENSSL_NO_MD4
40#endif
41#endif /* USE_OPENSSL */
42
43#ifdef USE_WOLFSSL
44#include <wolfssl/options.h>
45#ifdef NO_MD4
46#define WOLFSSL_NO_MD4
47#endif
48#endif
49
50#ifdef USE_MBEDTLS
51#include <mbedtls/version.h>
52#if MBEDTLS_VERSION_NUMBER >= 0x03000000
53#include <mbedtls/mbedtls_config.h>
54#else
55#include <mbedtls/config.h>
56#endif
57#if(MBEDTLS_VERSION_NUMBER >= 0x02070000)
58 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
59#endif
60#endif /* USE_MBEDTLS */
61
62#if defined(USE_GNUTLS)
63#include <nettle/md4.h>
64/* When OpenSSL or wolfSSL is available, we use their MD4 functions. */
65#elif defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
66#include <wolfssl/openssl/md4.h>
67#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
68#include <openssl/md4.h>
69#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
70 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
71 defined(__MAC_OS_X_VERSION_MIN_ALLOWED) && \
72 (__MAC_OS_X_VERSION_MIN_ALLOWED < 101500)) || \
73 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
74 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
75#define AN_APPLE_OS
76#include <CommonCrypto/CommonDigest.h>
77#elif defined(USE_WIN32_CRYPTO)
78#include <wincrypt.h>
79#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
80#include <mbedtls/md4.h>
81#endif
82
83/* The last 3 #include files should be in this order */
84#include "curl_printf.h"
85#include "curl_memory.h"
86#include "memdebug.h"
87
88
89#if defined(USE_WOLFSSL) && !defined(WOLFSSL_NO_MD4)
90
91#elif defined(USE_OPENSSL) && !defined(OPENSSL_NO_MD4)
92
93#elif defined(USE_GNUTLS)
94
95typedef struct md4_ctx MD4_CTX;
96
97static void MD4_Init(MD4_CTX *ctx)
98{
99 md4_init(ctx);
100}
101
102static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
103{
104 md4_update(ctx, size, data);
105}
106
107static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
108{
109 md4_digest(ctx, MD4_DIGEST_SIZE, result);
110}
111
112#elif defined(AN_APPLE_OS)
113typedef CC_MD4_CTX MD4_CTX;
114
115static void MD4_Init(MD4_CTX *ctx)
116{
117 (void)CC_MD4_Init(ctx);
118}
119
120static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
121{
122 (void)CC_MD4_Update(ctx, data, (CC_LONG)size);
123}
124
125static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
126{
127 (void)CC_MD4_Final(result, ctx);
128}
129
130#elif defined(USE_WIN32_CRYPTO)
131
132struct md4_ctx {
133 HCRYPTPROV hCryptProv;
134 HCRYPTHASH hHash;
135};
136typedef struct md4_ctx MD4_CTX;
137
138static void MD4_Init(MD4_CTX *ctx)
139{
140 ctx->hCryptProv = 0;
141 ctx->hHash = 0;
142
143 if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
144 CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) {
145 CryptCreateHash(ctx->hCryptProv, CALG_MD4, 0, 0, &ctx->hHash);
146 }
147}
148
149static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
150{
151 CryptHashData(ctx->hHash, (BYTE *)data, (unsigned int) size, 0);
152}
153
154static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
155{
156 unsigned long length = 0;
157
158 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
159 if(length == MD4_DIGEST_LENGTH)
160 CryptGetHashParam(ctx->hHash, HP_HASHVAL, result, &length, 0);
161
162 if(ctx->hHash)
163 CryptDestroyHash(ctx->hHash);
164
165 if(ctx->hCryptProv)
166 CryptReleaseContext(ctx->hCryptProv, 0);
167}
168
169#elif(defined(USE_MBEDTLS) && defined(MBEDTLS_MD4_C))
170
171struct md4_ctx {
172 void *data;
173 unsigned long size;
174};
175typedef struct md4_ctx MD4_CTX;
176
177static void MD4_Init(MD4_CTX *ctx)
178{
179 ctx->data = NULL;
180 ctx->size = 0;
181}
182
183static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
184{
185 if(!ctx->data) {
186 ctx->data = malloc(size);
187 if(ctx->data) {
188 memcpy(ctx->data, data, size);
189 ctx->size = size;
190 }
191 }
192}
193
194static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
195{
196 if(ctx->data) {
197#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
198 mbedtls_md4(ctx->data, ctx->size, result);
199#else
200 (void) mbedtls_md4_ret(ctx->data, ctx->size, result);
201#endif
202
203 Curl_safefree(ctx->data);
204 ctx->size = 0;
205 }
206}
207
208#else
209/* When no other crypto library is available, or the crypto library doesn't
210 * support MD4, we use this code segment this implementation of it
211 *
212 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
213 * MD4 Message-Digest Algorithm (RFC 1320).
214 *
215 * Homepage:
216 https://openwall.info/wiki/people/solar/software/public-domain-source-code/md4
217 *
218 * Author:
219 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
220 *
221 * This software was written by Alexander Peslyak in 2001. No copyright is
222 * claimed, and the software is hereby placed in the public domain. In case
223 * this attempt to disclaim copyright and place the software in the public
224 * domain is deemed null and void, then the software is Copyright (c) 2001
225 * Alexander Peslyak and it is hereby released to the general public under the
226 * following terms:
227 *
228 * Redistribution and use in source and binary forms, with or without
229 * modification, are permitted.
230 *
231 * There's ABSOLUTELY NO WARRANTY, express or implied.
232 *
233 * (This is a heavily cut-down "BSD license".)
234 *
235 * This differs from Colin Plumb's older public domain implementation in that
236 * no exactly 32-bit integer data type is required (any 32-bit or wider
237 * unsigned integer data type will do), there's no compile-time endianness
238 * configuration, and the function prototypes match OpenSSL's. No code from
239 * Colin Plumb's implementation has been reused; this comment merely compares
240 * the properties of the two independent implementations.
241 *
242 * The primary goals of this implementation are portability and ease of use.
243 * It is meant to be fast, but not as fast as possible. Some known
244 * optimizations are not included to reduce source code size and avoid
245 * compile-time configuration.
246 */
247
248/* Any 32-bit or wider unsigned integer data type will do */
249typedef unsigned int MD4_u32plus;
250
251struct md4_ctx {
252 MD4_u32plus lo, hi;
253 MD4_u32plus a, b, c, d;
254 unsigned char buffer[64];
255 MD4_u32plus block[16];
256};
257typedef struct md4_ctx MD4_CTX;
258
259static void MD4_Init(MD4_CTX *ctx);
260static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size);
261static void MD4_Final(unsigned char *result, MD4_CTX *ctx);
262
263/*
264 * The basic MD4 functions.
265 *
266 * F and G are optimized compared to their RFC 1320 definitions, with the
267 * optimization for F borrowed from Colin Plumb's MD5 implementation.
268 */
269#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
270#define G(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
271#define H(x, y, z) ((x) ^ (y) ^ (z))
272
273/*
274 * The MD4 transformation for all three rounds.
275 */
276#define STEP(f, a, b, c, d, x, s) \
277 (a) += f((b), (c), (d)) + (x); \
278 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s))));
279
280/*
281 * SET reads 4 input bytes in little-endian byte order and stores them
282 * in a properly aligned word in host byte order.
283 *
284 * The check for little-endian architectures that tolerate unaligned
285 * memory accesses is just an optimization. Nothing will break if it
286 * doesn't work.
287 */
288#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
289#define SET(n) \
290 (*(MD4_u32plus *)(void *)&ptr[(n) * 4])
291#define GET(n) \
292 SET(n)
293#else
294#define SET(n) \
295 (ctx->block[(n)] = \
296 (MD4_u32plus)ptr[(n) * 4] | \
297 ((MD4_u32plus)ptr[(n) * 4 + 1] << 8) | \
298 ((MD4_u32plus)ptr[(n) * 4 + 2] << 16) | \
299 ((MD4_u32plus)ptr[(n) * 4 + 3] << 24))
300#define GET(n) \
301 (ctx->block[(n)])
302#endif
303
304/*
305 * This processes one or more 64-byte data blocks, but does NOT update
306 * the bit counters. There are no alignment requirements.
307 */
308static const void *body(MD4_CTX *ctx, const void *data, unsigned long size)
309{
310 const unsigned char *ptr;
311 MD4_u32plus a, b, c, d;
312
313 ptr = (const unsigned char *)data;
314
315 a = ctx->a;
316 b = ctx->b;
317 c = ctx->c;
318 d = ctx->d;
319
320 do {
321 MD4_u32plus saved_a, saved_b, saved_c, saved_d;
322
323 saved_a = a;
324 saved_b = b;
325 saved_c = c;
326 saved_d = d;
327
328/* Round 1 */
329 STEP(F, a, b, c, d, SET(0), 3)
330 STEP(F, d, a, b, c, SET(1), 7)
331 STEP(F, c, d, a, b, SET(2), 11)
332 STEP(F, b, c, d, a, SET(3), 19)
333 STEP(F, a, b, c, d, SET(4), 3)
334 STEP(F, d, a, b, c, SET(5), 7)
335 STEP(F, c, d, a, b, SET(6), 11)
336 STEP(F, b, c, d, a, SET(7), 19)
337 STEP(F, a, b, c, d, SET(8), 3)
338 STEP(F, d, a, b, c, SET(9), 7)
339 STEP(F, c, d, a, b, SET(10), 11)
340 STEP(F, b, c, d, a, SET(11), 19)
341 STEP(F, a, b, c, d, SET(12), 3)
342 STEP(F, d, a, b, c, SET(13), 7)
343 STEP(F, c, d, a, b, SET(14), 11)
344 STEP(F, b, c, d, a, SET(15), 19)
345
346/* Round 2 */
347 STEP(G, a, b, c, d, GET(0) + 0x5a827999, 3)
348 STEP(G, d, a, b, c, GET(4) + 0x5a827999, 5)
349 STEP(G, c, d, a, b, GET(8) + 0x5a827999, 9)
350 STEP(G, b, c, d, a, GET(12) + 0x5a827999, 13)
351 STEP(G, a, b, c, d, GET(1) + 0x5a827999, 3)
352 STEP(G, d, a, b, c, GET(5) + 0x5a827999, 5)
353 STEP(G, c, d, a, b, GET(9) + 0x5a827999, 9)
354 STEP(G, b, c, d, a, GET(13) + 0x5a827999, 13)
355 STEP(G, a, b, c, d, GET(2) + 0x5a827999, 3)
356 STEP(G, d, a, b, c, GET(6) + 0x5a827999, 5)
357 STEP(G, c, d, a, b, GET(10) + 0x5a827999, 9)
358 STEP(G, b, c, d, a, GET(14) + 0x5a827999, 13)
359 STEP(G, a, b, c, d, GET(3) + 0x5a827999, 3)
360 STEP(G, d, a, b, c, GET(7) + 0x5a827999, 5)
361 STEP(G, c, d, a, b, GET(11) + 0x5a827999, 9)
362 STEP(G, b, c, d, a, GET(15) + 0x5a827999, 13)
363
364/* Round 3 */
365 STEP(H, a, b, c, d, GET(0) + 0x6ed9eba1, 3)
366 STEP(H, d, a, b, c, GET(8) + 0x6ed9eba1, 9)
367 STEP(H, c, d, a, b, GET(4) + 0x6ed9eba1, 11)
368 STEP(H, b, c, d, a, GET(12) + 0x6ed9eba1, 15)
369 STEP(H, a, b, c, d, GET(2) + 0x6ed9eba1, 3)
370 STEP(H, d, a, b, c, GET(10) + 0x6ed9eba1, 9)
371 STEP(H, c, d, a, b, GET(6) + 0x6ed9eba1, 11)
372 STEP(H, b, c, d, a, GET(14) + 0x6ed9eba1, 15)
373 STEP(H, a, b, c, d, GET(1) + 0x6ed9eba1, 3)
374 STEP(H, d, a, b, c, GET(9) + 0x6ed9eba1, 9)
375 STEP(H, c, d, a, b, GET(5) + 0x6ed9eba1, 11)
376 STEP(H, b, c, d, a, GET(13) + 0x6ed9eba1, 15)
377 STEP(H, a, b, c, d, GET(3) + 0x6ed9eba1, 3)
378 STEP(H, d, a, b, c, GET(11) + 0x6ed9eba1, 9)
379 STEP(H, c, d, a, b, GET(7) + 0x6ed9eba1, 11)
380 STEP(H, b, c, d, a, GET(15) + 0x6ed9eba1, 15)
381
382 a += saved_a;
383 b += saved_b;
384 c += saved_c;
385 d += saved_d;
386
387 ptr += 64;
388 } while(size -= 64);
389
390 ctx->a = a;
391 ctx->b = b;
392 ctx->c = c;
393 ctx->d = d;
394
395 return ptr;
396}
397
398static void MD4_Init(MD4_CTX *ctx)
399{
400 ctx->a = 0x67452301;
401 ctx->b = 0xefcdab89;
402 ctx->c = 0x98badcfe;
403 ctx->d = 0x10325476;
404
405 ctx->lo = 0;
406 ctx->hi = 0;
407}
408
409static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
410{
411 MD4_u32plus saved_lo;
412 unsigned long used;
413
414 saved_lo = ctx->lo;
415 ctx->lo = (saved_lo + size) & 0x1fffffff;
416 if(ctx->lo < saved_lo)
417 ctx->hi++;
418 ctx->hi += (MD4_u32plus)size >> 29;
419
420 used = saved_lo & 0x3f;
421
422 if(used) {
423 unsigned long available = 64 - used;
424
425 if(size < available) {
426 memcpy(&ctx->buffer[used], data, size);
427 return;
428 }
429
430 memcpy(&ctx->buffer[used], data, available);
431 data = (const unsigned char *)data + available;
432 size -= available;
433 body(ctx, ctx->buffer, 64);
434 }
435
436 if(size >= 64) {
437 data = body(ctx, data, size & ~(unsigned long)0x3f);
438 size &= 0x3f;
439 }
440
441 memcpy(ctx->buffer, data, size);
442}
443
444static void MD4_Final(unsigned char *result, MD4_CTX *ctx)
445{
446 unsigned long used, available;
447
448 used = ctx->lo & 0x3f;
449
450 ctx->buffer[used++] = 0x80;
451
452 available = 64 - used;
453
454 if(available < 8) {
455 memset(&ctx->buffer[used], 0, available);
456 body(ctx, ctx->buffer, 64);
457 used = 0;
458 available = 64;
459 }
460
461 memset(&ctx->buffer[used], 0, available - 8);
462
463 ctx->lo <<= 3;
464 ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
465 ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
466 ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
467 ctx->buffer[59] = curlx_ultouc((ctx->lo >> 24)&0xff);
468 ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
469 ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
470 ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
471 ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
472
473 body(ctx, ctx->buffer, 64);
474
475 result[0] = curlx_ultouc((ctx->a)&0xff);
476 result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
477 result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
478 result[3] = curlx_ultouc(ctx->a >> 24);
479 result[4] = curlx_ultouc((ctx->b)&0xff);
480 result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
481 result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
482 result[7] = curlx_ultouc(ctx->b >> 24);
483 result[8] = curlx_ultouc((ctx->c)&0xff);
484 result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
485 result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
486 result[11] = curlx_ultouc(ctx->c >> 24);
487 result[12] = curlx_ultouc((ctx->d)&0xff);
488 result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
489 result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
490 result[15] = curlx_ultouc(ctx->d >> 24);
491
492 memset(ctx, 0, sizeof(*ctx));
493}
494
495#endif /* CRYPTO LIBS */
496
497void Curl_md4it(unsigned char *output, const unsigned char *input,
498 const size_t len)
499{
500 MD4_CTX ctx;
501
502 MD4_Init(&ctx);
503 MD4_Update(&ctx, input, curlx_uztoui(len));
504 MD4_Final(output, &ctx);
505}
506
507#endif /* CURL_DISABLE_CRYPTO_AUTH */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette