105 lines
2.7 KiB
C
105 lines
2.7 KiB
C
/* $NetBSD: arc4.c,v 1.6 2005/12/11 12:20:48 christos Exp $ */
|
|
|
|
/*
|
|
* ARC4 implementation
|
|
* A Stream Cipher Encryption Algorithm "Arcfour"
|
|
* <draft-kaukonen-cipher-arcfour-03.txt>
|
|
*/
|
|
|
|
/* This code illustrates a sample implementation
|
|
* of the Arcfour algorithm
|
|
* Copyright (c) April 29, 1997 Kalle Kaukonen.
|
|
* All Rights Reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or
|
|
* without modification, are permitted provided that this copyright
|
|
* notice and disclaimer are retained.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY KALLE KAUKONEN AND CONTRIBUTORS ``AS
|
|
* IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KALLE
|
|
* KAUKONEN OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
#include <sys/cdefs.h>
|
|
__KERNEL_RCSID(0, "$NetBSD: arc4.c,v 1.6 2005/12/11 12:20:48 christos Exp $");
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <crypto/arc4/arc4.h>
|
|
|
|
struct arc4_ctx {
|
|
unsigned int x;
|
|
unsigned int y;
|
|
unsigned int state[256];
|
|
/* was unsigned char, changed to int for performance -- onoe */
|
|
};
|
|
|
|
int
|
|
arc4_ctxlen(void)
|
|
{
|
|
return sizeof(struct arc4_ctx);
|
|
}
|
|
|
|
void
|
|
arc4_setkey(void *ctxp, const u_char *key, u_int keylen)
|
|
{
|
|
struct arc4_ctx *ctx = ctxp;
|
|
unsigned int i, t, u, ki, si;
|
|
unsigned int *state;
|
|
|
|
state = ctx->state;
|
|
ctx->x = 0;
|
|
ctx->y = 0;
|
|
for (i = 0; i < 256; i++)
|
|
state[i] = i;
|
|
ki = si = 0;
|
|
for (i = 0; i < 256; i++) {
|
|
t = state[i];
|
|
si = (si + key[ki] + t) & 0xff;
|
|
u = state[si];
|
|
state[si] = t;
|
|
state[i] = u;
|
|
if (++ki >= keylen)
|
|
ki = 0;
|
|
}
|
|
}
|
|
|
|
void
|
|
arc4_encrypt(void *ctxp, u_char *dst, const u_char *src, int len)
|
|
{
|
|
struct arc4_ctx *ctx = ctxp;
|
|
unsigned int x, y, sx, sy;
|
|
unsigned int *state;
|
|
const unsigned char *endsrc;
|
|
|
|
state = ctx->state;
|
|
x = ctx->x;
|
|
y = ctx->y;
|
|
for (endsrc = src + len; src != endsrc; src++, dst++) {
|
|
x = (x + 1) & 0xff;
|
|
sx = state[x];
|
|
y = (sx + y) & 0xff;
|
|
state[x] = sy = state[y];
|
|
state[y] = sx;
|
|
*dst = *src ^ state[(sx + sy) & 0xff];
|
|
}
|
|
ctx->x = x;
|
|
ctx->y = y;
|
|
}
|
|
|
|
void
|
|
arc4_decrypt(void *ctxp, u_char *dst, const u_char *src, int len)
|
|
{
|
|
|
|
arc4_encrypt(ctxp, dst, src, len);
|
|
}
|