26 "MdCtx outgrew PC_WORK_MD - raise it in protocore_config.h, which derives PC_SECURE_ARENA_SIZE from it");
34static inline uint32_t rotl(uint32_t v,
unsigned n)
36 return (v << n) | (v >> (32 - n));
41static const uint32_t MD5_K[64] = {
42 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
43 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
44 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
45 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
46 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
47 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
48 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
49 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391};
51static const uint8_t MD5_S[64] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
52 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
53 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
54 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21};
56static void pc_md5_compress(uint32_t s[4],
const uint8_t block[64])
59 for (
int i = 0; i < 16; i++)
67 for (
int i = 0; i < 64; i++)
73 f = (b & c) | (~b & d);
78 f = (d & b) | (~d & c);
91 f += a + MD5_K[i] + m[g];
95 b += rotl(f, MD5_S[i]);
105 c->
state[0] = 0x67452301;
106 c->
state[1] = 0xefcdab89;
107 c->
state[2] = 0x98badcfe;
108 c->
state[3] = 0x10325476;
115static void pc_md4_compress(uint32_t s[4],
const uint8_t block[64])
118 for (
int i = 0; i < 16; i++)
126#define F4(X, Y, Z) (((X) & (Y)) | (~(X) & (Z)))
127#define G4(X, Y, Z) (((X) & (Y)) | ((X) & (Z)) | ((Y) & (Z)))
128#define H4(X, Y, Z) ((X) ^ (Y) ^ (Z))
129#define R1(A, B, C, D, K, S) A = rotl((uint32_t)(A + F4(B, C, D) + x[K]), S)
130#define R2(A, B, C, D, K, S) A = rotl((uint32_t)(A + G4(B, C, D) + x[K] + 0x5a827999u), S)
131#define R3(A, B, C, D, K, S) A = rotl((uint32_t)(A + H4(B, C, D) + x[K] + 0x6ed9eba1u), S)
132 R1(a, b, c, d, 0, 3);
133 R1(d, a, b, c, 1, 7);
134 R1(c, d, a, b, 2, 11);
135 R1(b, c, d, a, 3, 19);
136 R1(a, b, c, d, 4, 3);
137 R1(d, a, b, c, 5, 7);
138 R1(c, d, a, b, 6, 11);
139 R1(b, c, d, a, 7, 19);
140 R1(a, b, c, d, 8, 3);
141 R1(d, a, b, c, 9, 7);
142 R1(c, d, a, b, 10, 11);
143 R1(b, c, d, a, 11, 19);
144 R1(a, b, c, d, 12, 3);
145 R1(d, a, b, c, 13, 7);
146 R1(c, d, a, b, 14, 11);
147 R1(b, c, d, a, 15, 19);
148 R2(a, b, c, d, 0, 3);
149 R2(d, a, b, c, 4, 5);
150 R2(c, d, a, b, 8, 9);
151 R2(b, c, d, a, 12, 13);
152 R2(a, b, c, d, 1, 3);
153 R2(d, a, b, c, 5, 5);
154 R2(c, d, a, b, 9, 9);
155 R2(b, c, d, a, 13, 13);
156 R2(a, b, c, d, 2, 3);
157 R2(d, a, b, c, 6, 5);
158 R2(c, d, a, b, 10, 9);
159 R2(b, c, d, a, 14, 13);
160 R2(a, b, c, d, 3, 3);
161 R2(d, a, b, c, 7, 5);
162 R2(c, d, a, b, 11, 9);
163 R2(b, c, d, a, 15, 13);
164 R3(a, b, c, d, 0, 3);
165 R3(d, a, b, c, 8, 9);
166 R3(c, d, a, b, 4, 11);
167 R3(b, c, d, a, 12, 15);
168 R3(a, b, c, d, 2, 3);
169 R3(d, a, b, c, 10, 9);
170 R3(c, d, a, b, 6, 11);
171 R3(b, c, d, a, 14, 15);
172 R3(a, b, c, d, 1, 3);
173 R3(d, a, b, c, 9, 9);
174 R3(c, d, a, b, 5, 11);
175 R3(b, c, d, a, 13, 15);
176 R3(a, b, c, d, 3, 3);
177 R3(d, a, b, c, 11, 9);
178 R3(c, d, a, b, 7, 11);
179 R3(b, c, d, a, 15, 15);
194 c->
state[0] = 0x67452301;
195 c->
state[1] = 0xefcdab89;
196 c->
state[2] = 0x98badcfe;
197 c->
state[3] = 0x10325476;
208 c->
bits += (uint64_t)len * 8;
211 uint32_t take = 64 - c->
buf_len;
212 if ((
size_t)take > len)
214 take = (uint32_t)len;
230 uint64_t bits = c->
bits;
232 md_absorb(c, &pad, 1, compress);
236 md_absorb(c, &zero, 1, compress);
239 for (
int i = 0; i < 8; i++)
241 lenbuf[i] = (uint8_t)(bits >> (8 * i));
243 md_absorb(c, lenbuf, 8, compress);
244 for (
int i = 0; i < 4; i++)
252 md_absorb(c, data, len, pc_md5_compress);
256 md_finish(c, out, pc_md5_compress);
260 md_absorb(c, data, len, pc_md4_compress);
264 md_finish(c, out, pc_md4_compress);
267void md5(
const uint8_t *data,
size_t len, uint8_t out[16])
274void md4(
const uint8_t *data,
size_t len, uint8_t out[16])
284void pc_hmac_md5(
const uint8_t *key,
size_t key_len,
const uint8_t *msg,
size_t msg_len, uint8_t out[16])
287 memset(k, 0,
sizeof(k));
290 md5(key, key_len, k);
294 memcpy(k, key, key_len);
299 for (
int i = 0; i < 64; i++)
301 ipad[i] = (uint8_t)(k[i] ^ 0x36);
302 opad[i] = (uint8_t)(k[i] ^ 0x5c);
Per-translation-unit optimization override for hot, pure-integer crypto.
Fixed-width integer serializers into a raw uint8_t* buffer - one source of truth.
uint32_t pc_rd32le(const uint8_t *p)
Read a little-endian u32 at p.
size_t pc_wr32le(uint8_t *p, uint32_t v)
Write v little-endian at p.
void pc_md5_init(MdCtx *c)
#define R1(A, B, C, D, K, S)
void pc_md4_init(MdCtx *c)
void pc_md4_update(MdCtx *c, const uint8_t *data, size_t len)
MdCtx * pc_md_wants(void)
Storage this module wants for one MD4/MD5 context.
void pc_md5_update(MdCtx *c, const uint8_t *data, size_t len)
void pc_md5_final(MdCtx *c, uint8_t out[16])
void md4(const uint8_t *data, size_t len, uint8_t out[16])
One-shot MD4 (the NT-hash primitive).
#define R2(A, B, C, D, K, S)
#define R3(A, B, C, D, K, S)
void md5(const uint8_t *data, size_t len, uint8_t out[16])
One-shot MD5.
void pc_md4_final(MdCtx *c, uint8_t out[16])
void(*)(uint32_t[4], const uint8_t[64]) md_compress_fn
void pc_hmac_md5(const uint8_t *key, size_t key_len, const uint8_t *msg, size_t msg_len, uint8_t out[16])
HMAC-MD5 (RFC 2104): the NTLMv2 MAC primitive.
MD4 (RFC 1320), MD5 (RFC 1321), and HMAC-MD5 (RFC 2104) - the legacy digests NTLM needs.
pc_span pc_secure_span(size_t n, size_t align)
Borrow n secure bytes as a span whose capacity is bound to the allocation.
Secure pool accessor - borrows that hold key material.
bool pc_span_ok(const pc_span &s)
True when the span refers to real storage and every write so far has fit.
uint32_t buf_len
bytes currently in buf
uint64_t bits
total message length in bits
uint8_t buf[64]
partial block
A writable byte region: the storage, the capacity that belongs to it, and what has been produced into...
uint8_t * buf
first byte, or nullptr when the region could not be obtained