Coverage Report

Created: 2025-11-16 07:15

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wolfssl-sp-math-all/wolfcrypt/src/md5.c
Line
Count
Source
1
/* md5.c
2
 *
3
 * Copyright (C) 2006-2025 wolfSSL Inc.
4
 *
5
 * This file is part of wolfSSL.
6
 *
7
 * wolfSSL is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * wolfSSL is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20
 */
21
22
#include <wolfssl/wolfcrypt/libwolfssl_sources.h>
23
24
#if !defined(NO_MD5)
25
26
#if defined(WOLFSSL_TI_HASH)
27
/* #include <wolfcrypt/src/port/ti/ti-hash.c> included by wc_port.c */
28
29
#else
30
31
#include <wolfssl/wolfcrypt/md5.h>
32
#include <wolfssl/wolfcrypt/hash.h>
33
34
#ifdef NO_INLINE
35
#include <wolfssl/wolfcrypt/misc.h>
36
#else
37
#define WOLFSSL_MISC_INCLUDED
38
#include <wolfcrypt/src/misc.c>
39
#endif
40
41
42
/* Hardware Acceleration */
43
#if defined(STM32_HASH) && !defined(STM32_NOMD5)
44
45
/* Supports CubeMX HAL or Standard Peripheral Library */
46
#define HAVE_MD5_CUST_API
47
48
int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId)
49
{
50
    if (md5 == NULL) {
51
        return BAD_FUNC_ARG;
52
    }
53
54
    (void)devId;
55
    (void)heap;
56
57
    wc_Stm32_Hash_Init(&md5->stmCtx);
58
59
    return 0;
60
}
61
62
int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len)
63
{
64
    int ret;
65
66
    if (md5 == NULL || (data == NULL && len > 0)) {
67
        return BAD_FUNC_ARG;
68
    }
69
70
    ret = wolfSSL_CryptHwMutexLock();
71
    if (ret == 0) {
72
        ret = wc_Stm32_Hash_Update(&md5->stmCtx, HASH_AlgoSelection_MD5,
73
                                   data, len, WC_MD5_BLOCK_SIZE);
74
        wolfSSL_CryptHwMutexUnLock();
75
    }
76
    return ret;
77
}
78
79
int wc_Md5Final(wc_Md5* md5, byte* hash)
80
{
81
    int ret;
82
83
    if (md5 == NULL || hash == NULL) {
84
        return BAD_FUNC_ARG;
85
    }
86
87
    ret = wolfSSL_CryptHwMutexLock();
88
    if (ret == 0) {
89
        ret = wc_Stm32_Hash_Final(&md5->stmCtx, HASH_AlgoSelection_MD5,
90
                                  hash, WC_MD5_DIGEST_SIZE);
91
        wolfSSL_CryptHwMutexUnLock();
92
    }
93
94
    (void)wc_InitMd5(md5);  /* reset state */
95
96
    return ret;
97
}
98
99
#elif defined(FREESCALE_MMCAU_SHA)
100
101
#ifdef FREESCALE_MMCAU_CLASSIC_SHA
102
    #include "cau_api.h"
103
#else
104
    #include "fsl_mmcau.h"
105
#endif
106
107
#define XTRANSFORM(S,B)       Transform((S), (B))
108
#define XTRANSFORM_LEN(S,B,L) Transform_Len((S), (B), (L))
109
110
#ifndef WC_HASH_DATA_ALIGNMENT
111
    /* these hardware API's require 4 byte (word32) alignment */
112
    #define WC_HASH_DATA_ALIGNMENT 4
