File Coverage

src/hash/md5.c
Criterion Covered Total %
statement 58 73 79.4
branch 12 16 75.0
condition n/a
subroutine n/a
pod n/a
total 70 89 78.6


line stmt bran cond sub pod time code
1             /*
2             * Copyright (c) 2016 Thomas Pornin
3             *
4             * Permission is hereby granted, free of charge, to any person obtaining
5             * a copy of this software and associated documentation files (the
6             * "Software"), to deal in the Software without restriction, including
7             * without limitation the rights to use, copy, modify, merge, publish,
8             * distribute, sublicense, and/or sell copies of the Software, and to
9             * permit persons to whom the Software is furnished to do so, subject to
10             * the following conditions:
11             *
12             * The above copyright notice and this permission notice shall be
13             * included in all copies or substantial portions of the Software.
14             *
15             * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16             * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17             * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18             * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19             * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20             * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21             * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22             * SOFTWARE.
23             */
24              
25             #include "inner.h"
26              
27             #define F(B, C, D) ((((C) ^ (D)) & (B)) ^ (D))
28             #define G(B, C, D) ((((C) ^ (B)) & (D)) ^ (C))
29             #define H(B, C, D) ((B) ^ (C) ^ (D))
30             #define I(B, C, D) ((C) ^ ((B) | ~(D)))
31              
32             #define ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
33              
34             /* see inner.h */
35             const uint32_t br_md5_IV[4] = {
36             0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476
37             };
38              
39             static const uint32_t K[64] = {
40             0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE,
41             0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501,
42             0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE,
43             0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821,
44              
45             0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA,
46             0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8,
47             0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED,
48             0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A,
49              
50             0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C,
51             0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70,
52             0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05,
53             0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665,
54              
55             0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039,
56             0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1,
57             0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1,
58             0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391
59             };
60              
61             static const unsigned char MP[48] = {
62             1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12,
63             5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2,
64             0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9
65             };
66              
67             /* see inner.h */
68             void
69 52           br_md5_round(const unsigned char *buf, uint32_t *val)
70             {
71             uint32_t m[16];
72             uint32_t a, b, c, d;
73             int i;
74              
75 52           a = val[0];
76 52           b = val[1];
77 52           c = val[2];
78 52           d = val[3];
79             /* obsolete
80             for (i = 0; i < 16; i ++) {
81             m[i] = br_dec32le(buf + (i << 2));
82             }
83             */
84 52           br_range_dec32le(m, 16, buf);
85              
86 260 100         for (i = 0; i < 16; i += 4) {
87 208           a = b + ROTL(a + F(b, c, d) + m[i + 0] + K[i + 0], 7);
88 208           d = a + ROTL(d + F(a, b, c) + m[i + 1] + K[i + 1], 12);
89 208           c = d + ROTL(c + F(d, a, b) + m[i + 2] + K[i + 2], 17);
90 208           b = c + ROTL(b + F(c, d, a) + m[i + 3] + K[i + 3], 22);
91             }
92 260 100         for (i = 16; i < 32; i += 4) {
93 208           a = b + ROTL(a + G(b, c, d) + m[MP[i - 16]] + K[i + 0], 5);
94 208           d = a + ROTL(d + G(a, b, c) + m[MP[i - 15]] + K[i + 1], 9);
95 208           c = d + ROTL(c + G(d, a, b) + m[MP[i - 14]] + K[i + 2], 14);
96 208           b = c + ROTL(b + G(c, d, a) + m[MP[i - 13]] + K[i + 3], 20);
97             }
98 260 100         for (i = 32; i < 48; i += 4) {
99 208           a = b + ROTL(a + H(b, c, d) + m[MP[i - 16]] + K[i + 0], 4);
100 208           d = a + ROTL(d + H(a, b, c) + m[MP[i - 15]] + K[i + 1], 11);
101 208           c = d + ROTL(c + H(d, a, b) + m[MP[i - 14]] + K[i + 2], 16);
102 208           b = c + ROTL(b + H(c, d, a) + m[MP[i - 13]] + K[i + 3], 23);
103             }
104 260 100         for (i = 48; i < 64; i += 4) {
105 208           a = b + ROTL(a + I(b, c, d) + m[MP[i - 16]] + K[i + 0], 6);
106 208           d = a + ROTL(d + I(a, b, c) + m[MP[i - 15]] + K[i + 1], 10);
107 208           c = d + ROTL(c + I(d, a, b) + m[MP[i - 14]] + K[i + 2], 15);
108 208           b = c + ROTL(b + I(c, d, a) + m[MP[i - 13]] + K[i + 3], 21);
109             }
110              
111 52           val[0] += a;
112 52           val[1] += b;
113 52           val[2] += c;
114 52           val[3] += d;
115 52           }
116              
117             /* see bearssl.h */
118             void
119 4           br_md5_init(br_md5_context *cc)
120             {
121 4           cc->vtable = &br_md5_vtable;
122 4           memcpy(cc->val, br_md5_IV, sizeof cc->val);
123 4           cc->count = 0;
124 4           }
125              
126             /* see bearssl.h */
127             void
128 26           br_md5_update(br_md5_context *cc, const void *data, size_t len)
129             {
130             const unsigned char *buf;
131             size_t ptr;
132              
133 26           buf = data;
134 26           ptr = (size_t)cc->count & 63;
135 78 100         while (len > 0) {
136             size_t clen;
137              
138 52           clen = 64 - ptr;
139 52 50         if (clen > len) {
140 0           clen = len;
141             }
142 52           memcpy(cc->buf + ptr, buf, clen);
143 52           ptr += clen;
144 52           buf += clen;
145 52           len -= clen;
146 52           cc->count += (uint64_t)clen;
147 52 50         if (ptr == 64) {
148 52           br_md5_round(cc->buf, cc->val);
149 52           ptr = 0;
150             }
151             }
152 26           }
153              
154             /* see bearssl.h */
155             void
156 0           br_md5_out(const br_md5_context *cc, void *dst)
157             {
158             unsigned char buf[64];
159             uint32_t val[4];
160             size_t ptr;
161              
162 0           ptr = (size_t)cc->count & 63;
163 0           memcpy(buf, cc->buf, ptr);
164 0           memcpy(val, cc->val, sizeof val);
165 0           buf[ptr ++] = 0x80;
166 0 0         if (ptr > 56) {
167 0           memset(buf + ptr, 0, 64 - ptr);
168 0           br_md5_round(buf, val);
169 0           memset(buf, 0, 56);
170             } else {
171 0           memset(buf + ptr, 0, 56 - ptr);
172             }
173 0           br_enc64le(buf + 56, cc->count << 3);
174 0           br_md5_round(buf, val);
175 0           br_range_enc32le(dst, val, 4);
176 0           }
177              
178             /* see bearssl.h */
179             uint64_t
180 30           br_md5_state(const br_md5_context *cc, void *dst)
181             {
182 30           br_range_enc32le(dst, cc->val, 4);
183 30           return cc->count;
184             }
185              
186             /* see bearssl.h */
187             void
188 26           br_md5_set_state(br_md5_context *cc, const void *stb, uint64_t count)
189             {
190 26           br_range_dec32le(cc->val, 4, stb);
191 26           cc->count = count;
192 26           }
193              
194             /* see bearssl.h */
195             const br_hash_class br_md5_vtable = {
196             sizeof(br_md5_context),
197             BR_HASHDESC_ID(br_md5_ID)
198             | BR_HASHDESC_OUT(16)
199             | BR_HASHDESC_STATE(16)
200             | BR_HASHDESC_LBLEN(6)
201             | BR_HASHDESC_MD_PADDING,
202             (void (*)(const br_hash_class **))&br_md5_init,
203             (void (*)(const br_hash_class **, const void *, size_t))&br_md5_update,
204             (void (*)(const br_hash_class *const *, void *))&br_md5_out,
205             (uint64_t (*)(const br_hash_class *const *, void *))&br_md5_state,
206             (void (*)(const br_hash_class **, const void *, uint64_t))
207             &br_md5_set_state
208             };