File Coverage

/usr/local/lib/perl5/site_perl/5.42.0/x86_64-linux/Horus/include/horus_sha1.h
Criterion Covered Total %
statement 0 31 0.0
branch 0 12 0.0
condition n/a
subroutine n/a
pod n/a
total 0 43 0.0


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 0           static inline uint32_t horus_sha1_decode32be(const unsigned char *p) {
23 0           return ((uint32_t)p[0] << 24) | ((uint32_t)p[1] << 16)
24 0           | ((uint32_t)p[2] << 8) | (uint32_t)p[3];
25             }
26              
27 0           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 0 0         for (t = 0; t < 16; t++)
33 0           W[t] = horus_sha1_decode32be(block + t * 4);
34 0 0         for (t = 16; t < 80; t++)
35 0           W[t] = HORUS_SHA1_ROTL(W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16], 1);
36              
37 0           a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4];
38              
39 0 0         for (t = 0; t < 20; t++) {
40 0           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + ((b & c) | ((~b) & d))
41 0           + e + W[t] + 0x5A827999;
42 0           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
43             }
44 0 0         for (t = 20; t < 40; t++) {
45 0           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + (b ^ c ^ d)
46 0           + e + W[t] + 0x6ED9EBA1;
47 0           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
48             }
49 0 0         for (t = 40; t < 60; t++) {
50 0           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + ((b & c) | (b & d) | (c & d))
51 0           + e + W[t] + 0x8F1BBCDC;
52 0           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
53             }
54 0 0         for (t = 60; t < 80; t++) {
55 0           uint32_t tmp = HORUS_SHA1_ROTL(a, 5) + (b ^ c ^ d)
56 0           + e + W[t] + 0xCA62C1D6;
57 0           e = d; d = c; c = HORUS_SHA1_ROTL(b, 30); b = a; a = tmp;
58             }
59              
60 0           state[0] += a;
61 0           state[1] += b;
62 0           state[2] += c;
63 0           state[3] += d;
64 0           state[4] += e;
65 0           }
66              
67             static inline void horus_sha1_init(horus_sha1_ctx *ctx) {
68             ctx->count = 0;
69             ctx->state[0] = 0x67452301;
70             ctx->state[1] = 0xEFCDAB89;
71             ctx->state[2] = 0x98BADCFE;
72             ctx->state[3] = 0x10325476;
73             ctx->state[4] = 0xC3D2E1F0;
74             }
75              
76             static inline void horus_sha1_update(horus_sha1_ctx *ctx,
77             const unsigned char *data, size_t len) {
78             size_t index = (size_t)(ctx->count & 0x3F);
79             ctx->count += len;
80              
81             if (index) {
82             size_t part_len = 64 - index;
83             if (len >= part_len) {
84             memcpy(ctx->buffer + index, data, part_len);
85             horus_sha1_transform(ctx->state, ctx->buffer);
86             data += part_len;
87             len -= part_len;
88             } else {
89             memcpy(ctx->buffer + index, data, len);
90             return;
91             }
92             }
93              
94             while (len >= 64) {
95             horus_sha1_transform(ctx->state, data);
96             data += 64;
97             len -= 64;
98             }
99              
100             if (len)
101             memcpy(ctx->buffer, data, len);
102             }
103              
104             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             uint64_t bit_count = ctx->count << 3;
108             size_t index;
109             int i;
110              
111             memset(padding, 0, sizeof(padding));
112             padding[0] = 0x80;
113              
114             /* Encode bit count as big-endian */
115             for (i = 0; i < 8; i++)
116             bits[7 - i] = (unsigned char)(bit_count >> (i * 8));
117              
118             /* Pad to 56 mod 64 */
119             index = (size_t)(ctx->count & 0x3F);
120             horus_sha1_update(ctx, padding, (index < 56) ? (56 - index) : (120 - index));
121              
122             /* Append length */
123             horus_sha1_update(ctx, bits, 8);
124              
125             /* Encode state as big-endian */
126             for (i = 0; i < 5; i++) {
127             digest[i*4 + 0] = (unsigned char)(ctx->state[i] >> 24);
128             digest[i*4 + 1] = (unsigned char)(ctx->state[i] >> 16);
129             digest[i*4 + 2] = (unsigned char)(ctx->state[i] >> 8);
130             digest[i*4 + 3] = (unsigned char)(ctx->state[i]);
131             }
132             }
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 */