113
#endif
114
115
static int Transform(wc_Md5* md5, const byte* data)
116
{
117
    int ret = wolfSSL_CryptHwMutexLock();
118
    if (ret == 0) {
119
#ifdef FREESCALE_MMCAU_CLASSIC_SHA
120
        cau_md5_hash_n((byte*)data, 1, (unsigned char*)md5->digest);
121
#else
122
        MMCAU_MD5_HashN((byte*)data, 1, (uint32_t*)md5->digest);
123
#endif
124
        wolfSSL_CryptHwMutexUnLock();
125
    }
126
    return ret;
127
}
128
129
static int Transform_Len(wc_Md5* md5, const byte* data, word32 len)
130
{
131
    int ret = wolfSSL_CryptHwMutexLock();
132
    if (ret == 0) {
133
    #if defined(WC_HASH_DATA_ALIGNMENT) && WC_HASH_DATA_ALIGNMENT > 0
134
        if ((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) {
135
            /* data pointer is NOT aligned,
136
             * so copy and perform one block at a time */
137
            byte* local = (byte*)md5->buffer;
138
            while (len >= WC_MD5_BLOCK_SIZE) {
139
                XMEMCPY(local, data, WC_MD5_BLOCK_SIZE);
140
            #ifdef FREESCALE_MMCAU_CLASSIC_SHA
141
                cau_md5_hash_n(local, 1, (unsigned char*)md5->digest);
142
            #else
143
                MMCAU_MD5_HashN(local, 1, (uint32_t*)md5->digest);
144
            #endif
145
                data += WC_MD5_BLOCK_SIZE;
146
                len  -= WC_MD5_BLOCK_SIZE;
147
            }
148
        }
149
        else
150
    #endif
151
        {
152
#ifdef FREESCALE_MMCAU_CLASSIC_SHA
153
        cau_md5_hash_n((byte*)data, len / WC_MD5_BLOCK_SIZE,
154
            (unsigned char*)md5->digest);
155
#else
156
        MMCAU_MD5_HashN((byte*)data, len / WC_MD5_BLOCK_SIZE,
157
            (uint32_t*)md5->digest);
158
#endif
159
        }
160
        wolfSSL_CryptHwMutexUnLock();
161
    }
162
    return ret;
163
}
164
165
#elif defined(WOLFSSL_PIC32MZ_HASH)
166
#include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
167
#define HAVE_MD5_CUST_API
168
169
#elif defined(WOLFSSL_IMX6_CAAM) && !defined(NO_IMX6_CAAM_HASH) && \
170
    !defined(WOLFSSL_QNX_CAAM)
171
/* functions implemented in wolfcrypt/src/port/caam/caam_sha.c */
172
#define HAVE_MD5_CUST_API
173
#else
174
#define NEED_SOFT_MD5
175
#endif /* End Hardware Acceleration */
176
177
#ifdef NEED_SOFT_MD5
178
179
786k
#define XTRANSFORM(S,B)  Transform((S),(B))
180
181
25.1M
#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
182
12.5M
#define F2(x, y, z) F1(z, x, y)
183
12.5M
#define F3(x, y, z) ((x) ^ (y) ^ (z))
184
12.5M
#define F4(x, y, z) ((y) ^ ((x) | ~(z)))
185
186
#define MD5STEP(f, w, x, y, z, data, s) \
187
50.3M
    (w) = (rotlFixed((w) + f(x, y, z) + (data), s) + (x))
188
189
static int Transform(wc_Md5* md5, const byte* data)
190
786k
{
191
786k
    const word32* buffer = (const word32*)data;
192
    /* Copy context->state[] to working vars  */
193
786k
    word32 a = md5->digest[0];
194
786k
    word32 b = md5->digest[1];
195
786k
    word32 c = md5->digest[2];
196
786k
    word32 d = md5->digest[3];
197
198
786k
    MD5STEP(F1, a, b, c, d, buffer[0]  + 0xd76aa478,  7);
199
786k
    MD5STEP(F1, d, a, b, c, buffer[1]  + 0xe8c7b756, 12);
200
786k
    MD5STEP(F1, c, d, a, b, buffer[2]  + 0x242070db, 17);
201
786k
    MD5STEP(F1, b, c, d, a, buffer[3]  + 0xc1bdceee, 22);
202
786k
    MD5STEP(F1, a, b, c, d, buffer[4]  + 0xf57c0faf,  7);
203
786k
    MD5STEP(F1, d, a, b, c, buffer[5]  + 0x4787c62a, 12);
204
786k
    MD5STEP(F1, c, d, a, b, buffer[6]  + 0xa8304613, 17);
205
786k
    MD5STEP(F1, b, c, d, a, buffer[7]  + 0xfd469501, 22);
206
786k
    MD5STEP(F1, a, b, c, d, buffer[8]  + 0x698098d8,  7);
207
786k
    MD5STEP(F1, d, a, b, c, buffer[9]  + 0x8b44f7af, 12);
208
786k
    MD5STEP(F1, c, d, a, b, buffer[10] + 0xffff5bb1, 17);
209
786k
    MD5STEP(F1, b, c, d, a, buffer[11] + 0x895cd7be, 22);
210
786k
    MD5STEP(F1, a, b, c, d, buffer[12] + 0x6b901122,  7);
211
786k
    MD5STEP(F1, d, a, b, c, buffer[13] + 0xfd987193, 12);
212
786k
    MD5STEP(F1, c, d, a, b, buffer[14] + 0xa679438e, 17);
213
786k
    MD5STEP(F1, b, c, d, a, buffer[15] + 0x49b40821, 22);
214
215
786k
    MD5STEP(F2, a, b, c, d, buffer[1]  + 0xf61e2562,  5);
216
786k
    MD5STEP(F2, d, a, b, c, buffer[6]  + 0xc040b340,  9);
217
786k
    MD5STEP(F2, c, d, a, b, buffer[11] + 0x265e5a51, 14);
218
786k
    MD5STEP(F2, b, c, d, a, buffer[0]  + 0xe9b6c7aa, 20);
219
786k
    MD5STEP(F2, a, b, c, d, buffer[5]  + 0xd62f105d,  5);
220
786k
    MD5STEP(F2, d, a, b, c, buffer[10] + 0x02441453,  9);
221
786k
    MD5STEP(F2, c, d, a, b, buffer[15] + 0xd8a1e681, 14);
222
786k
    MD5STEP(F2, b, c, d, a, buffer[4]  + 0xe7d3fbc8, 20);
223
786k
    MD5STEP(F2, a, b, c, d, buffer[9]  + 0x21e1cde6,  5);
224
786k
    MD5STEP(F2, d, a, b, c, buffer[14] + 0xc33707d6,  9);
225
786k
    MD5STEP(F2, c, d, a, b, buffer[3]  + 0xf4d50d87, 14);
226
786k
    MD5STEP(F2, b, c, d, a, buffer[8]  + 0x455a14ed, 20);
227
786k
    MD5STEP(F2, a, b, c, d, buffer[13] + 0xa9e3e905,  5);
228
786k
    MD5STEP(F2, d, a, b, c, buffer[2]  + 0xfcefa3f8,  9);
229
786k
    MD5STEP(F2, c, d, a, b, buffer[7]  + 0x676f02d9, 14);
230
786k
    MD5STEP(F2, b, c, d, a, buffer[12] + 0x8d2a4c8a, 20);
231
232
786k
    MD5STEP(F3, a, b, c, d, buffer[5]  + 0xfffa3942,  4);
233
786k
    MD5STEP(F3, d, a, b, c, buffer[8]  + 0x8771f681, 11);
234
786k
    MD5STEP(F3, c, d, a, b, buffer[11] + 0x6d9d6122, 16);
235
786k
    MD5STEP(F3, b, c, d, a, buffer[14] + 0xfde5380c, 23);
236
786k
    MD5STEP(F3, a, b, c, d, buffer[1]  + 0xa4beea44,  4);
237
786k
    MD5STEP(F3, d, a, b, c, buffer[4]  + 0x4bdecfa9, 11);
238
786k
    MD5STEP(F3, c, d, a, b, buffer[7]  + 0xf6bb4b60, 16);
239
786k
    MD5STEP(F3, b, c, d, a, buffer[10] + 0xbebfbc70, 23);
240
786k
    MD5STEP(F3, a, b, c, d, buffer[13] + 0x289b7ec6,  4);
241
786k
    MD5STEP(F3, d, a, b, c, buffer[0]  + 0xeaa127fa, 11);
242
786k
    MD5STEP(F3, c, d, a, b, buffer[3]  + 0xd4ef3085, 16);
243
786k
    MD5STEP(F3, b, c, d, a, buffer[6]  + 0x04881d05, 23);
244
786k
    MD5STEP(F3, a, b, c, d, buffer[9]  + 0xd9d4d039,  4);
245
786k
    MD5STEP(F3, d, a, b, c, buffer[12] + 0xe6db99e5, 11);
246
786k
    MD5STEP(F3, c, d, a, b, buffer[15] + 0x1fa27cf8, 16);
247
786k
    MD5STEP(F3, b, c, d, a, buffer[2]  + 0xc4ac5665, 23);
248
249
786k
    MD5STEP(F4, a, b, c, d, buffer[0]  + 0xf4292244,  6);
250
786k
    MD5STEP(F4, d, a, b, c, buffer[7]  + 0x432aff97, 10);
251
786k
    MD5STEP(F4, c, d, a, b, buffer[14] + 0xab9423a7, 15);
252
786k
    MD5STEP(F4, b, c, d, a, buffer[5]  + 0xfc93a039, 21);
253
786k
    MD5STEP(F4, a, b, c, d, buffer[12] + 0x655b59c3,  6);
254
786k
    MD5STEP(F4, d, a, b, c, buffer[3]  + 0x8f0ccc92, 10);
255
786k
    MD5STEP(F4, c, d, a, b, buffer[10] + 0xffeff47d, 15);
256
786k
    MD5STEP(F4, b, c, d, a, buffer[1]  + 0x85845dd1, 21);
257
786k
    MD5STEP(F4, a, b, c, d, buffer[8]  + 0x6fa87e4f,  6);
258
786k
    MD5STEP(F4, d, a, b, c, buffer[15] + 0xfe2ce6e0, 10);
259
786k
    MD5STEP(F4, c, d, a, b, buffer[6]  + 0xa3014314, 15);
260
786k
    MD5STEP(F4, b, c, d, a, buffer[13] + 0x4e0811a1, 21);
261
786k
    MD5STEP(F4, a, b, c, d, buffer[4]  + 0xf7537e82,  6);
262
786k
    MD5STEP(F4, d, a, b, c, buffer[11] + 0xbd3af235, 10);
263
786k
    MD5STEP(F4, c, d, a, b, buffer[2]  + 0x2ad7d2bb, 15);
264
786k
    MD5STEP(F4, b, c, d, a, buffer[9]  + 0xeb86d391, 21);
265
266
    /* Add the working vars back into digest state[]  */
267
786k
    md5->digest[0] += a;
268
786k
    md5->digest[1] += b;
269
786k
    md5->digest[2] += c;
270
786k
    md5->digest[3] += d;
271
272
786k
    return 0;
273
786k
}
274
#endif /* NEED_SOFT_MD5 */
275
276
#ifndef HAVE_MD5_CUST_API
277
278
static WC_INLINE void AddLength(wc_Md5* md5, word32 len)
279
209k
{
280
209k
    word32 tmp = md5->loLen;
281
209k
    if ((md5->loLen += len) < tmp) {
282
0
        md5->hiLen++;                       /* carry low to high */
283
0
    }
284
209k
}
285
286
static int _InitMd5(wc_Md5* md5)
287
122k
{
288
122k
    int ret = 0;
289
290
122k
    md5->digest[0] = 0x67452301L;
291
122k
    md5->digest[1] = 0xefcdab89L;
292
122k
    md5->digest[2] = 0x98badcfeL;
293
122k
    md5->digest[3] = 0x10325476L;
294
295
122k
    md5->buffLen = 0;
296
122k
    md5->loLen   = 0;
297
122k
    md5->hiLen   = 0;
298
122k
#ifdef WOLFSSL_HASH_FLAGS
299
122k
    md5->flags = 0;
300
122k
#endif
301
302
122k
    return ret;
303
122k
}
304
305
int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId)
306
99.2k
{
307
99.2k
    int ret = 0;
308
309
99.2k
    if (md5 == NULL)
310
0
        return BAD_FUNC_ARG;
311
312
99.2k
    md5->heap = heap;
313
314
99.2k
    ret = _InitMd5(md5);
315
99.2k
    if (ret != 0)
316
0
        return ret;
317
318
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)
319
    ret = wolfAsync_DevCtxInit(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5,
320
                               md5->heap, devId);
