1 | /* $NetBSD: arc4.c,v 1.7 2014/08/10 16:44:35 tls Exp $ */ |
2 | |
3 | /* |
4 | * ARC4 implementation |
5 | * A Stream Cipher Encryption Algorithm "Arcfour" |
6 | * <draft-kaukonen-cipher-arcfour-03.txt> |
7 | */ |
8 | |
9 | /* This code illustrates a sample implementation |
10 | * of the Arcfour algorithm |
11 | * Copyright (c) April 29, 1997 Kalle Kaukonen. |
12 | * All Rights Reserved. |
13 | * |
14 | * Redistribution and use in source and binary forms, with or |
15 | * without modification, are permitted provided that this copyright |
16 | * notice and disclaimer are retained. |
17 | * |
18 | * THIS SOFTWARE IS PROVIDED BY KALLE KAUKONEN AND CONTRIBUTORS ``AS |
19 | * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
20 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
21 | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALLE |
22 | * KAUKONEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
26 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
27 | * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
28 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 | */ |
31 | |
32 | #include <sys/cdefs.h> |
33 | __KERNEL_RCSID(0, "$NetBSD: arc4.c,v 1.7 2014/08/10 16:44:35 tls Exp $" ); |
34 | |
35 | #include <sys/types.h> |
36 | |
37 | #include <crypto/arc4/arc4.h> |
38 | |
39 | int |
40 | arc4_ctxlen(void) |
41 | { |
42 | return sizeof(struct arc4_ctx); |
43 | } |
44 | |
45 | void |
46 | arc4_setkey(void *ctxp, const u_char *key, u_int keylen) |
47 | { |
48 | struct arc4_ctx *ctx = ctxp; |
49 | unsigned int i, t, u, ki, si; |
50 | unsigned int *state; |
51 | |
52 | state = ctx->state; |
53 | ctx->x = 0; |
54 | ctx->y = 0; |
55 | for (i = 0; i < 256; i++) |
56 | state[i] = i; |
57 | ki = si = 0; |
58 | for (i = 0; i < 256; i++) { |
59 | t = state[i]; |
60 | si = (si + key[ki] + t) & 0xff; |
61 | u = state[si]; |
62 | state[si] = t; |
63 | state[i] = u; |
64 | if (++ki >= keylen) |
65 | ki = 0; |
66 | } |
67 | } |
68 | |
69 | void |
70 | arc4_encrypt(void *ctxp, u_char *dst, const u_char *src, int len) |
71 | { |
72 | struct arc4_ctx *ctx = ctxp; |
73 | unsigned int x, y, sx, sy; |
74 | unsigned int *state; |
75 | const unsigned char *endsrc; |
76 | |
77 | state = ctx->state; |
78 | x = ctx->x; |
79 | y = ctx->y; |
80 | for (endsrc = src + len; src != endsrc; src++, dst++) { |
81 | x = (x + 1) & 0xff; |
82 | sx = state[x]; |
83 | y = (sx + y) & 0xff; |
84 | state[x] = sy = state[y]; |
85 | state[y] = sx; |
86 | *dst = *src ^ state[(sx + sy) & 0xff]; |
87 | } |
88 | ctx->x = x; |
89 | ctx->y = y; |
90 | } |
91 | |
92 | void |
93 | arc4_stream(void *ctxp, u_char *dst, int len) |
94 | { |
95 | struct arc4_ctx *ctx = ctxp; |
96 | unsigned int x, y, sx, sy; |
97 | unsigned int *state; |
98 | const unsigned char *enddst; |
99 | |
100 | state = ctx->state; |
101 | x = ctx->x; |
102 | y = ctx->y; |
103 | |
104 | for (enddst = dst + len; dst != enddst; dst++) { |
105 | x = (x + 1) & 0xff; |
106 | sx = state[x]; |
107 | y = (sx + y) & 0xff; |
108 | state[x] = sy = state[y]; |
109 | state[y]= sx; |
110 | *dst = state[(sx + sy) & 0xff]; |
111 | } |
112 | ctx->x = x; |
113 | ctx->y = y; |
114 | } |
115 | |
116 | void |
117 | arc4_decrypt(void *ctxp, u_char *dst, const u_char *src, int len) |
118 | { |
119 | arc4_encrypt(ctxp, dst, src, len); |
120 | } |
121 | |