Coverage Report

Created: 2024-02-25 06:16

/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
32.5k
{
52
32.5k
  const uint32_t iv[_MD5_DIGEST_LENGTH] =
53
32.5k
    {
54
32.5k
      0x67452301,
55
32.5k
      0xefcdab89,
56
32.5k
      0x98badcfe,
57
32.5k
      0x10325476,
58
32.5k
    };
59
32.5k
  memcpy(ctx->state, iv, sizeof(ctx->state));
60
32.5k
  ctx->count = 0;
61
32.5k
  ctx->index = 0;
62
32.5k
}
63
64
13.9k
#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
66.2k
{
71
66.2k
  MD_UPDATE(ctx, length, data, COMPRESS, ctx->count++);
72
66.2k
}
73
74
void
75
md5_digest(struct md5_ctx *ctx,
76
     size_t length,
77
     uint8_t *digest)
78
31.9k
{
79
31.9k
  uint64_t bit_count;
80
  
81
31.9k
  assert(length <= MD5_DIGEST_SIZE);
82
83
31.9k
  MD_PAD(ctx, 8, COMPRESS);
84
85
  /* There are 512 = 2^9 bits in one block */
86
31.9k
  bit_count = (ctx->count << 9) | (ctx->index << 3);
87
88
31.9k
  LE_WRITE_UINT64(ctx->block + (MD5_BLOCK_SIZE - 8), bit_count);
89
31.9k
  nettle_md5_compress(ctx->state, ctx->block);
90
91
31.9k
  _nettle_write_le32(length, digest, ctx->state);
92
31.9k
  md5_init(ctx);
93
31.9k
}
94
95
/* A block, treated as a sequence of 32-bit words. */
96
779k
#define MD5_DATA_LENGTH 16
97
98
/* MD5 functions */
99
100
1.46M
#define F1(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
101
733k
#define F2(x, y, z) F1((z), (x), (y))
102
733k
#define F3(x, y, z) ((x) ^ (y) ^ (z))
103
733k
#define F4(x, y, z) ((y) ^ ((x) | ~(z)))
104
105
2.93M
#define ROUND(f, w, x, y, z, data, s) \
106
2.93M
( 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
45.8k
{
117
45.8k
  uint32_t data[MD5_DATA_LENGTH];
118
45.8k
  uint32_t a, b, c, d;
119
45.8k
  unsigned i;
120
121
779k
  for (i = 0; i < MD5_DATA_LENGTH; i++, input += 4)
122
733k
    data[i] = LE_READ_UINT32(input);
123
124
45.8k
  a = digest[0];
125
45.8k
  b = digest[1];
126
45.8k
  c = digest[2];
127
45.8k
  d = digest[3];
128
129
45.8k
  ROUND(F1, a, b, c, d, data[ 0] + 0xd76aa478, 7);
130
45.8k
  ROUND(F1, d, a, b, c, data[ 1] + 0xe8c7b756, 12);
131
45.8k
  ROUND(F1, c, d, a, b, data[ 2] + 0x242070db, 17);
132
45.8k
  ROUND(F1, b, c, d, a, data[ 3] + 0xc1bdceee, 22);
133
45.8k
  ROUND(F1, a, b, c, d, data[ 4] + 0xf57c0faf, 7);
134
45.8k
  ROUND(F1, d, a, b, c, data[ 5] + 0x4787c62a, 12);
135
45.8k
  ROUND(F1, c, d, a, b, data[ 6] + 0xa8304613, 17);
136
45.8k
  ROUND(F1, b, c, d, a, data[ 7] + 0xfd469501, 22);
137
45.8k
  ROUND(F1, a, b, c, d, data[ 8] + 0x698098d8, 7);
138
45.8k
  ROUND(F1, d, a, b, c, data[ 9] + 0x8b44f7af, 12);
139
45.8k
  ROUND(F1, c, d, a, b, data[10] + 0xffff5bb1, 17);
140
45.8k
  ROUND(F1, b, c, d, a, data[11] + 0x895cd7be, 22);
141
45.8k
  ROUND(F1, a, b, c, d, data[12] + 0x6b901122, 7);
142
45.8k
  ROUND(F1, d, a, b, c, data[13] + 0xfd987193, 12);
143
45.8k
  ROUND(F1, c, d, a, b, data[14] + 0xa679438e, 17);
144
45.8k
  ROUND(F1, b, c, d, a, data[15] + 0x49b40821, 22);
145
146
45.8k
  ROUND(F2, a, b, c, d, data[ 1] + 0xf61e2562, 5);
147
45.8k
  ROUND(F2, d, a, b, c, data[ 6] + 0xc040b340, 9);
148
45.8k
  ROUND(F2, c, d, a, b, data[11] + 0x265e5a51, 14);
149
45.8k
  ROUND(F2, b, c, d, a, data[ 0] + 0xe9b6c7aa, 20);
150
45.8k
  ROUND(F2, a, b, c, d, data[ 5] + 0xd62f105d, 5);
151
45.8k
  ROUND(F2, d, a, b, c, data[10] + 0x02441453, 9);
152
45.8k
  ROUND(F2, c, d, a, b, data[15] + 0xd8a1e681, 14);
153
45.8k
  ROUND(F2, b, c, d, a, data[ 4] + 0xe7d3fbc8, 20);
154
45.8k
  ROUND(F2, a, b, c, d, data[ 9] + 0x21e1cde6, 5);
155
45.8k
  ROUND(F2, d, a, b, c, data[14] + 0xc33707d6, 9);
156
45.8k
  ROUND(F2, c, d, a, b, data[ 3] + 0xf4d50d87, 14);
157
45.8k
  ROUND(F2, b, c, d, a, data[ 8] + 0x455a14ed, 20);
158
45.8k
  ROUND(F2, a, b, c, d, data[13] + 0xa9e3e905, 5);
159
45.8k
  ROUND(F2, d, a, b, c, data[ 2] + 0xfcefa3f8, 9);
160
45.8k
  ROUND(F2, c, d, a, b, data[ 7] + 0x676f02d9, 14);
161
45.8k
  ROUND(F2, b, c, d, a, data[12] + 0x8d2a4c8a, 20);
162
163
45.8k
  ROUND(F3, a, b, c, d, data[ 5] + 0xfffa3942, 4);
164
45.8k
  ROUND(F3, d, a, b, c, data[ 8] + 0x8771f681, 11);
165
45.8k
  ROUND(F3, c, d, a, b, data[11] + 0x6d9d6122, 16);
166
45.8k
  ROUND(F3, b, c, d, a, data[14] + 0xfde5380c, 23);
167
45.8k
  ROUND(F3, a, b, c, d, data[ 1] + 0xa4beea44, 4);
168
45.8k
  ROUND(F3, d, a, b, c, data[ 4] + 0x4bdecfa9, 11);
169
45.8k
  ROUND(F3, c, d, a, b, data[ 7] + 0xf6bb4b60, 16);
170
45.8k
  ROUND(F3, b, c, d, a, data[10] + 0xbebfbc70, 23);
171
45.8k
  ROUND(F3, a, b, c, d, data[13] + 0x289b7ec6, 4);
172
45.8k
  ROUND(F3, d, a, b, c, data[ 0] + 0xeaa127fa, 11);
173
45.8k
  ROUND(F3, c, d, a, b, data[ 3] + 0xd4ef3085, 16);
174
45.8k
  ROUND(F3, b, c, d, a, data[ 6] + 0x04881d05, 23);
175
45.8k
  ROUND(F3, a, b, c, d, data[ 9] + 0xd9d4d039, 4);
176
45.8k
  ROUND(F3, d, a, b, c, data[12] + 0xe6db99e5, 11);
177
45.8k
  ROUND(F3, c, d, a, b, data[15] + 0x1fa27cf8, 16);
178
45.8k
  ROUND(F3, b, c, d, a, data[ 2] + 0xc4ac5665, 23);
179
180
45.8k
  ROUND(F4, a, b, c, d, data[ 0] + 0xf4292244, 6);
181
45.8k
  ROUND(F4, d, a, b, c, data[ 7] + 0x432aff97, 10);
182
45.8k
  ROUND(F4, c, d, a, b, data[14] + 0xab9423a7, 15);
183
45.8k
  ROUND(F4, b, c, d, a, data[ 5] + 0xfc93a039, 21);
184
45.8k
  ROUND(F4, a, b, c, d, data[12] + 0x655b59c3, 6);
185
45.8k
  ROUND(F4, d, a, b, c, data[ 3] + 0x8f0ccc92, 10);
186
45.8k
  ROUND(F4, c, d, a, b, data[10] + 0xffeff47d, 15);
187
45.8k
  ROUND(F4, b, c, d, a, data[ 1] + 0x85845dd1, 21);
188
45.8k
  ROUND(F4, a, b, c, d, data[ 8] + 0x6fa87e4f, 6);
189
45.8k
  ROUND(F4, d, a, b, c, data[15] + 0xfe2ce6e0, 10);
190
45.8k
  ROUND(F4, c, d, a, b, data[ 6] + 0xa3014314, 15);
191
45.8k
  ROUND(F4, b, c, d, a, data[13] + 0x4e0811a1, 21);
192
45.8k
  ROUND(F4, a, b, c, d, data[ 4] + 0xf7537e82, 6);
193
45.8k
  ROUND(F4, d, a, b, c, data[11] + 0xbd3af235, 10);
194
45.8k
  ROUND(F4, c, d, a, b, data[ 2] + 0x2ad7d2bb, 15);
195
45.8k
  ROUND(F4, b, c, d, a, data[ 9] + 0xeb86d391, 21);
196
197
45.8k
  digest[0] += a;
198
45.8k
  digest[1] += b;
199
45.8k
  digest[2] += c;
200
45.8k
  digest[3] += d;
201
45.8k
}