321
#else
322
99.2k
    (void)devId;
323
99.2k
#endif
324
99.2k
    return ret;
325
99.2k
}
326
327
/* do block size increments/updates */
328
int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len)
329
209k
{
330
209k
    int ret = 0;
331
209k
    word32 blocksLen;
332
209k
    byte* local;
333
334
209k
    if (md5 == NULL || (data == NULL && len > 0)) {
335
0
        return BAD_FUNC_ARG;
336
0
    }
337
338
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)
339
    if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) {
340
#if defined(HAVE_INTEL_QA)
341
        return IntelQaSymMd5(&md5->asyncDev, NULL, data, len);
342
#endif
343
    }
344
#endif /* WOLFSSL_ASYNC_CRYPT */
345
346
    /* check that internal buffLen is valid */
347
209k
    if (md5->buffLen >= WC_MD5_BLOCK_SIZE)
348
0
        return BUFFER_E;
349
350
209k
    if (data == NULL && len == 0) {
351
        /* valid, but do nothing */
352
78
        return 0;
353
78
    }
354
355
    /* add length for final */
356
209k
    AddLength(md5, len);
357
358
209k
    local = (byte*)md5->buffer;
359
360
    /* process any remainder from previous operation */
361
209k
    if (md5->buffLen > 0) {
362
121k
        blocksLen = min(len, WC_MD5_BLOCK_SIZE - md5->buffLen);
363
121k
        XMEMCPY(&local[md5->buffLen], data, blocksLen);
364
365
121k
        md5->buffLen += blocksLen;
366
121k
        data         += blocksLen;
367
121k
        len          -= blocksLen;
368
369
121k
        if (md5->buffLen == WC_MD5_BLOCK_SIZE) {
370
        #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
371
            ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE);
372
        #endif
373
374
64.2k
            ret = XTRANSFORM(md5, (const byte*)local);
375
64.2k
            if (ret != 0)
376
0
                return ret;
377
378
64.2k
            md5->buffLen = 0;
379
64.2k
        }
