Coverage Report

Created: 2024-02-25 07:19

/src/libewf/libhmac/libhmac_md5.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * MD5 functions
3
 *
4
 * Copyright (C) 2011-2024, Joachim Metz <joachim.metz@gmail.com>
5
 *
6
 * Refer to AUTHORS for acknowledgements.
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public License
19
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20
 */
21
22
#include <common.h>
23
#include <memory.h>
24
#include <types.h>
25
26
#include "libhmac_definitions.h"
27
#include "libhmac_libcerror.h"
28
#include "libhmac_md5.h"
29
#include "libhmac_md5_context.h"
30
31
/* Creates a MD5 context
32
 * Make sure the value context is referencing, is set to NULL
33
 * Returns 1 if successful or -1 on error
34
 */
35
int libhmac_md5_initialize(
36
     libhmac_md5_context_t **context,
37
     libcerror_error_t **error )
38
0
{
39
0
  static char *function = "libhmac_md5_initialize";
40
41
0
  if( libhmac_md5_context_initialize(
42
0
       context,
43
0
       error ) != 1 )
44
0
  {
45
0
    libcerror_error_set(
46
0
     error,
47
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
48
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
49
0
     "%s: unable to initialize context.",
50
0
     function );
51
52
0
    return( -1 );
53
0
  }
54
0
  return( 1 );
55
0
}
56
57
/* Frees a MD5 context
58
 * Returns 1 if successful or -1 on error
59
 */
60
int libhmac_md5_free(
61
     libhmac_md5_context_t **context,
62
     libcerror_error_t **error )
63
0
{
64
0
  static char *function = "libhmac_md5_free";
65
66
0
  if( libhmac_md5_context_free(
67
0
       context,
68
0
       error ) != 1 )
69
0
  {
70
0
    libcerror_error_set(
71
0
     error,
72
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
73
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
74
0
     "%s: unable to free context.",
75
0
     function );
76
77
0
    return( -1 );
78
0
  }
79
0
  return( 1 );
80
0
}
81
82
/* Updates the MD5 context
83
 * Returns 1 if successful or -1 on error
84
 */
85
int libhmac_md5_update(
86
     libhmac_md5_context_t *context,
87
     const uint8_t *buffer,
88
     size_t size,
89
     libcerror_error_t **error )
90
0
{
91
0
  static char *function = "libhmac_md5_update";
92
93
0
  if( libhmac_md5_context_update(
94
0
       context,
95
0
       buffer,
96
0
       size,
97
0
       error ) != 1 )
98
0
  {
99
0
    libcerror_error_set(
100
0
     error,
101
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
102
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
103
0
     "%s: unable to update context.",
104
0
     function );
105
106
0
    return( -1 );
107
0
  }
108
0
  return( 1 );
109
0
}
110
111
/* Finalizes the MD5 context
112
 * Returns 1 if successful or -1 on error
113
 */
114
int libhmac_md5_finalize(
115
     libhmac_md5_context_t *context,
116
     uint8_t *hash,
117
     size_t hash_size,
118
     libcerror_error_t **error )
119
0
{
120
0
  static char *function = "libhmac_md5_finalize";
121
122
0
  if( libhmac_md5_context_finalize(
123
0
       context,
124
0
       hash,
125
0
       hash_size,
126
0
       error ) != 1 )
127
0
  {
128
0
    libcerror_error_set(
129
0
     error,
130
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
131
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
132
0
     "%s: unable to finalize context.",
133
0
     function );
134
135
0
    return( -1 );
136
0
  }
137
0
  return( 1 );
138
0
}
139
140
/* Calculates the MD5 of the buffer
141
 * Returns 1 if successful or -1 on error
142
 */
143
int libhmac_md5_calculate(
144
     const uint8_t *buffer,
145
     size_t size,
146
     uint8_t *hash,
147
     size_t hash_size,
148
     libcerror_error_t **error )
