File Coverage

src/pdfmake_rc4.c
Criterion Covered Total %
statement 31 31 100.0
branch 6 6 100.0
condition n/a
subroutine n/a
pod n/a
total 37 37 100.0


line stmt bran cond sub pod time code
1             /*
2             * pdfmake_rc4.c — RC4 stream cipher implementation
3             *
4             * Standard RC4 (ARC4) for PDF encryption R2/R3.
5             */
6              
7             #include "pdfmake_rc4.h"
8             #include
9              
10             /*============================================================================
11             * RC4 Key Scheduling Algorithm (KSA)
12             *==========================================================================*/
13              
14 1115           void pdfmake_rc4_init(pdfmake_rc4_ctx_t *ctx, const uint8_t *key, size_t key_len)
15             {
16             int i;
17             uint8_t j;
18              
19             /* Initialize identity permutation */
20 286555 100         for (i = 0; i < 256; i++) {
21 285440           ctx->S[i] = (uint8_t)i;
22             }
23              
24             /* Key scheduling */
25 1115           j = 0;
26 286555 100         for (i = 0; i < 256; i++) {
27             uint8_t tmp;
28 285440           j = j + ctx->S[i] + key[i % key_len];
29             /* Swap S[i] and S[j] */
30 285440           tmp = ctx->S[i];
31 285440           ctx->S[i] = ctx->S[j];
32 285440           ctx->S[j] = tmp;
33             }
34              
35 1115           ctx->i = 0;
36 1115           ctx->j = 0;
37 1115           }
38              
39             /*============================================================================
40             * RC4 Pseudo-Random Generation Algorithm (PRGA)
41             *==========================================================================*/
42              
43 1115           void pdfmake_rc4_crypt(pdfmake_rc4_ctx_t *ctx, uint8_t *data, size_t len)
44             {
45 1115           uint8_t i = ctx->i;
46 1115           uint8_t j = ctx->j;
47 1115           uint8_t *S = ctx->S;
48             size_t n;
49              
50 410101 100         for (n = 0; n < len; n++) {
51             uint8_t tmp;
52             uint8_t k;
53 408986           i++;
54 408986           j = j + S[i];
55              
56             /* Swap S[i] and S[j] */
57 408986           tmp = S[i];
58 408986           S[i] = S[j];
59 408986           S[j] = tmp;
60              
61             /* Generate keystream byte and XOR with data */
62 408986           k = S[(S[i] + S[j]) & 0xFF];
63 408986           data[n] ^= k;
64             }
65              
66 1115           ctx->i = i;
67 1115           ctx->j = j;
68 1115           }
69              
70             /*============================================================================
71             * One-shot convenience function
72             *==========================================================================*/
73              
74 1115           void pdfmake_rc4(const uint8_t *key, size_t key_len, uint8_t *data, size_t data_len)
75             {
76             pdfmake_rc4_ctx_t ctx;
77 1115           pdfmake_rc4_init(&ctx, key, key_len);
78 1115           pdfmake_rc4_crypt(&ctx, data, data_len);
79 1115           }