Coverage Report

Created: 2025-08-28 07:06

/src/ghostpdl/base/sarc4.c
Line
Count
Source (jump to first uncovered line)
1
/* Copyright (C) 2001-2023 Artifex Software, Inc.
2
   All Rights Reserved.
3
4
   This software is provided AS-IS with no warranty, either express or
5
   implied.
6
7
   This software is distributed under license and may not be copied,
8
   modified or distributed except as expressly authorized under the terms
9
   of the license contained in the file LICENSE in this distribution.
10
11
   Refer to licensing information at http://www.artifex.com or contact
12
   Artifex Software, Inc.,  39 Mesa Street, Suite 108A, San Francisco,
13
   CA 94129, USA, for further information.
14
*/
15
16
17
18
/* Arcfour cipher and filter implementation */
19
20
#include "memory_.h"
21
#include "gserrors.h"
22
#include "strimpl.h"
23
#include "sarc4.h"
24
25
/* This is an independent implementation of the symmetric block
26
 * cipher commonly known as 'arcfour' based on Bruce Schneier's
27
 * description of the algorithm in _Applied Cryptography_. Arcfour
28
 * is believed to be functionally equivalent to the RC4(tm) cipher
29
 * mentioned in the PDF specification. (RC4 is a registered
30
 * trademark of RSA Data Security, Inc.)
31
 */
32
33
/* stream implementation */
34
35
private_st_arcfour_state(); /* creates a gc object for our state, defined in sarc4.h */
36
37
/* initialize the S box using the given key */
38
int
39
s_arcfour_set_key(stream_arcfour_state * state, const unsigned char *key,
40
                  int keylength)
41
19.0k
{
42
19.0k
    unsigned int x, y;
43
19.0k
    unsigned char s, *S = state->S;
44
45
19.0k
    if (keylength < 1)
46
0
        return_error(gs_error_rangecheck);
47
48
    /* initialize to eponymous values */
49
4.88M
    for (x = 0; x < 256; x++)
50
4.86M
        S[x] = x;
51
52
    /* scramble based on the key */
53
19.0k
    y = 0;
54
4.88M
    for (x = 0; x < 256; x++) {
55
4.86M
        y = (y + S[x] + key[x % keylength]) & 0xFF;
56
4.86M
        s = S[x];
57
4.86M
        S[x] = S[y];
58
4.86M
        S[y] = s;
59
4.86M
    }
60
61
    /* initialize the indicies */
62
19.0k
    state->x = 0;
63
19.0k
    state->y = 0;
64
65
    /* return successfully */
66
19.0k
    return 0;
67
19.0k
}
68
69
/* (de)crypt a section of text--the procedure is the same
70
 * in each direction. see strimpl.h for return codes.
71
 */
72
static int
73
s_arcfour_process(stream_state * ss, stream_cursor_read * pr,
74
                  stream_cursor_write * pw, bool last)
75
43.3k
{
76
43.3k
    stream_arcfour_state *const state = (stream_arcfour_state *) ss;
77
43.3k
    unsigned int x = state->x;
78
43.3k
    unsigned int y = state->y;
79
43.3k
    unsigned char s, *S = state->S;
80
43.3k
    unsigned char z;
81
43.3k
   const unsigned char *limit;
82
43.3k
    int status;
83
84
    /* figure out if we're going to run out of space */
85
43.3k
    if ((pr->limit - pr->ptr) > (pw->limit - pw->ptr)) {
86
11.1k
        limit = pr->ptr + (pw->limit - pw->ptr);
87
11.1k
        status = 1;
88
32.2k
    } else {
89
32.2k
        limit = pr->limit;
90
32.2k
        status = last ? EOFC : 0;
91
32.2k
    }
92
    /* generate a pseudorandom byte stream and xor it with the input */
93
25.0M
    while (pr->ptr < limit) {
94
25.0M
        x = (x + 1) & 0xFF;
95
25.0M
        y = (y + S[x]) & 0xFF;
96
25.0M
        s = S[x];
97
25.0M
        S[x] = S[y];
98
25.0M
        S[y] = s;
99
25.0M
        z = S[(S[x] + S[y]) & 0xFF];
100
101
25.0M
        *++pw->ptr = (*++pr->ptr) ^ z;
102
25.0M
    }
103
    /* save state */
104
43.3k
    state->x = x;
105
43.3k
    state->y = y;
106
107
43.3k
    return status;
108
43.3k
}
109
110
/* stream template */
111
const stream_template s_arcfour_template = {
112
    &st_arcfour_state, NULL, s_arcfour_process, 1, 1
113
};
114
115
/* (de)crypt a section of text in a buffer -- the procedure is the same
116
 * in each direction. see strimpl.h for return codes.
117
 */
118
int
119
s_arcfour_process_buffer(stream_arcfour_state *ss, byte *buf, int buf_size)
120
0
{
121
0
    stream_cursor_read r;
122
0
    stream_cursor_write w;
123
0
    const bool unused = false;
124
125
0
    r.ptr = w.ptr = buf - 1;
126
0
    r.limit = w.limit = buf - 1 + buf_size;
127
0
    return s_arcfour_process((stream_state *)ss, &r, &w, unused);
128
0
}