380
121k
    }
381
382
    /* process blocks */
383
#ifdef XTRANSFORM_LEN
384
    /* get number of blocks */
385
    /* 64-1 = 0x3F (~ Inverted = 0xFFFFFFC0) */
386
    /* len (masked by 0xFFFFFFC0) returns block aligned length */
387
    blocksLen = len & ~(WC_MD5_BLOCK_SIZE-1);
388
    if (blocksLen > 0) {
389
        /* Byte reversal performed in function if required. */
390
        XTRANSFORM_LEN(md5, data, blocksLen);
391
        data += blocksLen;
392
        len  -= blocksLen;
393
    }
394
#else
395
907k
    while (len >= WC_MD5_BLOCK_SIZE) {
396
697k
        word32* local32 = md5->buffer;
397
        /* optimization to avoid memcpy if data pointer is properly aligned */
398
        /* Big Endian requires byte swap, so can't use data directly */
399
    #if defined(WC_HASH_DATA_ALIGNMENT) && !defined(BIG_ENDIAN_ORDER)
400
        if (((wc_ptr_t)data % WC_HASH_DATA_ALIGNMENT) == 0) {
401
            local32 = (word32*)data;
402
        }
403
        else
404
    #endif
405
697k
        {
406
697k
            XMEMCPY(local32, data, WC_MD5_BLOCK_SIZE);
407
697k
        }
408
409
697k
        data += WC_MD5_BLOCK_SIZE;
410
697k
        len  -= WC_MD5_BLOCK_SIZE;
411
412
    #if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
413
        ByteReverseWords(local32, local32, WC_MD5_BLOCK_SIZE);
414
    #endif
415
416
697k
        ret = XTRANSFORM(md5, (const byte*)local32);
417
697k
    }
