Coverage Report

Created: 2024-06-28 06:39

/src/nettle-with-mini-gmp/md5.c
Line
Count
Source
1
/* md5.c
2
3
   The MD5 hash function, described in RFC 1321.
4
5
   Copyright (C) 2001 Niels Möller
6
7
   This file is part of GNU Nettle.
8
9
   GNU Nettle is free software: you can redistribute it and/or
10
   modify it under the terms of either:
11
12
     * the GNU Lesser General Public License as published by the Free
13
       Software Foundation; either version 3 of the License, or (at your
14
       option) any later version.
15
16
   or
17
18
     * the GNU General Public License as published by the Free
19
       Software Foundation; either version 2 of the License, or (at your
20
       option) any later version.
21
22
   or both in parallel, as here.
23
24
   GNU Nettle is distributed in the hope that it will be useful,
25
   but WITHOUT ANY WARRANTY; without even the implied warranty of
26
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
27
   General Public License for more details.
28
29
   You should have received copies of the GNU General Public License and
30
   the GNU Lesser General Public License along with this program.  If
31
   not, see http://www.gnu.org/licenses/.
32
*/
33
34
/* Based on public domain code hacked by Colin Plumb, Andrew Kuchling, and
35
 * Niels Möller. */
36
37
#if HAVE_CONFIG_H
38
# include "config.h"
39
#endif
40
41
#include <assert.h>
42
#include <string.h>
43
44
#include "md5.h"
45
46
#include "macros.h"
47
#include "nettle-write.h"
48
49
void
50
md5_init(struct md5_ctx *ctx)
51
25.2k
{
52
25.2k
  const uint32_t iv[_MD5_DIGEST_LENGTH] =
53
25.2k
    {
54
25.2k
      0x67452301,
55
25.2k
      0xefcdab89,
56
25.2k
      0x98badcfe,
57
25.2k
      0x10325476,
58
25.2k
    };
59
25.2k
  memcpy(ctx->state, iv, sizeof(ctx->state));
60
25.2k
  ctx->count = 0;
61
25.2k
  ctx->index = 0;
62
25.2k
}
63
64
29.4k
#define COMPRESS(ctx, data) (nettle_md5_compress((ctx)->state, (data)))
65
66
void
67
md5_update(struct md5_ctx *ctx,
68
     size_t length,
69
     const uint8_t *data)
70
57.3k
{
71
57.3k
  MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++);
72
57.3k
}
73
74
void
75
md5_digest(struct md5_ctx *ctx,
76
     size_t length,
77
     uint8_t *digest)
78
24.6k
{
79
24.6k
  uint64_t bit_count;
80
  
81
24.6k
  assert(length <= MD5_DIGEST_SIZE);
82
83
24.6k
  MD_PAD(ctx, 8, COMPRESS);
84
85
  /* There are 512 = 2^9 bits in one block */
86
24.6k
  bit_count = (ctx->count << 9) | (ctx->index << 3);
87
88
24.6k
  LE_WRITE_UINT64(ctx->block + (MD5_BLOCK_SIZE - 8), bit_count);
89
24.6k
  nettle_md5_compress(ctx->state, ctx->block);
90
91
24.6k
  _nettle_write_le32(length, digest, ctx->state);
92
24.6k
  md5_init(ctx);
93
24.6k
}
94
95
/* A block, treated as a sequence of 32-bit words. */
96
920k
#define MD5_DATA_LENGTH 16
97
98
/* MD5 functions */
99
100
1.73M
#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
101
866k
#define F2(x, y, z) F1((z), (x), (y))
102
866k
#define F3(x, y, z) ((x) ^ (y) ^ (z))
103
866k
#define F4(x, y, z) ((y) ^ ((x) | ~(z)))
104
105
3.46M
#define ROUND(f, w, x, y, z, data, s) \
106
3.46M
( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )
107
108
/* Perform the MD5 transformation on one full block of 16 32-bit
109
 * words.
110
 *
111
 * Compresses 20 (_MD5_DIGEST_LENGTH + MD5_DATA_LENGTH) words into 4
112
 * (_MD5_DIGEST_LENGTH) words. */