149
0
{
150
0
  libhmac_md5_context_t *context = NULL;
151
0
  static char *function          = "libhmac_md5_calculate";
152
153
0
  if( libhmac_md5_context_initialize(
154
0
       &context,
155
0
       error ) != 1 )
156
0
  {
157
0
    libcerror_error_set(
158
0
     error,
159
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
160
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
161
0
     "%s: unable to initialize context.",
162
0
     function );
163
164
0
    goto on_error;
165
0
  }
166
0
  if( libhmac_md5_context_update(
167
0
       context,
168
0
       buffer,
169
0
       size,
170
0
       error ) != 1 )
171
0
  {
172
0
    libcerror_error_set(
173
0
     error,
174
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
175
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
176
0
     "%s: unable to update context.",
177
0
     function );
178
179
0
    goto on_error;
180
0
  }
181
0
  if( libhmac_md5_context_finalize(
182
0
       context,
183
0
       hash,
184
0
       hash_size,
185
0
       error ) != 1 )
186
0
  {
187
0
    libcerror_error_set(
188
0
     error,
189
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
190
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
191
0
     "%s: unable to finalize context.",
192
0
     function );
193
194
0
    goto on_error;
195
0
  }
196
0
  if( libhmac_md5_context_free(
197
0
       &context,
198
0
       error ) != 1 )
199
0
  {
200
0
    libcerror_error_set(
201
0
     error,
202
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
203
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
204
0
     "%s: unable to free context.",
205
0
     function );
206
207
0
    goto on_error;
208
0
  }
209
0
  return( 1 );
210
211
0
on_error:
212
0
  if( context != NULL )
213
0
  {
214
0
    libhmac_md5_context_free(
215
0
     &context,
216
0
     NULL );
217
0
  }
218
0
  return( -1 );
219
0
}
220
221
/* Calculates the MD5 HMAC of the buffer
222
 * HMAC is defined in RFC 2104
223
 * Returns 1 if successful or -1 on error
224
 */
225
int libhmac_md5_calculate_hmac(
226
     const uint8_t *key,
227
     size_t key_size,
228
     const uint8_t *buffer,
229
     size_t size,
230
     uint8_t *hmac,
231
     size_t hmac_size,
232
     libcerror_error_t **error )