418
209k
#endif /* XTRANSFORM_LEN */
419
420
    /* save remainder */
421
209k
    if (len > 0) {
422
131k
        XMEMCPY(local, data, len);
423
131k
        md5->buffLen = len;
424
131k
    }
425
426
209k
    return ret;
427
209k
}
428
429
int wc_Md5Final(wc_Md5* md5, byte* hash)
430
23.4k
{
431
23.4k
    byte* local;
432
433
23.4k
    if (md5 == NULL || hash == NULL) {
434
0
        return BAD_FUNC_ARG;
435
0
    }
436
437
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)
438
    if (md5->asyncDev.marker == WOLFSSL_ASYNC_MARKER_MD5) {
439
#if defined(HAVE_INTEL_QA)
440
        return IntelQaSymMd5(&md5->asyncDev, hash, NULL, WC_MD5_DIGEST_SIZE);
441
#endif
442
    }
443
#endif /* WOLFSSL_ASYNC_CRYPT */
444
445
23.4k
    local = (byte*)md5->buffer; /* buffer allocated in word32 size */
446
447
    /* ensure we have a valid buffer length; (-1 to append a byte to length) */
448
23.4k
    if (md5->buffLen > WC_MD5_BLOCK_SIZE - 1) {
449
        /* some places consider this BAD_STATE_E */
450
0
        return BUFFER_E;
451
0
    }
