blob: aa5e3a2b3a24441531f7022e650831427d1e9222 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * An implementation of the ARCFOUR algorithm
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
19/*
20 * The ARCFOUR algorithm was publicly disclosed on 94/09.
21 *
22 * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0
23 */
24
Gilles Peskinedb09ef62020-06-03 01:43:33 +020025#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000026
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020027#if defined(MBEDTLS_ARC4_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000028
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000029#include "mbedtls/arc4.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050030#include "mbedtls/platform_util.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Rich Evans00ab4702015-02-06 13:43:58 +000032#include <string.h>
33
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000034#include "mbedtls/platform.h"
Paul Bakker7dc4c442014-02-01 22:50:26 +010035
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020036#if !defined(MBEDTLS_ARC4_ALT)
Paul Bakker90995b52013-06-24 19:20:35 +020037
David Horstmannceeaeb92023-01-05 15:44:23 +000038void mbedtls_arc4_init(mbedtls_arc4_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +020039{
David Horstmannceeaeb92023-01-05 15:44:23 +000040 memset(ctx, 0, sizeof(mbedtls_arc4_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +020041}
42
David Horstmannceeaeb92023-01-05 15:44:23 +000043void mbedtls_arc4_free(mbedtls_arc4_context *ctx)
Paul Bakkerc7ea99a2014-06-18 11:12:03 +020044{
David Horstmannceeaeb92023-01-05 15:44:23 +000045 if (ctx == NULL) {
Paul Bakkerc7ea99a2014-06-18 11:12:03 +020046 return;
David Horstmannceeaeb92023-01-05 15:44:23 +000047 }
Paul Bakkerc7ea99a2014-06-18 11:12:03 +020048
David Horstmannceeaeb92023-01-05 15:44:23 +000049 mbedtls_platform_zeroize(ctx, sizeof(mbedtls_arc4_context));
Paul Bakkerc7ea99a2014-06-18 11:12:03 +020050}
51
Paul Bakker5121ce52009-01-03 21:22:43 +000052/*
53 * ARC4 key schedule
54 */
David Horstmannceeaeb92023-01-05 15:44:23 +000055void mbedtls_arc4_setup(mbedtls_arc4_context *ctx, const unsigned char *key,
56 unsigned int keylen)
Paul Bakker5121ce52009-01-03 21:22:43 +000057{
Paul Bakker23986e52011-04-24 08:57:21 +000058 int i, j, a;
59 unsigned int k;
Paul Bakker5121ce52009-01-03 21:22:43 +000060 unsigned char *m;
61
62 ctx->x = 0;
63 ctx->y = 0;
64 m = ctx->m;
65
David Horstmannceeaeb92023-01-05 15:44:23 +000066 for (i = 0; i < 256; i++) {
Paul Bakker5121ce52009-01-03 21:22:43 +000067 m[i] = (unsigned char) i;
David Horstmannceeaeb92023-01-05 15:44:23 +000068 }
Paul Bakker5121ce52009-01-03 21:22:43 +000069
70 j = k = 0;
71
David Horstmannceeaeb92023-01-05 15:44:23 +000072 for (i = 0; i < 256; i++, k++) {
73 if (k >= keylen) {
74 k = 0;
75 }
Paul Bakker5121ce52009-01-03 21:22:43 +000076
77 a = m[i];
David Horstmannceeaeb92023-01-05 15:44:23 +000078 j = (j + a + key[k]) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +000079 m[i] = m[j];
80 m[j] = (unsigned char) a;
81 }
82}
83
84/*
85 * ARC4 cipher function
86 */
David Horstmannceeaeb92023-01-05 15:44:23 +000087int mbedtls_arc4_crypt(mbedtls_arc4_context *ctx, size_t length, const unsigned char *input,
88 unsigned char *output)
Paul Bakker5121ce52009-01-03 21:22:43 +000089{
Paul Bakker23986e52011-04-24 08:57:21 +000090 int x, y, a, b;
91 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +000092 unsigned char *m;
93
94 x = ctx->x;
95 y = ctx->y;
96 m = ctx->m;
97
David Horstmannceeaeb92023-01-05 15:44:23 +000098 for (i = 0; i < length; i++) {
99 x = (x + 1) & 0xFF; a = m[x];
100 y = (y + a) & 0xFF; b = m[y];
Paul Bakker5121ce52009-01-03 21:22:43 +0000101
102 m[x] = (unsigned char) b;
103 m[y] = (unsigned char) a;
104
Paul Bakkerbaad6502010-03-21 15:42:15 +0000105 output[i] = (unsigned char)
David Horstmannceeaeb92023-01-05 15:44:23 +0000106 (input[i] ^ m[(unsigned char) (a + b)]);
Paul Bakker5121ce52009-01-03 21:22:43 +0000107 }
108
109 ctx->x = x;
110 ctx->y = y;
Paul Bakkerf3ccc682010-03-18 21:21:02 +0000111
David Horstmannceeaeb92023-01-05 15:44:23 +0000112 return 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000113}
114
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115#endif /* !MBEDTLS_ARC4_ALT */
Paul Bakker90995b52013-06-24 19:20:35 +0200116
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +0000118/*
119 * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994:
120 *
121 * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0
122 */
123static const unsigned char arc4_test_key[3][8] =
124{
125 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
126 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
127 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
128};
129
130static const unsigned char arc4_test_pt[3][8] =
131{
132 { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF },
133 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
134 { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
135};
136
137static const unsigned char arc4_test_ct[3][8] =
138{
139 { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 },
140 { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 },
141 { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A }
142};
143
144/*
145 * Checkup routine
146 */
David Horstmannceeaeb92023-01-05 15:44:23 +0000147int mbedtls_arc4_self_test(int verbose)
Paul Bakker5121ce52009-01-03 21:22:43 +0000148{
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200149 int i, ret = 0;
Paul Bakkerbaad6502010-03-21 15:42:15 +0000150 unsigned char ibuf[8];
151 unsigned char obuf[8];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200152 mbedtls_arc4_context ctx;
Paul Bakker5121ce52009-01-03 21:22:43 +0000153
David Horstmannceeaeb92023-01-05 15:44:23 +0000154 mbedtls_arc4_init(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200155
David Horstmannceeaeb92023-01-05 15:44:23 +0000156 for (i = 0; i < 3; i++) {
157 if (verbose != 0) {
158 mbedtls_printf(" ARC4 test #%d: ", i + 1);
159 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000160
David Horstmannceeaeb92023-01-05 15:44:23 +0000161 memcpy(ibuf, arc4_test_pt[i], 8);
Paul Bakker5121ce52009-01-03 21:22:43 +0000162
David Horstmannceeaeb92023-01-05 15:44:23 +0000163 mbedtls_arc4_setup(&ctx, arc4_test_key[i], 8);
164 mbedtls_arc4_crypt(&ctx, 8, ibuf, obuf);
Paul Bakker5121ce52009-01-03 21:22:43 +0000165
David Horstmannceeaeb92023-01-05 15:44:23 +0000166 if (memcmp(obuf, arc4_test_ct[i], 8) != 0) {
167 if (verbose != 0) {
168 mbedtls_printf("failed\n");
169 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000170
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200171 ret = 1;
172 goto exit;
Paul Bakker5121ce52009-01-03 21:22:43 +0000173 }
174
David Horstmannceeaeb92023-01-05 15:44:23 +0000175 if (verbose != 0) {
176 mbedtls_printf("passed\n");
177 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000178 }
179
David Horstmannceeaeb92023-01-05 15:44:23 +0000180 if (verbose != 0) {
181 mbedtls_printf("\n");
182 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000183
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200184exit:
David Horstmannceeaeb92023-01-05 15:44:23 +0000185 mbedtls_arc4_free(&ctx);
Paul Bakkerc7ea99a2014-06-18 11:12:03 +0200186
David Horstmannceeaeb92023-01-05 15:44:23 +0000187 return ret;
Paul Bakker5121ce52009-01-03 21:22:43 +0000188}
189
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200190#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +0000191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200192#endif /* MBEDTLS_ARC4_C */