233
0
{
234
0
  uint8_t key_hash[ LIBHMAC_MD5_HASH_SIZE ];
235
236
0
  libhmac_md5_context_t *context = NULL;
237
0
  uint8_t *key_data              = NULL;
238
0
  uint8_t *inner_padding         = NULL;
239
0
  uint8_t *outer_padding         = NULL;
240
0
  static char *function          = "libhmac_md5_calculate_hmac";
241
0
  size_t block_index             = 0;
242
0
  size_t block_size              = 64;
243
244
0
  if( key == NULL )
245
0
  {
246
0
    libcerror_error_set(
247
0
     error,
248
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
249
0
     LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
250
0
     "%s: invalid key.",
251
0
     function );
252
253
0
    return( -1 );
254
0
  }
255
0
  if( key_size > (size_t) SSIZE_MAX )
256
0
  {
257
0
    libcerror_error_set(
258
0
     error,
259
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
260
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
261
0
     "%s: invalid key size value exceeds maximum.",
262
0
     function );
263
264
0
    return( -1 );
265
0
  }
266
0
  if( hmac_size < (size_t) LIBHMAC_MD5_HASH_SIZE )
267
0
  {
268
0
    libcerror_error_set(
269
0
     error,
270
0
     LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
271
0
     LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
272
0
     "%s: invalid HMAC size value too small.",
273
0
     function );
274
275
0
    return( -1 );
276
0
  }
277
0
  key_data = (uint8_t *) memory_allocate(
278
0
                          sizeof( uint8_t ) * block_size );
279
280
0
  if( key_data == NULL )
281
0
  {
282
0
    libcerror_error_set(
283
0
     error,
284
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
285
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
286
0
     "%s: unable to create key data.",
287
0
     function );
288
289
0
    goto on_error;
290
0
  }
291
0
  if( key_size <= block_size )
292
0
  {
293
0
    if( memory_copy(
294
0
         key_data,
295
0
         key,
296
0
         key_size ) == NULL )
297
0
    {
298
0
      libcerror_error_set(
299
0
       error,
300
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
301
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
302
0
       "%s: unable to copy key data.",
303
0
       function );
304
305
0
      goto on_error;
306
0
    }
307
0
    if( memory_set(
308
0
         &( key_data[ key_size ] ),
309
0
         0,
310
0
         block_size - key_size ) == NULL )
311
0
    {
312
0
      libcerror_error_set(
313
0
       error,
314
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
315
0
       LIBCERROR_MEMORY_ERROR_SET_FAILED,
316
0
       "%s: unable to clear key remaining data.",
317
0
       function );
318
319
0
      goto on_error;
320
0
    }
321
0
  }
322
0
  else
323
0
  {
324
0
    if( libhmac_md5_context_initialize(
325
0
         &context,
326
0
         error ) != 1 )
327
0
    {
328
0
      libcerror_error_set(
329
0
       error,
330
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
331
0
       LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
332
0
       "%s: unable to initialize context.",
333
0
       function );
334
335
0
      goto on_error;
336
0
    }
337
0
    if( libhmac_md5_context_update(
338
0
         context,
339
0
         key,
340
0
         key_size,
341
0
         error ) != 1 )
342
0
    {
343
0
      libcerror_error_set(
344
0
       error,
345
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
346
0
       LIBCERROR_RUNTIME_ERROR_SET_FAILED,
347
0
       "%s: unable to update context.",
348
0
       function );
349
350
0
      goto on_error;
351
0
    }
352
0
    if( libhmac_md5_context_finalize(
353
0
         context,
354
0
         key_hash,
355
0
         LIBHMAC_MD5_HASH_SIZE,
356
0
         error ) != 1 )
357
0
    {
358
0
      libcerror_error_set(
359
0
       error,
360
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
361
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
362
0
       "%s: unable to finalize context.",
363
0
       function );
364
365
0
      goto on_error;
366
0
    }
367
0
    if( libhmac_md5_context_free(
368
0
         &context,
369
0
         error ) != 1 )
370
0
    {
371
0
      libcerror_error_set(
372
0
       error,
373
0
       LIBCERROR_ERROR_DOMAIN_RUNTIME,
374
0
       LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
375
0
       "%s: unable to free context.",
376
0
       function );
377
378
0
      goto on_error;
379
0
    }
380
0
    if( block_size > LIBHMAC_MD5_HASH_SIZE )
381
0
    {
382
0
      if( memory_set(
383
0
           &( key_data[ LIBHMAC_MD5_HASH_SIZE ] ),
384
0
           0,
385
0
           block_size - LIBHMAC_MD5_HASH_SIZE ) == NULL )
386
0
      {
387
0
        libcerror_error_set(
388
0
         error,
389
0
         LIBCERROR_ERROR_DOMAIN_MEMORY,
390
0
         LIBCERROR_MEMORY_ERROR_SET_FAILED,
391
0
         "%s: unable to clear remaining key data.",
392
0
         function );
393
394
0
        goto on_error;
395
0
      }
396
0
    }
397
0
    if( memory_copy(
398
0
         key_data,
399
0
         key_hash,
400
0
         LIBHMAC_MD5_HASH_SIZE ) == NULL )
401
0
    {
402
0
      libcerror_error_set(
403
0
       error,
404
0
       LIBCERROR_ERROR_DOMAIN_MEMORY,
405
0
       LIBCERROR_MEMORY_ERROR_COPY_FAILED,
406
0
       "%s: unable to copy key hash data.",
407
0
       function );
408
409
0
      goto on_error;
410
0
    }
411
0
  }
412
0
  inner_padding = (uint8_t *) memory_allocate(
413
0
                               sizeof( uint8_t ) * block_size );
414
415
0
  if( inner_padding == NULL )
416
0
  {
417
0
    libcerror_error_set(
418
0
     error,
419
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
420
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
421
0
     "%s: unable to create inner padding.",
422
0
     function );
423
424
0
    goto on_error;
425
0
  }
426
0
  if( memory_set(
427
0
       inner_padding,
428
0
       0x36,
429
0
       block_size ) == NULL )
430
0
  {
431
0
    libcerror_error_set(
432
0
     error,
433
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
434
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
435
0
     "%s: unable to set inner padding.",
436
0
     function );
437
438
0
    goto on_error;
439
0
  }
440
0
  outer_padding = (uint8_t *) memory_allocate(
441
0
                               sizeof( uint8_t ) * block_size );
442
443
0
  if( outer_padding == NULL )
444
0
  {
445
0
    libcerror_error_set(
446
0
     error,
447
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
448
0
     LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
449
0
     "%s: unable to create outer padding.",
450
0
     function );
451
452
0
    goto on_error;
453
0
  }
454
0
  if( memory_set(
455
0
       outer_padding,
456
0
       0x5c,
457
0
       block_size ) == NULL )
458
0
  {
459
0
    libcerror_error_set(
460
0
     error,
461
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
462
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
463
0
     "%s: unable to set outer padding.",
464
0
     function );
465
466
0
    goto on_error;
467
0
  }
468
0
  for( block_index = 0;
469
0
       block_index < block_size;
470
0
       block_index++ )
471
0
  {
472
0
    inner_padding[ block_index ] ^= key_data[ block_index ];
473
0
    outer_padding[ block_index ] ^= key_data[ block_index ];
474
0
  }
475
0
  if( libhmac_md5_context_initialize(
476
0
       &context,
477
0
       error ) != 1 )
478
0
  {
479
0
    libcerror_error_set(
480
0
     error,
481
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
482
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
483
0
     "%s: unable to initialize context.",
484
0
     function );
485
486
0
    goto on_error;
487
0
  }
488
0
  if( libhmac_md5_context_update(
489
0
       context,
490
0
       inner_padding,
491
0
       block_size,
492
0
       error ) != 1 )
493
0
  {
494
0
    libcerror_error_set(
495
0
     error,
496
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
497
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
498
0
     "%s: unable to update context.",
499
0
     function );
500
501
0
    goto on_error;
502
0
  }
503
0
  if( libhmac_md5_context_update(
504
0
       context,
505
0
       buffer,
506
0
       size,
507
0
       error ) != 1 )
508
0
  {
509
0
    libcerror_error_set(
510
0
     error,
511
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
512
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
513
0
     "%s: unable to update context.",
514
0
     function );
515
516
0
    goto on_error;
517
0
  }
518
0
  if( libhmac_md5_context_finalize(
519
0
       context,
520
0
       hmac,
521
0
       hmac_size,
522
0
       error ) != 1 )
523
0
  {
524
0
    libcerror_error_set(
525
0
     error,
526
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
527
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
528
0
     "%s: unable to finalize context.",
529
0
     function );
530
531
0
    goto on_error;
532
0
  }
533
0
  if( libhmac_md5_context_free(
534
0
       &context,
535
0
       error ) != 1 )
536
0
  {
537
0
    libcerror_error_set(
538
0
     error,
539
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
540
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
541
0
     "%s: unable to free context.",
542
0
     function );
543
544
0
    goto on_error;
545
0
  }
546
0
  if( libhmac_md5_context_initialize(
547
0
       &context,
548
0
       error ) != 1 )
549
0
  {
550
0
    libcerror_error_set(
551
0
     error,
552
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
553
0
     LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
554
0
     "%s: unable to initialize context.",
555
0
     function );
556
557
0
    goto on_error;
558
0
  }
559
0
  if( libhmac_md5_context_update(
560
0
       context,
561
0
       outer_padding,
562
0
       block_size,
563
0
       error ) != 1 )
564
0
  {
565
0
    libcerror_error_set(
566
0
     error,
567
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
568
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
569
0
     "%s: unable to update context.",
570
0
     function );
571
572
0
    goto on_error;
573
0
  }
574
0
  if( libhmac_md5_context_update(
575
0
       context,
576
0
       hmac,
577
0
       LIBHMAC_MD5_HASH_SIZE,
578
0
       error ) != 1 )
579
0
  {
580
0
    libcerror_error_set(
581
0
     error,
582
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
583
0
     LIBCERROR_RUNTIME_ERROR_SET_FAILED,
584
0
     "%s: unable to update context.",
585
0
     function );
586
587
0
    goto on_error;
588
0
  }
589
0
  if( libhmac_md5_context_finalize(
590
0
       context,
591
0
       hmac,
592
0
       hmac_size,
593
0
       error ) != 1 )
594
0
  {
595
0
    libcerror_error_set(
596
0
     error,
597
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
598
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
599
0
     "%s: unable to finalize context.",
600
0
     function );
601
602
0
    goto on_error;
603
0
  }
604
0
  if( libhmac_md5_context_free(
605
0
       &context,
606
0
       error ) != 1 )
607
0
  {
608
0
    libcerror_error_set(
609
0
     error,
610
0
     LIBCERROR_ERROR_DOMAIN_RUNTIME,
611
0
     LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
612
0
     "%s: unable to free context.",
613
0
     function );
614
615
0
    goto on_error;
616
0
  }
617
0
  if( memory_set(
618
0
       outer_padding,
619
0
       0,
620
0
       block_size ) == NULL )
621
0
  {
622
0
    libcerror_error_set(
623
0
     error,
624
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
625
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
626
0
     "%s: unable to clear outer padding.",
627
0
     function );
628
629
0
    goto on_error;
630
0
  }
631
0
  memory_free(
632
0
   outer_padding );
633
634
0
  outer_padding = NULL;
635
636
0
  if( memory_set(
637
0
       inner_padding,
638
0
       0,
639
0
       block_size ) == NULL )
640
0
  {
641
0
    libcerror_error_set(
642
0
     error,
643
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
644
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
645
0
     "%s: unable to clear inner padding.",
646
0
     function );
647
648
0
    goto on_error;
649
0
  }
650
0
  memory_free(
651
0
   inner_padding );
652
653
0
  inner_padding = NULL;
654
655
0
  if( memory_set(
656
0
       key_data,
657
0
       0,
658
0
       block_size ) == NULL )
659
0
  {
660
0
    libcerror_error_set(
661
0
     error,
662
0
     LIBCERROR_ERROR_DOMAIN_MEMORY,
663
0
     LIBCERROR_MEMORY_ERROR_SET_FAILED,
664
0
     "%s: unable to clear key data.",
665
0
     function );
666
667
0
    goto on_error;
668
0
  }
669
0
  memory_free(
670
0
   key_data );
671
672
0
  key_data = NULL;
673
674
0
  return( 1 );
675
676
0
on_error:
677
0
  if( context != NULL )
678
0
  {
679
0
    libhmac_md5_context_free(
680
0
     &context,
681
0
     NULL );
682
0
  }
683
0
  if( outer_padding != NULL )
684
0
  {
685
0
    memory_set(
686
0
           outer_padding,
687
0
           0,
688
0
           block_size );
689
690
0
    memory_free(
691
0
     outer_padding );
692
0
  }
693
0
  if( inner_padding != NULL )
694
0
  {
695
0
    memory_set(
696
0
           inner_padding,
697
0
           0,
698
0
           block_size );
699
700
0
    memory_free(
701
0
     inner_padding );
702
0
  }
703
0
  if( key_data != NULL )
704
0
  {
705
0
    memory_set(
706
0
           key_data,
707
0
           0,
708
0
           block_size );
709
710
0
    memory_free(
711
0
     key_data );
712
0
  }
713
0
  return( -1 );
714
0
}
715