452
453
23.4k
    local[md5->buffLen++] = 0x80;  /* add 1 */
454
455
    /* pad with zeros */
456
23.4k
    if (md5->buffLen > WC_MD5_PAD_SIZE) {
457
1.11k
        if (md5->buffLen < WC_MD5_BLOCK_SIZE) {
458
699
            XMEMSET(&local[md5->buffLen], 0, WC_MD5_BLOCK_SIZE - md5->buffLen);
459
699
        }
460
1.11k
        md5->buffLen += WC_MD5_BLOCK_SIZE - md5->buffLen;
461
462
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
463
        ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE);
464
#endif
465
1.11k
        XTRANSFORM(md5, local);
466
1.11k
        md5->buffLen = 0;
467
1.11k
    }
468
23.4k
    XMEMSET(&local[md5->buffLen], 0, WC_MD5_PAD_SIZE - md5->buffLen);
469
470
#if defined(BIG_ENDIAN_ORDER) && !defined(FREESCALE_MMCAU_SHA)
471
    ByteReverseWords(md5->buffer, md5->buffer, WC_MD5_BLOCK_SIZE);
472
#endif
473
474
    /* put lengths in bits */
475
23.4k
    md5->hiLen = (md5->loLen >> (8 * sizeof(md5->loLen) - 3)) +
476
23.4k
                 (md5->hiLen << 3);
477
23.4k
    md5->loLen = md5->loLen << 3;
478
479
    /* store lengths */
480
    /* ! length ordering dependent on digest endian type ! */
481
23.4k
    XMEMCPY(&local[WC_MD5_PAD_SIZE], &md5->loLen, sizeof(word32));
482
23.4k
    XMEMCPY(&local[WC_MD5_PAD_SIZE + sizeof(word32)], &md5->hiLen, sizeof(word32));
483
484
    /* final transform and result to hash */
485
23.4k
    XTRANSFORM(md5, local);
486
#ifdef BIG_ENDIAN_ORDER
487
    ByteReverseWords(md5->digest, md5->digest, WC_MD5_DIGEST_SIZE);
488
#endif
489
23.4k
    XMEMCPY(hash, md5->digest, WC_MD5_DIGEST_SIZE);
