Coverage Report

Created: 2022-08-24 06:37

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