File Coverage

/usr/local/lib/perl5/site_perl/5.42.0/x86_64-linux/Horus/include/horus_md5.h
Criterion Covered Total %
statement 0 76 0.0
branch 0 2 0.0
condition n/a
subroutine n/a
pod n/a
total 0 78 0.0


line stmt bran cond sub pod time code
1             #ifndef HORUS_MD5_H
2             #define HORUS_MD5_H
3              
4             /*
5             * horus_md5.h - Minimal embedded MD5 implementation (RFC 1321)
6             *
7             * Self-contained, no external dependencies. All functions static
8             * to avoid symbol conflicts with system MD5.
9             */
10              
11             #include
12             #include
13              
14             typedef struct {
15             uint32_t state[4];
16             uint64_t count;
17             unsigned char buffer[64];
18             } horus_md5_ctx;
19              
20             #define HORUS_MD5_F(x, y, z) (((x) & (y)) | ((~(x)) & (z)))
21             #define HORUS_MD5_G(x, y, z) (((x) & (z)) | ((y) & (~(z))))
22             #define HORUS_MD5_HH(x, y, z) ((x) ^ (y) ^ (z))
23             #define HORUS_MD5_I(x, y, z) ((y) ^ ((x) | (~(z))))
24             #define HORUS_MD5_ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
25              
26             #define HORUS_MD5_STEP(f, a, b, c, d, x, t, s) \
27             (a) += f((b), (c), (d)) + (x) + (t); \
28             (a) = HORUS_MD5_ROTL((a), (s)); \
29             (a) += (b)
30              
31 0           static inline uint32_t horus_md5_decode32(const unsigned char *p) {
32 0           return (uint32_t)p[0] | ((uint32_t)p[1] << 8)
33 0           | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24);
34             }
35              
36 0           static void horus_md5_transform(uint32_t state[4], const unsigned char block[64]) {
37 0           uint32_t a = state[0], b = state[1], c = state[2], d = state[3];
38             uint32_t M[16];
39             int i;
40              
41 0 0         for (i = 0; i < 16; i++)
42 0           M[i] = horus_md5_decode32(block + i * 4);
43              
44             /* Round 1 */
45 0           HORUS_MD5_STEP(HORUS_MD5_F, a, b, c, d, M[ 0], 0xd76aa478, 7);
46 0           HORUS_MD5_STEP(HORUS_MD5_F, d, a, b, c, M[ 1], 0xe8c7b756, 12);
47 0           HORUS_MD5_STEP(HORUS_MD5_F, c, d, a, b, M[ 2], 0x242070db, 17);
48 0           HORUS_MD5_STEP(HORUS_MD5_F, b, c, d, a, M[ 3], 0xc1bdceee, 22);
49 0           HORUS_MD5_STEP(HORUS_MD5_F, a, b, c, d, M[ 4], 0xf57c0faf, 7);
50 0           HORUS_MD5_STEP(HORUS_MD5_F, d, a, b, c, M[ 5], 0x4787c62a, 12);
51 0           HORUS_MD5_STEP(HORUS_MD5_F, c, d, a, b, M[ 6], 0xa8304613, 17);
52 0           HORUS_MD5_STEP(HORUS_MD5_F, b, c, d, a, M[ 7], 0xfd469501, 22);
53 0           HORUS_MD5_STEP(HORUS_MD5_F, a, b, c, d, M[ 8], 0x698098d8, 7);
54 0           HORUS_MD5_STEP(HORUS_MD5_F, d, a, b, c, M[ 9], 0x8b44f7af, 12);
55 0           HORUS_MD5_STEP(HORUS_MD5_F, c, d, a, b, M[10], 0xffff5bb1, 17);
56 0           HORUS_MD5_STEP(HORUS_MD5_F, b, c, d, a, M[11], 0x895cd7be, 22);
57 0           HORUS_MD5_STEP(HORUS_MD5_F, a, b, c, d, M[12], 0x6b901122, 7);
58 0           HORUS_MD5_STEP(HORUS_MD5_F, d, a, b, c, M[13], 0xfd987193, 12);
59 0           HORUS_MD5_STEP(HORUS_MD5_F, c, d, a, b, M[14], 0xa679438e, 17);
60 0           HORUS_MD5_STEP(HORUS_MD5_F, b, c, d, a, M[15], 0x49b40821, 22);
61              
62             /* Round 2 */
63 0           HORUS_MD5_STEP(HORUS_MD5_G, a, b, c, d, M[ 1], 0xf61e2562, 5);
64 0           HORUS_MD5_STEP(HORUS_MD5_G, d, a, b, c, M[ 6], 0xc040b340, 9);
65 0           HORUS_MD5_STEP(HORUS_MD5_G, c, d, a, b, M[11], 0x265e5a51, 14);
66 0           HORUS_MD5_STEP(HORUS_MD5_G, b, c, d, a, M[ 0], 0xe9b6c7aa, 20);
67 0           HORUS_MD5_STEP(HORUS_MD5_G, a, b, c, d, M[ 5], 0xd62f105d, 5);
68 0           HORUS_MD5_STEP(HORUS_MD5_G, d, a, b, c, M[10], 0x02441453, 9);
69 0           HORUS_MD5_STEP(HORUS_MD5_G, c, d, a, b, M[15], 0xd8a1e681, 14);
70 0           HORUS_MD5_STEP(HORUS_MD5_G, b, c, d, a, M[ 4], 0xe7d3fbc8, 20);
71 0           HORUS_MD5_STEP(HORUS_MD5_G, a, b, c, d, M[ 9], 0x21e1cde6, 5);
72 0           HORUS_MD5_STEP(HORUS_MD5_G, d, a, b, c, M[14], 0xc33707d6, 9);
73 0           HORUS_MD5_STEP(HORUS_MD5_G, c, d, a, b, M[ 3], 0xf4d50d87, 14);
74 0           HORUS_MD5_STEP(HORUS_MD5_G, b, c, d, a, M[ 8], 0x455a14ed, 20);
75 0           HORUS_MD5_STEP(HORUS_MD5_G, a, b, c, d, M[13], 0xa9e3e905, 5);
76 0           HORUS_MD5_STEP(HORUS_MD5_G, d, a, b, c, M[ 2], 0xfcefa3f8, 9);
77 0           HORUS_MD5_STEP(HORUS_MD5_G, c, d, a, b, M[ 7], 0x676f02d9, 14);
78 0           HORUS_MD5_STEP(HORUS_MD5_G, b, c, d, a, M[12], 0x8d2a4c8a, 20);
79              
80             /* Round 3 */
81 0           HORUS_MD5_STEP(HORUS_MD5_HH, a, b, c, d, M[ 5], 0xfffa3942, 4);
82 0           HORUS_MD5_STEP(HORUS_MD5_HH, d, a, b, c, M[ 8], 0x8771f681, 11);
83 0           HORUS_MD5_STEP(HORUS_MD5_HH, c, d, a, b, M[11], 0x6d9d6122, 16);
84 0           HORUS_MD5_STEP(HORUS_MD5_HH, b, c, d, a, M[14], 0xfde5380c, 23);
85 0           HORUS_MD5_STEP(HORUS_MD5_HH, a, b, c, d, M[ 1], 0xa4beea44, 4);
86 0           HORUS_MD5_STEP(HORUS_MD5_HH, d, a, b, c, M[ 4], 0x4bdecfa9, 11);
87 0           HORUS_MD5_STEP(HORUS_MD5_HH, c, d, a, b, M[ 7], 0xf6bb4b60, 16);
88 0           HORUS_MD5_STEP(HORUS_MD5_HH, b, c, d, a, M[10], 0xbebfbc70, 23);
89 0           HORUS_MD5_STEP(HORUS_MD5_HH, a, b, c, d, M[13], 0x289b7ec6, 4);
90 0           HORUS_MD5_STEP(HORUS_MD5_HH, d, a, b, c, M[ 0], 0xeaa127fa, 11);
91 0           HORUS_MD5_STEP(HORUS_MD5_HH, c, d, a, b, M[ 3], 0xd4ef3085, 16);
92 0           HORUS_MD5_STEP(HORUS_MD5_HH, b, c, d, a, M[ 6], 0x04881d05, 23);
93 0           HORUS_MD5_STEP(HORUS_MD5_HH, a, b, c, d, M[ 9], 0xd9d4d039, 4);
94 0           HORUS_MD5_STEP(HORUS_MD5_HH, d, a, b, c, M[12], 0xe6db99e5, 11);
95 0           HORUS_MD5_STEP(HORUS_MD5_HH, c, d, a, b, M[15], 0x1fa27cf8, 16);
96 0           HORUS_MD5_STEP(HORUS_MD5_HH, b, c, d, a, M[ 2], 0xc4ac5665, 23);
97              
98             /* Round 4 */
99 0           HORUS_MD5_STEP(HORUS_MD5_I, a, b, c, d, M[ 0], 0xf4292244, 6);
100 0           HORUS_MD5_STEP(HORUS_MD5_I, d, a, b, c, M[ 7], 0x432aff97, 10);
101 0           HORUS_MD5_STEP(HORUS_MD5_I, c, d, a, b, M[14], 0xab9423a7, 15);
102 0           HORUS_MD5_STEP(HORUS_MD5_I, b, c, d, a, M[ 5], 0xfc93a039, 21);
103 0           HORUS_MD5_STEP(HORUS_MD5_I, a, b, c, d, M[12], 0x655b59c3, 6);
104 0           HORUS_MD5_STEP(HORUS_MD5_I, d, a, b, c, M[ 3], 0x8f0ccc92, 10);
105 0           HORUS_MD5_STEP(HORUS_MD5_I, c, d, a, b, M[10], 0xffeff47d, 15);
106 0           HORUS_MD5_STEP(HORUS_MD5_I, b, c, d, a, M[ 1], 0x85845dd1, 21);
107 0           HORUS_MD5_STEP(HORUS_MD5_I, a, b, c, d, M[ 8], 0x6fa87e4f, 6);
108 0           HORUS_MD5_STEP(HORUS_MD5_I, d, a, b, c, M[15], 0xfe2ce6e0, 10);
109 0           HORUS_MD5_STEP(HORUS_MD5_I, c, d, a, b, M[ 6], 0xa3014314, 15);
110 0           HORUS_MD5_STEP(HORUS_MD5_I, b, c, d, a, M[13], 0x4e0811a1, 21);
111 0           HORUS_MD5_STEP(HORUS_MD5_I, a, b, c, d, M[ 4], 0xf7537e82, 6);
112 0           HORUS_MD5_STEP(HORUS_MD5_I, d, a, b, c, M[11], 0xbd3af235, 10);
113 0           HORUS_MD5_STEP(HORUS_MD5_I, c, d, a, b, M[ 2], 0x2ad7d2bb, 15);
114 0           HORUS_MD5_STEP(HORUS_MD5_I, b, c, d, a, M[ 9], 0xeb86d391, 21);
115              
116 0           state[0] += a;
117 0           state[1] += b;
118 0           state[2] += c;
119 0           state[3] += d;
120 0           }
121              
122             static inline void horus_md5_init(horus_md5_ctx *ctx) {
123             ctx->count = 0;
124             ctx->state[0] = 0x67452301;
125             ctx->state[1] = 0xefcdab89;
126             ctx->state[2] = 0x98badcfe;
127             ctx->state[3] = 0x10325476;
128             }
129              
130             static inline void horus_md5_update(horus_md5_ctx *ctx,
131             const unsigned char *data, size_t len) {
132             size_t index = (size_t)(ctx->count & 0x3F);
133             ctx->count += len;
134              
135             if (index) {
136             size_t part_len = 64 - index;
137             if (len >= part_len) {
138             memcpy(ctx->buffer + index, data, part_len);
139             horus_md5_transform(ctx->state, ctx->buffer);
140             data += part_len;
141             len -= part_len;
142             } else {
143             memcpy(ctx->buffer + index, data, len);
144             return;
145             }
146             }
147              
148             while (len >= 64) {
149             horus_md5_transform(ctx->state, data);
150             data += 64;
151             len -= 64;
152             }
153              
154             if (len)
155             memcpy(ctx->buffer, data, len);
156             }
157              
158             static inline void horus_md5_final(unsigned char digest[16], horus_md5_ctx *ctx) {
159             static const unsigned char padding[64] = { 0x80 };
160             unsigned char bits[8];
161             uint64_t bit_count = ctx->count << 3;
162             size_t index;
163             int i;
164              
165             /* Encode bit count as little-endian */
166             for (i = 0; i < 8; i++)
167             bits[i] = (unsigned char)(bit_count >> (i * 8));
168              
169             /* Pad to 56 mod 64 */
170             index = (size_t)(ctx->count & 0x3F);
171             horus_md5_update(ctx, padding, (index < 56) ? (56 - index) : (120 - index));
172              
173             /* Append length */
174             horus_md5_update(ctx, bits, 8);
175              
176             /* Encode state as little-endian */
177             for (i = 0; i < 4; i++) {
178             digest[i*4 + 0] = (unsigned char)(ctx->state[i]);
179             digest[i*4 + 1] = (unsigned char)(ctx->state[i] >> 8);
180             digest[i*4 + 2] = (unsigned char)(ctx->state[i] >> 16);
181             digest[i*4 + 3] = (unsigned char)(ctx->state[i] >> 24);
182             }
183             }
184              
185             /* Convenience: hash data in one shot */
186             static inline void horus_md5(unsigned char digest[16],
187             const unsigned char *data, size_t len) {
188             horus_md5_ctx ctx;
189             horus_md5_init(&ctx);
190             horus_md5_update(&ctx, data, len);
191             horus_md5_final(digest, &ctx);
192             }
193              
194             #endif /* HORUS_MD5_H */