blob: be11bade7bc027735d828a9ac1a7d3500367899f [file] [log] [blame]
Rich Salz62867572016-05-17 14:24:46 -04001/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00003 *
Rich Salz62867572016-05-17 14:24:46 -04004 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00008 */
9
Bodo Möllerec577821999-04-23 22:13:45 +000010#include <openssl/rc4.h>
Ralf S. Engelschall58964a41998-12-21 10:56:39 +000011#include "rc4_locl.h"
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000012
Matt Caswellc80fd6b2015-01-16 09:21:50 +000013/*-
14 * RC4 as implemented from a posting from
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000015 * Newsgroups: sci.crypt
16 * From: sterndark@netcom.com (David Sterndark)
17 * Subject: RC4 Algorithm revealed.
18 * Message-ID: <sternCvKL4B.Hyy@netcom.com>
19 * Date: Wed, 14 Sep 1994 06:35:31 GMT
20 */
21
Andy Polyakovf768be82008-10-31 19:30:11 +000022void RC4(RC4_KEY *key, size_t len, const unsigned char *indata,
Matt Caswell0f113f32015-01-22 03:40:55 +000023 unsigned char *outdata)
24{
25 register RC4_INT *d;
26 register RC4_INT x, y, tx, ty;
27 size_t i;
28
29 x = key->x;
30 y = key->y;
31 d = key->data;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000032
33#define LOOP(in,out) \
Matt Caswell0f113f32015-01-22 03:40:55 +000034 x=((x+1)&0xff); \
35 tx=d[x]; \
36 y=(tx+y)&0xff; \
37 d[x]=ty=d[y]; \
38 d[y]=tx; \
39 (out) = d[(tx+ty)&0xff]^ (in);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000040
Matt Caswell0f113f32015-01-22 03:40:55 +000041 i = len >> 3;
42 if (i) {
43 for (;;) {
Rich Salz3e9e8102016-01-27 18:43:25 -050044 LOOP(indata[0], outdata[0]);
45 LOOP(indata[1], outdata[1]);
46 LOOP(indata[2], outdata[2]);
47 LOOP(indata[3], outdata[3]);
48 LOOP(indata[4], outdata[4]);
49 LOOP(indata[5], outdata[5]);
50 LOOP(indata[6], outdata[6]);
51 LOOP(indata[7], outdata[7]);
Matt Caswell0f113f32015-01-22 03:40:55 +000052 indata += 8;
53 outdata += 8;
Matt Caswell0f113f32015-01-22 03:40:55 +000054 if (--i == 0)
55 break;
56 }
57 }
58 i = len & 0x07;
59 if (i) {
60 for (;;) {
Rich Salz3e9e8102016-01-27 18:43:25 -050061 LOOP(indata[0], outdata[0]);
Matt Caswell0f113f32015-01-22 03:40:55 +000062 if (--i == 0)
63 break;
Rich Salz3e9e8102016-01-27 18:43:25 -050064 LOOP(indata[1], outdata[1]);
Matt Caswell0f113f32015-01-22 03:40:55 +000065 if (--i == 0)
66 break;
Rich Salz3e9e8102016-01-27 18:43:25 -050067 LOOP(indata[2], outdata[2]);
Matt Caswell0f113f32015-01-22 03:40:55 +000068 if (--i == 0)
69 break;
Rich Salz3e9e8102016-01-27 18:43:25 -050070 LOOP(indata[3], outdata[3]);
Matt Caswell0f113f32015-01-22 03:40:55 +000071 if (--i == 0)
72 break;
Rich Salz3e9e8102016-01-27 18:43:25 -050073 LOOP(indata[4], outdata[4]);
Matt Caswell0f113f32015-01-22 03:40:55 +000074 if (--i == 0)
75 break;
Rich Salz3e9e8102016-01-27 18:43:25 -050076 LOOP(indata[5], outdata[5]);
Matt Caswell0f113f32015-01-22 03:40:55 +000077 if (--i == 0)
78 break;
Rich Salz3e9e8102016-01-27 18:43:25 -050079 LOOP(indata[6], outdata[6]);
Matt Caswell0f113f32015-01-22 03:40:55 +000080 if (--i == 0)
81 break;
82 }
83 }
84 key->x = x;
85 key->y = y;
86}