1 | /*
|
---|
2 | * dlls/rsaenh/rc4.c
|
---|
3 | * RC4 functions
|
---|
4 | *
|
---|
5 | * Copyright 2004 Michael Jung
|
---|
6 | * Based on public domain code by Tom St Denis (tomstdenis@iahu.ca)
|
---|
7 | *
|
---|
8 | * This library is free software; you can redistribute it and/or
|
---|
9 | * modify it under the terms of the GNU Lesser General Public
|
---|
10 | * License as published by the Free Software Foundation; either
|
---|
11 | * version 2.1 of the License, or (at your option) any later version.
|
---|
12 | *
|
---|
13 | * This library is distributed in the hope that it will be useful,
|
---|
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
16 | * Lesser General Public License for more details.
|
---|
17 | *
|
---|
18 | * You should have received a copy of the GNU Lesser General Public
|
---|
19 | * License along with this library; if not, write to the Free Software
|
---|
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
---|
21 | */
|
---|
22 |
|
---|
23 | /*
|
---|
24 | * This file contains code from the LibTomCrypt cryptographic
|
---|
25 | * library written by Tom St Denis (tomstdenis@iahu.ca). LibTomCrypt
|
---|
26 | * is in the public domain. The code in this file is tailored to
|
---|
27 | * special requirements. Take a look at http://libtomcrypt.org for the
|
---|
28 | * original version.
|
---|
29 | */
|
---|
30 |
|
---|
31 | #include "tomcrypt.h"
|
---|
32 |
|
---|
33 | int rc4_start(prng_state *prng)
|
---|
34 | {
|
---|
35 | /* set keysize to zero */
|
---|
36 | prng->rc4.x = 0;
|
---|
37 |
|
---|
38 | return CRYPT_OK;
|
---|
39 | }
|
---|
40 |
|
---|
41 | int rc4_add_entropy(const unsigned char *buf, unsigned long len, prng_state *prng)
|
---|
42 | {
|
---|
43 | /* trim as required */
|
---|
44 | if (prng->rc4.x + len > 256) {
|
---|
45 | if (prng->rc4.x == 256) {
|
---|
46 | /* I can't possibly accept another byte, ok maybe a mint wafer... */
|
---|
47 | return CRYPT_OK;
|
---|
48 | } else {
|
---|
49 | /* only accept part of it */
|
---|
50 | len = 256 - prng->rc4.x;
|
---|
51 | }
|
---|
52 | }
|
---|
53 |
|
---|
54 | while (len--) {
|
---|
55 | prng->rc4.buf[prng->rc4.x++] = *buf++;
|
---|
56 | }
|
---|
57 |
|
---|
58 | return CRYPT_OK;
|
---|
59 | }
|
---|
60 |
|
---|
61 | int rc4_ready(prng_state *prng)
|
---|
62 | {
|
---|
63 | unsigned char key[256], tmp, *s;
|
---|
64 | int keylen, x, y, j;
|
---|
65 |
|
---|
66 | /* extract the key */
|
---|
67 | s = prng->rc4.buf;
|
---|
68 | memcpy(key, s, 256);
|
---|
69 | keylen = prng->rc4.x;
|
---|
70 |
|
---|
71 | /* make RC4 perm and shuffle */
|
---|
72 | for (x = 0; x < 256; x++) {
|
---|
73 | s[x] = x;
|
---|
74 | }
|
---|
75 |
|
---|
76 | for (j = x = y = 0; x < 256; x++) {
|
---|
77 | y = (y + prng->rc4.buf[x] + key[j++]) & 255;
|
---|
78 | if (j == keylen) {
|
---|
79 | j = 0;
|
---|
80 | }
|
---|
81 | tmp = s[x]; s[x] = s[y]; s[y] = tmp;
|
---|
82 | }
|
---|
83 | prng->rc4.x = 0;
|
---|
84 | prng->rc4.y = 0;
|
---|
85 |
|
---|
86 | return CRYPT_OK;
|
---|
87 | }
|
---|
88 |
|
---|
89 | unsigned long rc4_read(unsigned char *buf, unsigned long len, prng_state *prng)
|
---|
90 | {
|
---|
91 | unsigned char x, y, *s, tmp;
|
---|
92 | unsigned long n;
|
---|
93 |
|
---|
94 | n = len;
|
---|
95 | x = prng->rc4.x;
|
---|
96 | y = prng->rc4.y;
|
---|
97 | s = prng->rc4.buf;
|
---|
98 | while (len--) {
|
---|
99 | x = (x + 1) & 255;
|
---|
100 | y = (y + s[x]) & 255;
|
---|
101 | tmp = s[x]; s[x] = s[y]; s[y] = tmp;
|
---|
102 | tmp = (s[x] + s[y]) & 255;
|
---|
103 | *buf++ ^= s[tmp];
|
---|
104 | }
|
---|
105 | prng->rc4.x = x;
|
---|
106 | prng->rc4.y = y;
|
---|
107 | return n;
|
---|
108 | }
|
---|