File Coverage

src/pdfmake_sha2.c
Criterion Covered Total %
statement 139 140 99.2
branch 36 38 94.7
condition n/a
subroutine n/a
pod n/a
total 175 178 98.3


line stmt bran cond sub pod time code
1             /*
2             * pdfmake_sha2.c — SHA-256, SHA-384, SHA-512 implementations
3             *
4             * Reference implementation per FIPS 180-4.
5             * Required for PDF encryption R6 key derivation.
6             */
7              
8             #include "pdfmake_sha2.h"
9             #include "pdfmake_internal.h"
10             #include
11              
12             /*============================================================================
13             * SHA-256 constants
14             *==========================================================================*/
15              
16             static const uint32_t SHA256_K[64] = {
17             0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
18             0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
19             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
20             0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
21             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
22             0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
23             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
24             0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
25             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
26             0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
27             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
28             0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
29             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
30             0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
31             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
32             0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
33             };
34              
35             static const uint32_t SHA256_H0[8] = {
36             0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
37             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
38             };
39              
40             /*============================================================================
41             * SHA-512 constants
42             *==========================================================================*/
43              
44             static const uint64_t SHA512_K[80] = {
45             0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
46             0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
47             0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
48             0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
49             0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
50             0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
51             0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
52             0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
53             0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
54             0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
55             0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
56             0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
57             0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
58             0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
59             0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
60             0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
61             0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
62             0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
63             0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
64             0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
65             };
66              
67             static const uint64_t SHA512_H0[8] = {
68             0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL, 0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
69             0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL, 0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
70             };
71              
72             static const uint64_t SHA384_H0[8] = {
73             0xcbbb9d5dc1059ed8ULL, 0x629a292a367cd507ULL, 0x9159015a3070dd17ULL, 0x152fecd8f70e5939ULL,
74             0x67332667ffc00b31ULL, 0x8eb44a8768581511ULL, 0xdb0c2e0d64f98fa7ULL, 0x47b5481dbefa4fa4ULL
75             };
76              
77             /*============================================================================
78             * Helper macros - 32-bit
79             *==========================================================================*/
80              
81             #define ROTR32(x, n) (((x) >> (n)) | ((x) << (32 - (n))))
82             #define SHR32(x, n) ((x) >> (n))
83              
84             #define CH32(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
85             #define MAJ32(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
86              
87             #define SIGMA0_256(x) (ROTR32(x, 2) ^ ROTR32(x, 13) ^ ROTR32(x, 22))
88             #define SIGMA1_256(x) (ROTR32(x, 6) ^ ROTR32(x, 11) ^ ROTR32(x, 25))
89             #define sigma0_256(x) (ROTR32(x, 7) ^ ROTR32(x, 18) ^ SHR32(x, 3))
90             #define sigma1_256(x) (ROTR32(x, 17) ^ ROTR32(x, 19) ^ SHR32(x, 10))
91              
92             /*============================================================================
93             * Helper macros - 64-bit
94             *==========================================================================*/
95              
96             #define ROTR64(x, n) (((x) >> (n)) | ((x) << (64 - (n))))
97             #define SHR64(x, n) ((x) >> (n))
98              
99             #define CH64(x, y, z) (((x) & (y)) ^ ((~(x)) & (z)))
100             #define MAJ64(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
101              
102             #define SIGMA0_512(x) (ROTR64(x, 28) ^ ROTR64(x, 34) ^ ROTR64(x, 39))
103             #define SIGMA1_512(x) (ROTR64(x, 14) ^ ROTR64(x, 18) ^ ROTR64(x, 41))
104             #define sigma0_512(x) (ROTR64(x, 1) ^ ROTR64(x, 8) ^ SHR64(x, 7))
105             #define sigma1_512(x) (ROTR64(x, 19) ^ ROTR64(x, 61) ^ SHR64(x, 6))
106              
107             /*============================================================================
108             * SHA-256 transform
109             *==========================================================================*/
110              
111 85811           static void sha256_transform(uint32_t state[8], const uint8_t block[64])
112             {
113             uint32_t W[64];
114             uint32_t a, b, c, d, e, f, g, h;
115             uint32_t T1, T2;
116             int t;
117              
118             /* Prepare message schedule */
119 1458787 100         for (t = 0; t < 16; t++) {
120 1372976           W[t] = pdfmake_read_be32(block + t * 4);
121             }
122 4204739 100         for (t = 16; t < 64; t++) {
123 4118928           W[t] = sigma1_256(W[t-2]) + W[t-7] + sigma0_256(W[t-15]) + W[t-16];
124             }
125            
126             /* Initialize working variables */
127 85811           a = state[0]; b = state[1]; c = state[2]; d = state[3];
128 85811           e = state[4]; f = state[5]; g = state[6]; h = state[7];
129            
130             /* 64 rounds */
131 5577715 100         for (t = 0; t < 64; t++) {
132 5491904           T1 = h + SIGMA1_256(e) + CH32(e, f, g) + SHA256_K[t] + W[t];
133 5491904           T2 = SIGMA0_256(a) + MAJ32(a, b, c);
134 5491904           h = g; g = f; f = e;
135 5491904           e = d + T1;
136 5491904           d = c; c = b; b = a;
137 5491904           a = T1 + T2;
138             }
139            
140 85811           state[0] += a; state[1] += b; state[2] += c; state[3] += d;
141 85811           state[4] += e; state[5] += f; state[6] += g; state[7] += h;
142 85811           }
143              
144             /*============================================================================
145             * SHA-256 public API
146             *==========================================================================*/
147              
148 1149           void pdfmake_sha256_init(pdfmake_sha256_ctx_t *ctx)
149             {
150 1149           memcpy(ctx->state, SHA256_H0, sizeof(SHA256_H0));
151 1149           ctx->count = 0;
152 1149           memset(ctx->buffer, 0, sizeof(ctx->buffer));
153 1149           }
154              
155 3520           void pdfmake_sha256_update(pdfmake_sha256_ctx_t *ctx, const uint8_t *data, size_t len)
156             {
157 3520           size_t buf_pos = (ctx->count / 8) % 64;
158 3520           ctx->count += (uint64_t)len * 8;
159            
160 3520 100         if (buf_pos > 0) {
161 1254           size_t space = 64 - buf_pos;
162 1254 100         if (len >= space) {
163 1173           memcpy(ctx->buffer + buf_pos, data, space);
164 1173           sha256_transform(ctx->state, ctx->buffer);
165 1173           data += space;
166 1173           len -= space;
167 1173           buf_pos = 0;
168             } else {
169 81           memcpy(ctx->buffer + buf_pos, data, len);
170 81           return;
171             }
172             }
173            
174 88077 100         while (len >= 64) {
175 84638           sha256_transform(ctx->state, data);
176 84638           data += 64;
177 84638           len -= 64;
178             }
179            
180 3439 100         if (len > 0) {
181 1173           memcpy(ctx->buffer, data, len);
182             }
183             }
184              
185 1149           void pdfmake_sha256_final(pdfmake_sha256_ctx_t *ctx, uint8_t digest[32])
186             {
187 1149           uint64_t bits = ctx->count;
188 1149           size_t buf_pos = (bits / 8) % 64;
189             uint8_t pad[64];
190             size_t pad_len;
191             uint8_t len_bytes[8];
192             int i;
193              
194 1149           memset(pad, 0, sizeof(pad));
195 1149           pad[0] = 0x80;
196              
197 1149 100         pad_len = (buf_pos < 56) ? (56 - buf_pos) : (120 - buf_pos);
198 1149           pdfmake_sha256_update(ctx, pad, pad_len);
199              
200 1149           pdfmake_write_be64(len_bytes, bits);
201 1149           pdfmake_sha256_update(ctx, len_bytes, 8);
202              
203 10341 100         for (i = 0; i < 8; i++) {
204 9192           pdfmake_write_be32(digest + i * 4, ctx->state[i]);
205             }
206 1149           }
207              
208 1100           void pdfmake_sha256(const uint8_t *data, size_t len, uint8_t digest[32])
209             {
210             pdfmake_sha256_ctx_t ctx;
211 1100           pdfmake_sha256_init(&ctx);
212 1100           pdfmake_sha256_update(&ctx, data, len);
213 1100           pdfmake_sha256_final(&ctx, digest);
214 1100           }
215              
216             /*============================================================================
217             * SHA-512 transform
218             *==========================================================================*/
219              
220 87764           static void sha512_transform(uint64_t state[8], const uint8_t block[128])
221             {
222             uint64_t W[80];
223             uint64_t a, b, c, d, e, f, g, h;
224             uint64_t T1, T2;
225             int t;
226              
227             /* Prepare message schedule */
228 1491988 100         for (t = 0; t < 16; t++) {
229 1404224           W[t] = pdfmake_read_be64(block + t * 8);
230             }
231 5704660 100         for (t = 16; t < 80; t++) {
232 5616896           W[t] = sigma1_512(W[t-2]) + W[t-7] + sigma0_512(W[t-15]) + W[t-16];
233             }
234            
235             /* Initialize working variables */
236 87764           a = state[0]; b = state[1]; c = state[2]; d = state[3];
237 87764           e = state[4]; f = state[5]; g = state[6]; h = state[7];
238            
239             /* 80 rounds */
240 7108884 100         for (t = 0; t < 80; t++) {
241 7021120           T1 = h + SIGMA1_512(e) + CH64(e, f, g) + SHA512_K[t] + W[t];
242 7021120           T2 = SIGMA0_512(a) + MAJ64(a, b, c);
243 7021120           h = g; g = f; f = e;
244 7021120           e = d + T1;
245 7021120           d = c; c = b; b = a;
246 7021120           a = T1 + T2;
247             }
248            
249 87764           state[0] += a; state[1] += b; state[2] += c; state[3] += d;
250 87764           state[4] += e; state[5] += f; state[6] += g; state[7] += h;
251 87764           }
252              
253             /*============================================================================
254             * SHA-512 public API
255             *==========================================================================*/
256              
257 1215           void pdfmake_sha512_init(pdfmake_sha512_ctx_t *ctx)
258             {
259 1215           memcpy(ctx->state, SHA512_H0, sizeof(SHA512_H0));
260 1215           ctx->count[0] = 0;
261 1215           ctx->count[1] = 0;
262 1215           memset(ctx->buffer, 0, sizeof(ctx->buffer));
263 1215           }
264              
265 6801           void pdfmake_sha512_update(pdfmake_sha512_ctx_t *ctx, const uint8_t *data, size_t len)
266             {
267 6801           size_t buf_pos = (size_t)(ctx->count[0] / 8) % 128;
268            
269             /* Update bit count */
270 6801           uint64_t add_bits = (uint64_t)len * 8;
271 6801           ctx->count[0] += add_bits;
272 6801 50         if (ctx->count[0] < add_bits) {
273 0           ctx->count[1]++; /* Carry */
274             }
275            
276 6801 100         if (buf_pos > 0) {
277 2708           size_t space = 128 - buf_pos;
278 2708 100         if (len >= space) {
279 2267           memcpy(ctx->buffer + buf_pos, data, space);
280 2267           sha512_transform(ctx->state, ctx->buffer);
281 2267           data += space;
282 2267           len -= space;
283 2267           buf_pos = 0;
284             } else {
285 441           memcpy(ctx->buffer + buf_pos, data, len);
286 441           return;
287             }
288             }
289            
290 91857 100         while (len >= 128) {
291 85497           sha512_transform(ctx->state, data);
292 85497           data += 128;
293 85497           len -= 128;
294             }
295            
296 6360 100         if (len > 0) {
297 2267           memcpy(ctx->buffer, data, len);
298             }
299             }
300              
301 2267           void pdfmake_sha512_final(pdfmake_sha512_ctx_t *ctx, uint8_t digest[64])
302             {
303             /* Snapshot the bit count BEFORE padding (update() will mutate it). */
304 2267           uint64_t bits_lo = ctx->count[0];
305 2267           uint64_t bits_hi = ctx->count[1];
306 2267           size_t buf_pos = (size_t)(bits_lo / 8) % 128;
307             uint8_t pad[128];
308             size_t pad_len;
309             uint8_t len_bytes[16];
310             int i;
311              
312 2267           memset(pad, 0, sizeof(pad));
313 2267           pad[0] = 0x80;
314              
315             /* Pad to 112 mod 128 bytes (leaving 16 bytes for 128-bit length) */
316 2267 50         pad_len = (buf_pos < 112) ? (112 - buf_pos) : (240 - buf_pos);
317 2267           pdfmake_sha512_update(ctx, pad, pad_len);
318              
319             /* Append 128-bit length (high 64 bits, then low 64 bits) */
320 2267           pdfmake_write_be64(len_bytes, bits_hi);
321 2267           pdfmake_write_be64(len_bytes + 8, bits_lo);
322 2267           pdfmake_sha512_update(ctx, len_bytes, 16);
323              
324 20403 100         for (i = 0; i < 8; i++) {
325 18136           pdfmake_write_be64(digest + i * 8, ctx->state[i]);
326             }
327 2267           }
328              
329 1215           void pdfmake_sha512(const uint8_t *data, size_t len, uint8_t digest[64])
330             {
331             pdfmake_sha512_ctx_t ctx;
332 1215           pdfmake_sha512_init(&ctx);
333 1215           pdfmake_sha512_update(&ctx, data, len);
334 1215           pdfmake_sha512_final(&ctx, digest);
335 1215           }
336              
337             /*============================================================================
338             * SHA-384 (SHA-512 with different IV and truncated output)
339             *==========================================================================*/
340              
341 1052           void pdfmake_sha384_init(pdfmake_sha384_ctx_t *ctx)
342             {
343 1052           memcpy(ctx->state, SHA384_H0, sizeof(SHA384_H0));
344 1052           ctx->count[0] = 0;
345 1052           ctx->count[1] = 0;
346 1052           memset(ctx->buffer, 0, sizeof(ctx->buffer));
347 1052           }
348              
349 1052           void pdfmake_sha384_update(pdfmake_sha384_ctx_t *ctx, const uint8_t *data, size_t len)
350             {
351             /* SHA-384 uses same update logic as SHA-512 */
352 1052           pdfmake_sha512_update((pdfmake_sha512_ctx_t *)ctx, data, len);
353 1052           }
354              
355 1052           void pdfmake_sha384_final(pdfmake_sha384_ctx_t *ctx, uint8_t digest[48])
356             {
357             uint8_t full_digest[64];
358 1052           pdfmake_sha512_final((pdfmake_sha512_ctx_t *)ctx, full_digest);
359 1052           memcpy(digest, full_digest, 48); /* Truncate to 384 bits */
360 1052           }
361              
362 1052           void pdfmake_sha384(const uint8_t *data, size_t len, uint8_t digest[48])
363             {
364             pdfmake_sha384_ctx_t ctx;
365 1052           pdfmake_sha384_init(&ctx);
366 1052           pdfmake_sha384_update(&ctx, data, len);
367 1052           pdfmake_sha384_final(&ctx, digest);
368 1052           }