113
114
void
115
nettle_md5_compress(uint32_t *digest, const uint8_t *input)
116
54.1k
{
117
54.1k
  uint32_t data[MD5_DATA_LENGTH];
118
54.1k
  uint32_t a, b, c, d;
119
54.1k
  unsigned i;
120
121
920k
  for (i = 0; i < MD5_DATA_LENGTH; i++, input += 4)
122
866k
    data[i] = LE_READ_UINT32(input);
123
124
54.1k
  a = digest[0];
125
54.1k
  b = digest[1];
126
54.1k
  c = digest[2];
127
54.1k
  d = digest[3];
128
129
54.1k
  ROUND(F1, a, b, c, d, data[ 0] + 0xd76aa478, 7);
130
54.1k
  ROUND(F1, d, a, b, c, data[ 1] + 0xe8c7b756, 12);
131
54.1k
  ROUND(F1, c, d, a, b, data[ 2] + 0x242070db, 17);
132
54.1k
  ROUND(F1, b, c, d, a, data[ 3] + 0xc1bdceee, 22);
133
54.1k
  ROUND(F1, a, b, c, d, data[ 4] + 0xf57c0faf, 7);
134
54.1k
  ROUND(F1, d, a, b, c, data[ 5] + 0x4787c62a, 12);
135
54.1k
  ROUND(F1, c, d, a, b, data[ 6] + 0xa8304613, 17);
136
54.1k
  ROUND(F1, b, c, d, a, data[ 7] + 0xfd469501, 22);
137
54.1k
  ROUND(F1, a, b, c, d, data[ 8] + 0x698098d8, 7);
138
54.1k
  ROUND(F1, d, a, b, c, data[ 9] + 0x8b44f7af, 12);
139
54.1k
  ROUND(F1, c, d, a, b, data[10] + 0xffff5bb1, 17);
140
54.1k
  ROUND(F1, b, c, d, a, data[11] + 0x895cd7be, 22);
141
54.1k
  ROUND(F1, a, b, c, d, data[12] + 0x6b901122, 7);
142
54.1k
  ROUND(F1, d, a, b, c, data[13] + 0xfd987193, 12);
143
54.1k
  ROUND(F1, c, d, a, b, data[14] + 0xa679438e, 17);
144
54.1k
  ROUND(F1, b, c, d, a, data[15] + 0x49b40821, 22);
145
146
54.1k
  ROUND(F2, a, b, c, d, data[ 1] + 0xf61e2562, 5);
147
54.1k
  ROUND(F2, d, a, b, c, data[ 6] + 0xc040b340, 9);
148
54.1k
  ROUND(F2, c, d, a, b, data[11] + 0x265e5a51, 14);
149
54.1k
  ROUND(F2, b, c, d, a, data[ 0] + 0xe9b6c7aa, 20);
150
54.1k
  ROUND(F2, a, b, c, d, data[ 5] + 0xd62f105d, 5);
151
54.1k
  ROUND(F2, d, a, b, c, data[10] + 0x02441453, 9);
152
54.1k
  ROUND(F2, c, d, a, b, data[15] + 0xd8a1e681, 14);
153
54.1k
  ROUND(F2, b, c, d, a, data[ 4] + 0xe7d3fbc8, 20);
154
54.1k
  ROUND(F2, a, b, c, d, data[ 9] + 0x21e1cde6, 5);
155
54.1k
  ROUND(F2, d, a, b, c, data[14] + 0xc33707d6, 9);
156
54.1k
  ROUND(F2, c, d, a, b, data[ 3] + 0xf4d50d87, 14);
157
54.1k
  ROUND(F2, b, c, d, a, data[ 8] + 0x455a14ed, 20);
158
54.1k
  ROUND(F2, a, b, c, d, data[13] + 0xa9e3e905, 5);
159
54.1k
  ROUND(F2, d, a, b, c, data[ 2] + 0xfcefa3f8, 9);
160
54.1k
  ROUND(F2, c, d, a, b, data[ 7] + 0x676f02d9, 14);
161
54.1k
  ROUND(F2, b, c, d, a, data[12] + 0x8d2a4c8a, 20);
162
163
54.1k
  ROUND(F3, a, b, c, d, data[ 5] + 0xfffa3942, 4);
164
54.1k
  ROUND(F3, d, a, b, c, data[ 8] + 0x8771f681, 11);
165
54.1k
  ROUND(F3, c, d, a, b, data[11] + 0x6d9d6122, 16);
166
54.1k
  ROUND(F3, b, c, d, a, data[14] + 0xfde5380c, 23);
167
54.1k
  ROUND(F3, a, b, c, d, data[ 1] + 0xa4beea44, 4);
168
54.1k
  ROUND(F3, d, a, b, c, data[ 4] + 0x4bdecfa9, 11);
169
54.1k
  ROUND(F3, c, d, a, b, data[ 7] + 0xf6bb4b60, 16);
170
54.1k
  ROUND(F3, b, c, d, a, data[10] + 0xbebfbc70, 23);
171
54.1k
  ROUND(F3, a, b, c, d, data[13] + 0x289b7ec6, 4);
172
54.1k
  ROUND(F3, d, a, b, c, data[ 0] + 0xeaa127fa, 11);
173
54.1k
  ROUND(F3, c, d, a, b, data[ 3] + 0xd4ef3085, 16);
174
54.1k
  ROUND(F3, b, c, d, a, data[ 6] + 0x04881d05, 23);
175
54.1k
  ROUND(F3, a, b, c, d, data[ 9] + 0xd9d4d039, 4);
176
54.1k
  ROUND(F3, d, a, b, c, data[12] + 0xe6db99e5, 11);
177
54.1k
  ROUND(F3, c, d, a, b, data[15] + 0x1fa27cf8, 16);
178
54.1k
  ROUND(F3, b, c, d, a, data[ 2] + 0xc4ac5665, 23);
179
180
54.1k
  ROUND(F4, a, b, c, d, data[ 0] + 0xf4292244, 6);
181
54.1k
  ROUND(F4, d, a, b, c, data[ 7] + 0x432aff97, 10);
182
54.1k
  ROUND(F4, c, d, a, b, data[14] + 0xab9423a7, 15);
183
54.1k
  ROUND(F4, b, c, d, a, data[ 5] + 0xfc93a039, 21);
184
54.1k
  ROUND(F4, a, b, c, d, data[12] + 0x655b59c3, 6);
185
54.1k
  ROUND(F4, d, a, b, c, data[ 3] + 0x8f0ccc92, 10);
186
54.1k
  ROUND(F4, c, d, a, b, data[10] + 0xffeff47d, 15);
187
54.1k
  ROUND(F4, b, c, d, a, data[ 1] + 0x85845dd1, 21);
188
54.1k
  ROUND(F4, a, b, c, d, data[ 8] + 0x6fa87e4f, 6);
189
54.1k
  ROUND(F4, d, a, b, c, data[15] + 0xfe2ce6e0, 10);
190
54.1k
  ROUND(F4, c, d, a, b, data[ 6] + 0xa3014314, 15);
191
54.1k
  ROUND(F4, b, c, d, a, data[13] + 0x4e0811a1, 21);
192
54.1k
  ROUND(F4, a, b, c, d, data[ 4] + 0xf7537e82, 6);
193
54.1k
  ROUND(F4, d, a, b, c, data[11] + 0xbd3af235, 10);
194
54.1k
  ROUND(F4, c, d, a, b, data[ 2] + 0x2ad7d2bb, 15);
195
54.1k
  ROUND(F4, b, c, d, a, data[ 9] + 0xeb86d391, 21);
196
197
54.1k
  digest[0] += a;
198
54.1k
  digest[1] += b;
199
54.1k
  digest[2] += c;
200
54.1k
  digest[3] += d;
201
54.1k
}