1/* This code illustrates a sample implementation
2 * of the Arcfour algorithm
3 * Copyright (c) April 29, 1997 Kalle Kaukonen.
4 * All Rights Reserved.
5 *
6 * Redistribution and use in source and binary forms, with or
7 * without modification, are permitted provided that this copyright
8 * notice and disclaimer are retained.
9 *
10 * THIS SOFTWARE IS PROVIDED BY KALLE KAUKONEN AND CONTRIBUTORS ``AS
11 * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
12 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
13 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALLE
14 * KAUKONEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
15 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
16 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
17 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
18 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
19 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
21 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22 */
23
24#include "mupdf/fitz.h"
25
26void
27fz_arc4_init(fz_arc4 *arc4, const unsigned char *key, size_t keylen)
28{
29 unsigned int t, u;
30 size_t keyindex;
31 unsigned int stateindex;
32 unsigned char *state;
33 unsigned int counter;
34
35 state = arc4->state;
36
37 arc4->x = 0;
38 arc4->y = 0;
39
40 for (counter = 0; counter < 256; counter++)
41 {
42 state[counter] = counter;
43 }
44
45 keyindex = 0;
46 stateindex = 0;
47
48 for (counter = 0; counter < 256; counter++)
49 {
50 t = state[counter];
51 stateindex = (stateindex + key[keyindex] + t) & 0xff;
52 u = state[stateindex];
53
54 state[stateindex] = t;
55 state[counter] = u;
56
57 if (++keyindex >= keylen)
58 {
59 keyindex = 0;
60 }
61 }
62}
63
64static unsigned char
65fz_arc4_next(fz_arc4 *arc4)
66{
67 unsigned int x;
68 unsigned int y;
69 unsigned int sx, sy;
70 unsigned char *state;
71
72 state = arc4->state;
73
74 x = (arc4->x + 1) & 0xff;
75 sx = state[x];
76 y = (sx + arc4->y) & 0xff;
77 sy = state[y];
78
79 arc4->x = x;
80 arc4->y = y;
81
82 state[y] = sx;
83 state[x] = sy;
84
85 return state[(sx + sy) & 0xff];
86}
87
88void
89fz_arc4_encrypt(fz_arc4 *arc4, unsigned char *dest, const unsigned char *src, size_t len)
90{
91 size_t i;
92 for (i = 0; i < len; i++)
93 {
94 unsigned char x;
95 x = fz_arc4_next(arc4);
96 dest[i] = src[i] ^ x;
97 }
98}
99