1*753dd0dbSdjm /* $OpenBSD: arc4.c,v 1.3 2007/09/11 12:07:05 djm Exp $ */
238553144Smarkus /*
338553144Smarkus * Copyright (c) 2003 Markus Friedl <markus@openbsd.org>
438553144Smarkus *
538553144Smarkus * Permission to use, copy, modify, and distribute this software for any
638553144Smarkus * purpose with or without fee is hereby granted, provided that the above
738553144Smarkus * copyright notice and this permission notice appear in all copies.
838553144Smarkus *
938553144Smarkus * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1038553144Smarkus * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1138553144Smarkus * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1238553144Smarkus * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1338553144Smarkus * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1438553144Smarkus * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1538553144Smarkus * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1638553144Smarkus */
1738553144Smarkus
1838553144Smarkus #include <sys/types.h>
1938553144Smarkus
2038553144Smarkus #include <crypto/arc4.h>
2138553144Smarkus
2238553144Smarkus #define RC4SWAP(x,y) \
2338553144Smarkus do { \
2438553144Smarkus u_int8_t t = ctx->state[x]; \
2538553144Smarkus ctx->state[x] = ctx->state[y]; \
2638553144Smarkus ctx->state[y] = t; \
2738553144Smarkus } while(0)
2838553144Smarkus
2938553144Smarkus void
rc4_keysetup(struct rc4_ctx * ctx,u_char * key,u_int32_t klen)3038553144Smarkus rc4_keysetup(struct rc4_ctx *ctx, u_char *key, u_int32_t klen)
3138553144Smarkus {
3238553144Smarkus u_int8_t x, y;
3338553144Smarkus u_int32_t i;
3438553144Smarkus
3538553144Smarkus x = y = 0;
3638553144Smarkus for (i = 0; i < RC4STATE; i++)
3738553144Smarkus ctx->state[i] = i;
3838553144Smarkus for (i = 0; i < RC4STATE; i++) {
39*753dd0dbSdjm y = (key[x] + ctx->state[i] + y) & (RC4STATE - 1);
4038553144Smarkus RC4SWAP(i, y);
4138553144Smarkus x = (x + 1) % klen;
4238553144Smarkus }
4338553144Smarkus ctx->x = ctx->y = 0;
4438553144Smarkus }
4538553144Smarkus
4638553144Smarkus void
rc4_crypt(struct rc4_ctx * ctx,u_char * src,u_char * dst,u_int32_t len)4738553144Smarkus rc4_crypt(struct rc4_ctx *ctx, u_char *src, u_char *dst,
4838553144Smarkus u_int32_t len)
4938553144Smarkus {
5038553144Smarkus u_int32_t i;
5138553144Smarkus
5238553144Smarkus for (i = 0; i < len; i++) {
53*753dd0dbSdjm ctx->x = (ctx->x + 1) & (RC4STATE - 1);
54*753dd0dbSdjm ctx->y = (ctx->state[ctx->x] + ctx->y) & (RC4STATE - 1);
5538553144Smarkus RC4SWAP(ctx->x, ctx->y);
5638553144Smarkus dst[i] = src[i] ^ ctx->state[
57*753dd0dbSdjm (ctx->state[ctx->x] + ctx->state[ctx->y]) & (RC4STATE - 1)];
58*753dd0dbSdjm }
59*753dd0dbSdjm }
60*753dd0dbSdjm
61*753dd0dbSdjm void
rc4_getbytes(struct rc4_ctx * ctx,u_char * dst,u_int32_t len)62*753dd0dbSdjm rc4_getbytes(struct rc4_ctx *ctx, u_char *dst, u_int32_t len)
63*753dd0dbSdjm {
64*753dd0dbSdjm u_int32_t i;
65*753dd0dbSdjm
66*753dd0dbSdjm for (i = 0; i < len; i++) {
67*753dd0dbSdjm ctx->x = (ctx->x + 1) & (RC4STATE - 1);
68*753dd0dbSdjm ctx->y = (ctx->state[ctx->x] + ctx->y) & (RC4STATE - 1);
69*753dd0dbSdjm RC4SWAP(ctx->x, ctx->y);
70*753dd0dbSdjm dst[i] = ctx->state[
71*753dd0dbSdjm (ctx->state[ctx->x] + ctx->state[ctx->y]) & (RC4STATE - 1)];
7238553144Smarkus }
7338553144Smarkus }
74c5823ff2Sdamien
75c5823ff2Sdamien void
rc4_skip(struct rc4_ctx * ctx,u_int32_t len)76c5823ff2Sdamien rc4_skip(struct rc4_ctx *ctx, u_int32_t len)
77c5823ff2Sdamien {
78c5823ff2Sdamien for (; len > 0; len--) {
79*753dd0dbSdjm ctx->x = (ctx->x + 1) & (RC4STATE - 1);
80*753dd0dbSdjm ctx->y = (ctx->state[ctx->x] + ctx->y) & (RC4STATE - 1);
81c5823ff2Sdamien RC4SWAP(ctx->x, ctx->y);
82c5823ff2Sdamien }
83c5823ff2Sdamien }
84