VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/md5.c@ 97138

最後變更 在這個檔案從97138是 95312,由 vboxsync 提交於 3 年 前

libs/{curl,libxml2}: OSE export fixes, bugref:8515

  • 屬性 svn:eol-style 設為 native
檔案大小: 18.6 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 ***************************************************************************/
22
23#include "curl_setup.h"
24
25#ifndef CURL_DISABLE_CRYPTO_AUTH
26
27#include <curl/curl.h>
28
29#include "curl_md5.h"
30#include "curl_hmac.h"
31#include "warnless.h"
32
33#ifdef USE_MBEDTLS
34#include <mbedtls/version.h>
35
36#if(MBEDTLS_VERSION_NUMBER >= 0x02070000) && \
37 (MBEDTLS_VERSION_NUMBER < 0x03000000)
38 #define HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS
39#endif
40#endif /* USE_MBEDTLS */
41
42#if defined(USE_OPENSSL) && !defined(USE_AMISSL)
43 #include <openssl/opensslconf.h>
44 #if !defined(OPENSSL_NO_MD5) && !defined(OPENSSL_NO_DEPRECATED_3_0)
45 #define USE_OPENSSL_MD5
46 #endif
47#endif
48
49#ifdef USE_WOLFSSL
50 #include <wolfssl/options.h>
51 #ifndef NO_MD5
52 #define USE_WOLFSSL_MD5
53 #endif
54#endif
55
56#if defined(USE_GNUTLS)
57
58#include <nettle/md5.h>
59#include "curl_memory.h"
60/* The last #include file should be: */
61#include "memdebug.h"
62
63typedef struct md5_ctx my_md5_ctx;
64
65static CURLcode my_md5_init(my_md5_ctx *ctx)
66{
67 md5_init(ctx);
68 return CURLE_OK;
69}
70
71static void my_md5_update(my_md5_ctx *ctx,
72 const unsigned char *input,
73 unsigned int inputLen)
74{
75 md5_update(ctx, inputLen, input);
76}
77
78static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
79{
80 md5_digest(ctx, 16, digest);
81}
82
83#elif defined(USE_OPENSSL_MD5) || defined(USE_WOLFSSL_MD5)
84
85/* When OpenSSL or wolfSSL is available, we use their MD5 functions. */
86#if defined(USE_OPENSSL_MD5)
87#include <openssl/md5.h>
88#elif defined(USE_WOLFSSL_MD5)
89#include <wolfssl/openssl/md5.h>
90#endif
91
92#include "curl_memory.h"
93/* The last #include file should be: */
94#include "memdebug.h"
95
96typedef MD5_CTX my_md5_ctx;
97
98static CURLcode my_md5_init(my_md5_ctx *ctx)
99{
100 if(!MD5_Init(ctx))
101 return CURLE_OUT_OF_MEMORY;
102
103 return CURLE_OK;
104}
105
106static void my_md5_update(my_md5_ctx *ctx,
107 const unsigned char *input,
108 unsigned int len)
109{
110 (void)MD5_Update(ctx, input, len);
111}
112
113static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
114{
115 (void)MD5_Final(digest, ctx);
116}
117
118#elif defined(USE_MBEDTLS)
119
120#include <mbedtls/md5.h>
121
122#include "curl_memory.h"
123
124/* The last #include file should be: */
125#include "memdebug.h"
126
127typedef mbedtls_md5_context my_md5_ctx;
128
129static CURLcode my_md5_init(my_md5_ctx *ctx)
130{
131#if (MBEDTLS_VERSION_NUMBER >= 0x03000000)
132 if(mbedtls_md5_starts(ctx))
133 return CURLE_OUT_OF_MEMORY;
134#elif defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
135 if(mbedtls_md5_starts_ret(ctx))
136 return CURLE_OUT_OF_MEMORY;
137#else
138 (void)mbedtls_md5_starts(ctx);
139#endif
140 return CURLE_OK;
141}
142
143static void my_md5_update(my_md5_ctx *ctx,
144 const unsigned char *data,
145 unsigned int length)
146{
147#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
148 (void) mbedtls_md5_update(ctx, data, length);
149#else
150 (void) mbedtls_md5_update_ret(ctx, data, length);
151#endif
152}
153
154static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
155{
156#if !defined(HAS_MBEDTLS_RESULT_CODE_BASED_FUNCTIONS)
157 (void) mbedtls_md5_finish(ctx, digest);
158#else
159 (void) mbedtls_md5_finish_ret(ctx, digest);
160#endif
161}
162
163#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \
164 (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040) && \
165 defined(__MAC_OS_X_VERSION_MIN_ALLOWED) && \
166 (__MAC_OS_X_VERSION_MIN_ALLOWED < 101500)) || \
167 (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \
168 (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000))
169
170/* For Apple operating systems: CommonCrypto has the functions we need.
171 These functions are available on Tiger and later, as well as iOS 2.0
172 and later. If you're building for an older cat, well, sorry.
173
174 Declaring the functions as static like this seems to be a bit more
175 reliable than defining COMMON_DIGEST_FOR_OPENSSL on older cats. */
176# include <CommonCrypto/CommonDigest.h>
177# define my_md5_ctx CC_MD5_CTX
178#include "curl_memory.h"
179/* The last #include file should be: */
180#include "memdebug.h"
181
182static CURLcode my_md5_init(my_md5_ctx *ctx)
183{
184 if(!CC_MD5_Init(ctx))
185 return CURLE_OUT_OF_MEMORY;
186
187 return CURLE_OK;
188}
189
190static void my_md5_update(my_md5_ctx *ctx,
191 const unsigned char *input,
192 unsigned int inputLen)
193{
194 CC_MD5_Update(ctx, input, inputLen);
195}
196
197static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
198{
199 CC_MD5_Final(digest, ctx);
200}
201
202#elif defined(USE_WIN32_CRYPTO)
203
204#include <wincrypt.h>
205#include "curl_memory.h"
206/* The last #include file should be: */
207#include "memdebug.h"
208
209struct md5_ctx {
210 HCRYPTPROV hCryptProv;
211 HCRYPTHASH hHash;
212};
213typedef struct md5_ctx my_md5_ctx;
214
215static CURLcode my_md5_init(my_md5_ctx *ctx)
216{
217 if(!CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, PROV_RSA_FULL,
218 CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
219 return CURLE_OUT_OF_MEMORY;
220
221 if(!CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash)) {
222 CryptReleaseContext(ctx->hCryptProv, 0);
223 return CURLE_OUT_OF_MEMORY;
224 }
225
226 return CURLE_OK;
227}
228
229static void my_md5_update(my_md5_ctx *ctx,
230 const unsigned char *input,
231 unsigned int inputLen)
232{
233 CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0);
234}
235
236static void my_md5_final(unsigned char *digest, my_md5_ctx *ctx)
237{
238 unsigned long length = 0;
239 CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0);
240 if(length == 16)
241 CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0);
242 if(ctx->hHash)
243 CryptDestroyHash(ctx->hHash);
244 if(ctx->hCryptProv)
245 CryptReleaseContext(ctx->hCryptProv, 0);
246}
247
248#else
249
250/* When no other crypto library is available we use this code segment */
251
252/*
253 * This is an OpenSSL-compatible implementation of the RSA Data Security, Inc.
254 * MD5 Message-Digest Algorithm (RFC 1321).
255 *
256 * Homepage:
257 https://openwall.info/wiki/people/solar/software/public-domain-source-code/md5
258 *
259 * Author:
260 * Alexander Peslyak, better known as Solar Designer <solar at openwall.com>
261 *
262 * This software was written by Alexander Peslyak in 2001. No copyright is
263 * claimed, and the software is hereby placed in the public domain.
264 * In case this attempt to disclaim copyright and place the software in the
265 * public domain is deemed null and void, then the software is
266 * Copyright (c) 2001 Alexander Peslyak and it is hereby released to the
267 * general public under the following terms:
268 *
269 * Redistribution and use in source and binary forms, with or without
270 * modification, are permitted.
271 *
272 * There's ABSOLUTELY NO WARRANTY, express or implied.
273 *
274 * (This is a heavily cut-down "BSD license".)
275 *
276 * This differs from Colin Plumb's older public domain implementation in that
277 * no exactly 32-bit integer data type is required (any 32-bit or wider
278 * unsigned integer data type will do), there's no compile-time endianness
279 * configuration, and the function prototypes match OpenSSL's. No code from
280 * Colin Plumb's implementation has been reused; this comment merely compares
281 * the properties of the two independent implementations.
282 *
283 * The primary goals of this implementation are portability and ease of use.
284 * It is meant to be fast, but not as fast as possible. Some known
285 * optimizations are not included to reduce source code size and avoid
286 * compile-time configuration.
287 */
288
289#include <string.h>
290
291/* The last #include files should be: */
292#include "curl_memory.h"
293#include "memdebug.h"
294
295/* Any 32-bit or wider unsigned integer data type will do */
296typedef unsigned int MD5_u32plus;
297
298struct md5_ctx {
299 MD5_u32plus lo, hi;
300 MD5_u32plus a, b, c, d;
301 unsigned char buffer[64];
302 MD5_u32plus block[16];
303};
304typedef struct md5_ctx my_md5_ctx;
305
306static CURLcode my_md5_init(my_md5_ctx *ctx);
307static void my_md5_update(my_md5_ctx *ctx, const void *data,
308 unsigned long size);
309static void my_md5_final(unsigned char *result, my_md5_ctx *ctx);
310
311/*
312 * The basic MD5 functions.
313 *
314 * F and G are optimized compared to their RFC 1321 definitions for
315 * architectures that lack an AND-NOT instruction, just like in Colin Plumb's
316 * implementation.
317 */
318#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
319#define G(x, y, z) ((y) ^ ((z) & ((x) ^ (y))))
320#define H(x, y, z) (((x) ^ (y)) ^ (z))
321#define H2(x, y, z) ((x) ^ ((y) ^ (z)))
322#define I(x, y, z) ((y) ^ ((x) | ~(z)))
323
324/*
325 * The MD5 transformation for all four rounds.
326 */
327#define STEP(f, a, b, c, d, x, t, s) \
328 (a) += f((b), (c), (d)) + (x) + (t); \
329 (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \
330 (a) += (b);
331
332/*
333 * SET reads 4 input bytes in little-endian byte order and stores them
334 * in a properly aligned word in host byte order.
335 *
336 * The check for little-endian architectures that tolerate unaligned
337 * memory accesses is just an optimization. Nothing will break if it
338 * doesn't work.
339 */
340#if defined(__i386__) || defined(__x86_64__) || defined(__vax__)
341#define SET(n) \
342 (*(MD5_u32plus *)(void *)&ptr[(n) * 4])
343#define GET(n) \
344 SET(n)
345#else
346#define SET(n) \
347 (ctx->block[(n)] = \
348 (MD5_u32plus)ptr[(n) * 4] | \
349 ((MD5_u32plus)ptr[(n) * 4 + 1] << 8) | \
350 ((MD5_u32plus)ptr[(n) * 4 + 2] << 16) | \
351 ((MD5_u32plus)ptr[(n) * 4 + 3] << 24))
352#define GET(n) \
353 (ctx->block[(n)])
354#endif
355
356/*
357 * This processes one or more 64-byte data blocks, but does NOT update
358 * the bit counters. There are no alignment requirements.
359 */
360static const void *body(my_md5_ctx *ctx, const void *data, unsigned long size)
361{
362 const unsigned char *ptr;
363 MD5_u32plus a, b, c, d;
364
365 ptr = (const unsigned char *)data;
366
367 a = ctx->a;
368 b = ctx->b;
369 c = ctx->c;
370 d = ctx->d;
371
372 do {
373 MD5_u32plus saved_a, saved_b, saved_c, saved_d;
374
375 saved_a = a;
376 saved_b = b;
377 saved_c = c;
378 saved_d = d;
379
380/* Round 1 */
381 STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7)
382 STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12)
383 STEP(F, c, d, a, b, SET(2), 0x242070db, 17)
384 STEP(F, b, c, d, a, SET(3), 0xc1bdceee, 22)
385 STEP(F, a, b, c, d, SET(4), 0xf57c0faf, 7)
386 STEP(F, d, a, b, c, SET(5), 0x4787c62a, 12)
387 STEP(F, c, d, a, b, SET(6), 0xa8304613, 17)
388 STEP(F, b, c, d, a, SET(7), 0xfd469501, 22)
389 STEP(F, a, b, c, d, SET(8), 0x698098d8, 7)
390 STEP(F, d, a, b, c, SET(9), 0x8b44f7af, 12)
391 STEP(F, c, d, a, b, SET(10), 0xffff5bb1, 17)
392 STEP(F, b, c, d, a, SET(11), 0x895cd7be, 22)
393 STEP(F, a, b, c, d, SET(12), 0x6b901122, 7)
394 STEP(F, d, a, b, c, SET(13), 0xfd987193, 12)
395 STEP(F, c, d, a, b, SET(14), 0xa679438e, 17)
396 STEP(F, b, c, d, a, SET(15), 0x49b40821, 22)
397
398/* Round 2 */
399 STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5)
400 STEP(G, d, a, b, c, GET(6), 0xc040b340, 9)
401 STEP(G, c, d, a, b, GET(11), 0x265e5a51, 14)
402 STEP(G, b, c, d, a, GET(0), 0xe9b6c7aa, 20)
403 STEP(G, a, b, c, d, GET(5), 0xd62f105d, 5)
404 STEP(G, d, a, b, c, GET(10), 0x02441453, 9)
405 STEP(G, c, d, a, b, GET(15), 0xd8a1e681, 14)
406 STEP(G, b, c, d, a, GET(4), 0xe7d3fbc8, 20)
407 STEP(G, a, b, c, d, GET(9), 0x21e1cde6, 5)
408 STEP(G, d, a, b, c, GET(14), 0xc33707d6, 9)
409 STEP(G, c, d, a, b, GET(3), 0xf4d50d87, 14)
410 STEP(G, b, c, d, a, GET(8), 0x455a14ed, 20)
411 STEP(G, a, b, c, d, GET(13), 0xa9e3e905, 5)
412 STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9)
413 STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14)
414 STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20)
415
416/* Round 3 */
417 STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4)
418 STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11)
419 STEP(H, c, d, a, b, GET(11), 0x6d9d6122, 16)
420 STEP(H2, b, c, d, a, GET(14), 0xfde5380c, 23)
421 STEP(H, a, b, c, d, GET(1), 0xa4beea44, 4)
422 STEP(H2, d, a, b, c, GET(4), 0x4bdecfa9, 11)
423 STEP(H, c, d, a, b, GET(7), 0xf6bb4b60, 16)
424 STEP(H2, b, c, d, a, GET(10), 0xbebfbc70, 23)
425 STEP(H, a, b, c, d, GET(13), 0x289b7ec6, 4)
426 STEP(H2, d, a, b, c, GET(0), 0xeaa127fa, 11)
427 STEP(H, c, d, a, b, GET(3), 0xd4ef3085, 16)
428 STEP(H2, b, c, d, a, GET(6), 0x04881d05, 23)
429 STEP(H, a, b, c, d, GET(9), 0xd9d4d039, 4)
430 STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11)
431 STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16)
432 STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23)
433
434/* Round 4 */
435 STEP(I, a, b, c, d, GET(0), 0xf4292244, 6)
436 STEP(I, d, a, b, c, GET(7), 0x432aff97, 10)
437 STEP(I, c, d, a, b, GET(14), 0xab9423a7, 15)
438 STEP(I, b, c, d, a, GET(5), 0xfc93a039, 21)
439 STEP(I, a, b, c, d, GET(12), 0x655b59c3, 6)
440 STEP(I, d, a, b, c, GET(3), 0x8f0ccc92, 10)
441 STEP(I, c, d, a, b, GET(10), 0xffeff47d, 15)
442 STEP(I, b, c, d, a, GET(1), 0x85845dd1, 21)
443 STEP(I, a, b, c, d, GET(8), 0x6fa87e4f, 6)
444 STEP(I, d, a, b, c, GET(15), 0xfe2ce6e0, 10)
445 STEP(I, c, d, a, b, GET(6), 0xa3014314, 15)
446 STEP(I, b, c, d, a, GET(13), 0x4e0811a1, 21)
447 STEP(I, a, b, c, d, GET(4), 0xf7537e82, 6)
448 STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10)
449 STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15)
450 STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21)
451
452 a += saved_a;
453 b += saved_b;
454 c += saved_c;
455 d += saved_d;
456
457 ptr += 64;
458 } while(size -= 64);
459
460 ctx->a = a;
461 ctx->b = b;
462 ctx->c = c;
463 ctx->d = d;
464
465 return ptr;
466}
467
468static CURLcode my_md5_init(my_md5_ctx *ctx)
469{
470 ctx->a = 0x67452301;
471 ctx->b = 0xefcdab89;
472 ctx->c = 0x98badcfe;
473 ctx->d = 0x10325476;
474
475 ctx->lo = 0;
476 ctx->hi = 0;
477
478 return CURLE_OK;
479}
480
481static void my_md5_update(my_md5_ctx *ctx, const void *data,
482 unsigned long size)
483{
484 MD5_u32plus saved_lo;
485 unsigned long used;
486
487 saved_lo = ctx->lo;
488 ctx->lo = (saved_lo + size) & 0x1fffffff;
489 if(ctx->lo < saved_lo)
490 ctx->hi++;
491 ctx->hi += (MD5_u32plus)size >> 29;
492
493 used = saved_lo & 0x3f;
494
495 if(used) {
496 unsigned long available = 64 - used;
497
498 if(size < available) {
499 memcpy(&ctx->buffer[used], data, size);
500 return;
501 }
502
503 memcpy(&ctx->buffer[used], data, available);
504 data = (const unsigned char *)data + available;
505 size -= available;
506 body(ctx, ctx->buffer, 64);
507 }
508
509 if(size >= 64) {
510 data = body(ctx, data, size & ~(unsigned long)0x3f);
511 size &= 0x3f;
512 }
513
514 memcpy(ctx->buffer, data, size);
515}
516
517static void my_md5_final(unsigned char *result, my_md5_ctx *ctx)
518{
519 unsigned long used, available;
520
521 used = ctx->lo & 0x3f;
522
523 ctx->buffer[used++] = 0x80;
524
525 available = 64 - used;
526
527 if(available < 8) {
528 memset(&ctx->buffer[used], 0, available);
529 body(ctx, ctx->buffer, 64);
530 used = 0;
531 available = 64;
532 }
533
534 memset(&ctx->buffer[used], 0, available - 8);
535
536 ctx->lo <<= 3;
537 ctx->buffer[56] = curlx_ultouc((ctx->lo)&0xff);
538 ctx->buffer[57] = curlx_ultouc((ctx->lo >> 8)&0xff);
539 ctx->buffer[58] = curlx_ultouc((ctx->lo >> 16)&0xff);
540 ctx->buffer[59] = curlx_ultouc(ctx->lo >> 24);
541 ctx->buffer[60] = curlx_ultouc((ctx->hi)&0xff);
542 ctx->buffer[61] = curlx_ultouc((ctx->hi >> 8)&0xff);
543 ctx->buffer[62] = curlx_ultouc((ctx->hi >> 16)&0xff);
544 ctx->buffer[63] = curlx_ultouc(ctx->hi >> 24);
545
546 body(ctx, ctx->buffer, 64);
547
548 result[0] = curlx_ultouc((ctx->a)&0xff);
549 result[1] = curlx_ultouc((ctx->a >> 8)&0xff);
550 result[2] = curlx_ultouc((ctx->a >> 16)&0xff);
551 result[3] = curlx_ultouc(ctx->a >> 24);
552 result[4] = curlx_ultouc((ctx->b)&0xff);
553 result[5] = curlx_ultouc((ctx->b >> 8)&0xff);
554 result[6] = curlx_ultouc((ctx->b >> 16)&0xff);
555 result[7] = curlx_ultouc(ctx->b >> 24);
556 result[8] = curlx_ultouc((ctx->c)&0xff);
557 result[9] = curlx_ultouc((ctx->c >> 8)&0xff);
558 result[10] = curlx_ultouc((ctx->c >> 16)&0xff);
559 result[11] = curlx_ultouc(ctx->c >> 24);
560 result[12] = curlx_ultouc((ctx->d)&0xff);
561 result[13] = curlx_ultouc((ctx->d >> 8)&0xff);
562 result[14] = curlx_ultouc((ctx->d >> 16)&0xff);
563 result[15] = curlx_ultouc(ctx->d >> 24);
564
565 memset(ctx, 0, sizeof(*ctx));
566}
567
568#endif /* CRYPTO LIBS */
569
570const struct HMAC_params Curl_HMAC_MD5[] = {
571 {
572 /* Hash initialization function. */
573 CURLX_FUNCTION_CAST(HMAC_hinit_func, my_md5_init),
574 /* Hash update function. */
575 CURLX_FUNCTION_CAST(HMAC_hupdate_func, my_md5_update),
576 /* Hash computation end function. */
577 CURLX_FUNCTION_CAST(HMAC_hfinal_func, my_md5_final),
578 /* Size of hash context structure. */
579 sizeof(my_md5_ctx),
580 /* Maximum key length. */
581 64,
582 /* Result size. */
583 16
584 }
585};
586
587const struct MD5_params Curl_DIGEST_MD5[] = {
588 {
589 /* Digest initialization function */
590 CURLX_FUNCTION_CAST(Curl_MD5_init_func, my_md5_init),
591 /* Digest update function */
592 CURLX_FUNCTION_CAST(Curl_MD5_update_func, my_md5_update),
593 /* Digest computation end function */
594 CURLX_FUNCTION_CAST(Curl_MD5_final_func, my_md5_final),
595 /* Size of digest context struct */
596 sizeof(my_md5_ctx),
597 /* Result size */
598 16
599 }
600};
601
602/*
603 * @unittest: 1601
604 * Returns CURLE_OK on success.
605 */
606CURLcode Curl_md5it(unsigned char *outbuffer, const unsigned char *input,
607 const size_t len)
608{
609 CURLcode result;
610 my_md5_ctx ctx;
611
612 result = my_md5_init(&ctx);
613 if(!result) {
614 my_md5_update(&ctx, input, curlx_uztoui(len));
615 my_md5_final(outbuffer, &ctx);
616 }
617 return result;
618}
619
620struct MD5_context *Curl_MD5_init(const struct MD5_params *md5params)
621{
622 struct MD5_context *ctxt;
623
624 /* Create MD5 context */
625 ctxt = malloc(sizeof(*ctxt));
626
627 if(!ctxt)
628 return ctxt;
629
630 ctxt->md5_hashctx = malloc(md5params->md5_ctxtsize);
631
632 if(!ctxt->md5_hashctx) {
633 free(ctxt);
634 return NULL;
635 }
636
637 ctxt->md5_hash = md5params;
638
639 if((*md5params->md5_init_func)(ctxt->md5_hashctx)) {
640 free(ctxt->md5_hashctx);
641 free(ctxt);
642 return NULL;
643 }
644
645 return ctxt;
646}
647
648CURLcode Curl_MD5_update(struct MD5_context *context,
649 const unsigned char *data,
650 unsigned int len)
651{
652 (*context->md5_hash->md5_update_func)(context->md5_hashctx, data, len);
653
654 return CURLE_OK;
655}
656
657CURLcode Curl_MD5_final(struct MD5_context *context, unsigned char *result)
658{
659 (*context->md5_hash->md5_final_func)(result, context->md5_hashctx);
660
661 free(context->md5_hashctx);
662 free(context);
663
664 return CURLE_OK;
665}
666
667#endif /* CURL_DISABLE_CRYPTO_AUTH */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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