File Coverage

/usr/local/lib/perl5/site_perl/5.42.0/x86_64-linux/Horus/include/horus_sha1.h
Criterion Covered Total %
statement 72 72 100.0
branch 25 26 96.1
condition n/a
subroutine n/a
pod n/a
total 97 98 98.9


line stmt bran cond sub pod time code
1             #ifndef HORUS_SHA1_H
2             #define HORUS_SHA1_H
3              
4             /*
5             * horus_sha1.h - Minimal embedded SHA-1 implementation (RFC 3174)
6             *
7             * Self-contained, no external dependencies. All functions static
8             * to avoid symbol conflicts with system SHA1.
9             */
10              
11             #include
12             #include
13              
14             typedef struct {
15             uint32_t state[5];
16             uint64_t count;
17             unsigned char buffer[64];
18             } horus_sha1_ctx;
19              
20             #define HORUS_SHA1_ROTL(x, n) (((x) << (n)) | ((x) >> (32 - (n))))
21              
22 313744           static inline uint32_t horus_sha1_decode32be(const unsigned char *p) {
23 313744           return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16)
24 313744           | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
25             }
26              
27 19609           static void horus_sha1_transform(uint32_t state[5], const unsigned char block[64]) {
28             uint32_t W[80];
29             uint32_t a, b, c, d, e;
30             int t;
31              
32 333353 100         for (t = 0; t < 16; t++)
33 313744           W[t] = horus_sha1_decode32be(block + t * 4);
34 1274585 100         for (t = 16; t < 80; t++)
35 1254976           W[t] = HORUS_SHA1_ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
36              
37 19609           a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4];
38              
39 411789 100         for (t = 0; t < 20; t++) {
40 392180           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + ((b & c) | ((~b) & d))
41 392180           + e + W[t] + 0x5A827999;
42 392180           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
43             }
44 411789 100         for (t = 20; t < 40; t++) {
45 392180           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + (b ^ c ^ d)
46 392180           + e + W[t] + 0x6ED9EBA1;
47 392180           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
48             }
49 411789 100         for (t = 40; t < 60; t++) {
50 392180           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + ((b & c) | (b & d) | (c & d))
51 392180           + e + W[t] + 0x8F1BBCDC;
52 392180           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
53             }
54 411789 100         for (t = 60; t < 80; t++) {
55 392180           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + (b ^ c ^ d)
56 392180           + e + W[t] + 0xCA62C1D6;
57 392180           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
58             }
59              
60 19609           state[0] += a;
61 19609           state[1] += b;
62 19609           state[2] += c;
63 19609           state[3] += d;
64 19609           state[4] += e;
65 19609           }
66              
67 61           static inline void horus_sha1_init(horus_sha1_ctx *ctx) {
68 61           ctx->count = 0;
69 61           ctx->state[0] = 0x67452301;
70 61           ctx->state[1] = 0xEFCDAB89;
71 61           ctx->state[2] = 0x98BADCFE;
72 61           ctx->state[3] = 0x10325476;
73 61           ctx->state[4] = 0xC3D2E1F0;
74 61           }
75              
76 251           static inline void horus_sha1_update(horus_sha1_ctx *ctx,
77             const unsigned char *data, size_t len) {
78 251           size_t index = (size_t)(ctx->count & 0x3F);
79 251           ctx->count += len;
80              
81 251 100         if (index) {
82 190           size_t part_len = 64 - index;
83 190 100         if (len >= part_len) {
84 75           memcpy(ctx->buffer + index, data, part_len);
85 75           horus_sha1_transform(ctx->state, ctx->buffer);
86 75           data += part_len;
87 75           len -= part_len;
88             } else {
89 115           memcpy(ctx->buffer + index, data, len);
90 115           return;
91             }
92             }
93              
94 19670 100         while (len >= 64) {
95 19534           horus_sha1_transform(ctx->state, data);
96 19534           data += 64;
97 19534           len -= 64;
98             }
99              
100 136 100         if (len)
101 75           memcpy(ctx->buffer, data, len);
102             }
103              
104 61           static inline void horus_sha1_final(unsigned char digest[20], horus_sha1_ctx *ctx) {
105             unsigned char padding[64];
106             unsigned char bits[8];
107 61           uint64_t bit_count = ctx->count << 3;
108             size_t index;
109             int i;
110              
111 61           memset(padding, 0, sizeof(padding));
112 61           padding[0] = 0x80;
113              
114             /* Encode bit count as big-endian */
115 549 100         for (i = 0; i < 8; i++)
116 488           bits[7 - i] = (unsigned char)(bit_count >> (i * 8));
117              
118             /* Pad to 56 mod 64 */
119 61           index = (size_t)(ctx->count & 0x3F);
120 61 50         horus_sha1_update(ctx, padding, (index < 56) ? (56 - index) : (120 - index));
121              
122             /* Append length */
123 61           horus_sha1_update(ctx, bits, 8);
124              
125             /* Encode state as big-endian */
126 366 100         for (i = 0; i < 5; i++) {
127 305           digest[i*4 + 0] = (unsigned char)(ctx->state[i] >> 24);
128 305           digest[i*4 + 1] = (unsigned char)(ctx->state[i] >> 16);
129 305           digest[i*4 + 2] = (unsigned char)(ctx->state[i] >> 8);
130 305           digest[i*4 + 3] = (unsigned char)(ctx->state[i]);
131             }
132 61           }
133              
134             /* Convenience: hash data in one shot */
135             static inline void horus_sha1(unsigned char digest[20],
136             const unsigned char *data, size_t len) {
137             horus_sha1_ctx ctx;
138             horus_sha1_init(&ctx);
139             horus_sha1_update(&ctx, data, len);
140             horus_sha1_final(digest, &ctx);
141             }
142              
143             #endif /* HORUS_SHA1_H */