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
39int
40arc4_ctxlen(void)
41{
42 return sizeof(struct arc4_ctx);
43}
44
45void
46arc4_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
69void
70arc4_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
92void
93arc4_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
116void
117arc4_decrypt(void *ctxp, u_char *dst, const u_char *src, int len)
118{
119 arc4_encrypt(ctxp, dst, src, len);
120}
121