2 * MD5 implementation based on RFC1321.
4 * Copyright (c) 2008 Marko Kreen, Skype Technologies OÜ
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
26 #define bufpos(ctx) ((ctx)->nbytes & (MD5_BLOCK_LENGTH - 1))
28 static inline uint32_t rol(uint32_t v
, int s
)
30 return (v
<< s
) | (v
>> (32 - s
));
33 static inline void swap_words(uint32_t *w
, int n
)
35 #ifdef WORDS_BIGENDIAN
36 for (; n
> 0; w
++, n
--) {
37 uint32_t v
= rol(*w
, 16);
38 *w
= ((v
>> 8) & 0x00FF00FF) | ((v
<< 8) & 0xFF00FF00);
43 static inline void put_word(uint8_t *dst
, uint32_t val
)
45 #ifdef WORDS_BIGENDIAN
59 #define F(X,Y,Z) ((X & Y) | ((~X) & Z))
60 #define G(X,Y,Z) ((X & Z) | (Y & (~Z)))
61 #define H(X,Y,Z) (X ^ Y ^ Z)
62 #define I(X,Y,Z) (Y ^ (X | (~Z)))
64 #define OP(fn, a, b, c, d, k, s, T_i) \
65 a = b + rol(a + fn(b, c, d) + X[k] + T_i, s)
67 static void md5_mix(struct md5_ctx
*ctx
, const uint32_t *X
)
77 OP(F
, a
, b
, c
, d
, 0, 7, 0xd76aa478);
78 OP(F
, d
, a
, b
, c
, 1, 12, 0xe8c7b756);
79 OP(F
, c
, d
, a
, b
, 2, 17, 0x242070db);
80 OP(F
, b
, c
, d
, a
, 3, 22, 0xc1bdceee);
81 OP(F
, a
, b
, c
, d
, 4, 7, 0xf57c0faf);
82 OP(F
, d
, a
, b
, c
, 5, 12, 0x4787c62a);
83 OP(F
, c
, d
, a
, b
, 6, 17, 0xa8304613);
84 OP(F
, b
, c
, d
, a
, 7, 22, 0xfd469501);
85 OP(F
, a
, b
, c
, d
, 8, 7, 0x698098d8);
86 OP(F
, d
, a
, b
, c
, 9, 12, 0x8b44f7af);
87 OP(F
, c
, d
, a
, b
, 10, 17, 0xffff5bb1);
88 OP(F
, b
, c
, d
, a
, 11, 22, 0x895cd7be);
89 OP(F
, a
, b
, c
, d
, 12, 7, 0x6b901122);
90 OP(F
, d
, a
, b
, c
, 13, 12, 0xfd987193);
91 OP(F
, c
, d
, a
, b
, 14, 17, 0xa679438e);
92 OP(F
, b
, c
, d
, a
, 15, 22, 0x49b40821);
95 OP(G
, a
, b
, c
, d
, 1, 5, 0xf61e2562);
96 OP(G
, d
, a
, b
, c
, 6, 9, 0xc040b340);
97 OP(G
, c
, d
, a
, b
, 11, 14, 0x265e5a51);
98 OP(G
, b
, c
, d
, a
, 0, 20, 0xe9b6c7aa);
99 OP(G
, a
, b
, c
, d
, 5, 5, 0xd62f105d);
100 OP(G
, d
, a
, b
, c
, 10, 9, 0x02441453);
101 OP(G
, c
, d
, a
, b
, 15, 14, 0xd8a1e681);
102 OP(G
, b
, c
, d
, a
, 4, 20, 0xe7d3fbc8);
103 OP(G
, a
, b
, c
, d
, 9, 5, 0x21e1cde6);
104 OP(G
, d
, a
, b
, c
, 14, 9, 0xc33707d6);
105 OP(G
, c
, d
, a
, b
, 3, 14, 0xf4d50d87);
106 OP(G
, b
, c
, d
, a
, 8, 20, 0x455a14ed);
107 OP(G
, a
, b
, c
, d
, 13, 5, 0xa9e3e905);
108 OP(G
, d
, a
, b
, c
, 2, 9, 0xfcefa3f8);
109 OP(G
, c
, d
, a
, b
, 7, 14, 0x676f02d9);
110 OP(G
, b
, c
, d
, a
, 12, 20, 0x8d2a4c8a);
113 OP(H
, a
, b
, c
, d
, 5, 4, 0xfffa3942);
114 OP(H
, d
, a
, b
, c
, 8, 11, 0x8771f681);
115 OP(H
, c
, d
, a
, b
, 11, 16, 0x6d9d6122);
116 OP(H
, b
, c
, d
, a
, 14, 23, 0xfde5380c);
117 OP(H
, a
, b
, c
, d
, 1, 4, 0xa4beea44);
118 OP(H
, d
, a
, b
, c
, 4, 11, 0x4bdecfa9);
119 OP(H
, c
, d
, a
, b
, 7, 16, 0xf6bb4b60);
120 OP(H
, b
, c
, d
, a
, 10, 23, 0xbebfbc70);
121 OP(H
, a
, b
, c
, d
, 13, 4, 0x289b7ec6);
122 OP(H
, d
, a
, b
, c
, 0, 11, 0xeaa127fa);
123 OP(H
, c
, d
, a
, b
, 3, 16, 0xd4ef3085);
124 OP(H
, b
, c
, d
, a
, 6, 23, 0x04881d05);
125 OP(H
, a
, b
, c
, d
, 9, 4, 0xd9d4d039);
126 OP(H
, d
, a
, b
, c
, 12, 11, 0xe6db99e5);
127 OP(H
, c
, d
, a
, b
, 15, 16, 0x1fa27cf8);
128 OP(H
, b
, c
, d
, a
, 2, 23, 0xc4ac5665);
131 OP(I
, a
, b
, c
, d
, 0, 6, 0xf4292244);
132 OP(I
, d
, a
, b
, c
, 7, 10, 0x432aff97);
133 OP(I
, c
, d
, a
, b
, 14, 15, 0xab9423a7);
134 OP(I
, b
, c
, d
, a
, 5, 21, 0xfc93a039);
135 OP(I
, a
, b
, c
, d
, 12, 6, 0x655b59c3);
136 OP(I
, d
, a
, b
, c
, 3, 10, 0x8f0ccc92);
137 OP(I
, c
, d
, a
, b
, 10, 15, 0xffeff47d);
138 OP(I
, b
, c
, d
, a
, 1, 21, 0x85845dd1);
139 OP(I
, a
, b
, c
, d
, 8, 6, 0x6fa87e4f);
140 OP(I
, d
, a
, b
, c
, 15, 10, 0xfe2ce6e0);
141 OP(I
, c
, d
, a
, b
, 6, 15, 0xa3014314);
142 OP(I
, b
, c
, d
, a
, 13, 21, 0x4e0811a1);
143 OP(I
, a
, b
, c
, d
, 4, 6, 0xf7537e82);
144 OP(I
, d
, a
, b
, c
, 11, 10, 0xbd3af235);
145 OP(I
, c
, d
, a
, b
, 2, 15, 0x2ad7d2bb);
146 OP(I
, b
, c
, d
, a
, 9, 21, 0xeb86d391);
158 void md5_reset(struct md5_ctx
*ctx
)
167 void md5_update(struct md5_ctx
*ctx
, const void *data
, unsigned int len
)
170 const uint8_t *ptr
= data
;
171 uint8_t *buf
= (uint8_t *)ctx
->buf
;
174 n
= MD5_BLOCK_LENGTH
- bufpos(ctx
);
177 memcpy(buf
+ bufpos(ctx
), ptr
, n
);
181 if (bufpos(ctx
) == 0) {
182 swap_words(ctx
->buf
, 16);
183 md5_mix(ctx
, ctx
->buf
);
188 void md5_final(uint8_t *dst
, struct md5_ctx
*ctx
)
190 static const uint8_t padding
[MD5_BLOCK_LENGTH
] = { 0x80 };
191 uint64_t final_len
= ctx
->nbytes
* 8;
192 int pad_len
, pos
= bufpos(ctx
);
195 pad_len
= MD5_BLOCK_LENGTH
- 8 - pos
;
197 pad_len
+= MD5_BLOCK_LENGTH
;
198 md5_update(ctx
, padding
, pad_len
);
200 /* add length directly */
201 swap_words(ctx
->buf
, 14);
202 ctx
->buf
[14] = final_len
;
203 ctx
->buf
[15] = final_len
>> 32;
206 md5_mix(ctx
, ctx
->buf
);
207 put_word(dst
, ctx
->a
);
208 put_word(dst
+ 4, ctx
->b
);
209 put_word(dst
+ 8, ctx
->c
);
210 put_word(dst
+ 12, ctx
->d
);