490
491
23.4k
    return _InitMd5(md5); /* reset state */
492
23.4k
}
493
#endif /* !HAVE_MD5_CUST_API */
494
495
496
int wc_InitMd5(wc_Md5* md5)
497
170
{
498
170
    if (md5 == NULL) {
499
0
        return BAD_FUNC_ARG;
500
0
    }
501
170
    return wc_InitMd5_ex(md5, NULL, INVALID_DEVID);
502
170
}
503
504
void wc_Md5Free(wc_Md5* md5)
505
99.2k
{
506
99.2k
    if (md5 == NULL)
507
0
        return;
508
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)
509
    wolfAsync_DevCtxFree(&md5->asyncDev, WOLFSSL_ASYNC_MARKER_MD5);
510
#endif /* WOLFSSL_ASYNC_CRYPT */
511
512
#ifdef WOLFSSL_PIC32MZ_HASH
513
    wc_Md5Pic32Free(md5);
514
#endif
515
99.2k
}
516
517
int wc_Md5GetHash(wc_Md5* md5, byte* hash)
518
1.10k
{
519
1.10k
    int ret;
520
1.10k
    wc_Md5 tmpMd5;
521
522
1.10k
    if (md5 == NULL || hash == NULL)
523
0
        return BAD_FUNC_ARG;
524
525
1.10k
    ret = wc_Md5Copy(md5, &tmpMd5);
526
1.10k
    if (ret == 0) {
527
1.10k
        ret = wc_Md5Final(&tmpMd5, hash);
528
1.10k
    }
529
530
1.10k
    return ret;
531
1.10k
}
532
533
int wc_Md5Copy(wc_Md5* src, wc_Md5* dst)
534
1.16k
{
535
1.16k
    int ret = 0;
536
537
1.16k
    if (src == NULL || dst == NULL)
538
0
        return BAD_FUNC_ARG;
539
540
1.16k
    XMEMCPY(dst, src, sizeof(wc_Md5));
541
542
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_MD5)
543
    ret = wolfAsync_DevCopy(&src->asyncDev, &dst->asyncDev);
544
#endif
545
#ifdef WOLFSSL_PIC32MZ_HASH
546
    ret = wc_Pic32HashCopy(&src->cache, &dst->cache);
547
#endif
548
1.16k
#ifdef WOLFSSL_HASH_FLAGS
549
1.16k
    dst->flags |= WC_HASH_FLAG_ISCOPY;
550
1.16k
#endif
551
552
1.16k
    return ret;
553
1.16k
}
554
555
#if defined(OPENSSL_EXTRA) || defined(HAVE_CURL)
556
/* Apply MD5 transformation to the data                   */
557
/* @param md5  a pointer to wc_MD5 structure              */
558
/* @param data data to be applied MD5 transformation      */
559
/* @return 0 on successful, otherwise non-zero on failure */
560
int wc_Md5Transform(wc_Md5* md5, const byte* data)
561
{
562
    /* sanity check */
563
    if (md5 == NULL || data == NULL) {
564
        return BAD_FUNC_ARG;
565
    }
566
#ifndef HAVE_MD5_CUST_API
567
    return Transform(md5, data);
568
#else
569
    return NOT_COMPILED_IN;
570
#endif
571
}
572
#endif /* OPENSSL_EXTRA */
573
574
#ifdef WOLFSSL_HASH_FLAGS
575
int wc_Md5SetFlags(wc_Md5* md5, word32 flags)
576
93.7k
{
577
93.7k
    if (md5) {
578
93.7k
        md5->flags = flags;
579
93.7k
    }
580
93.7k
    return 0;
581
93.7k
}
582
int wc_Md5GetFlags(wc_Md5* md5, word32* flags)
583
0
{
584
0
    if (md5 && flags) {
585
0
        *flags = md5->flags;
586
0
    }
587
0
    return 0;
588
0
}
589
#endif
590
591
#endif /* WOLFSSL_TI_HASH */
592
#endif /* NO_MD5 */