/work/mbedtls-2.28.8/library/arc4.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * An implementation of the ARCFOUR algorithm |
3 | | * |
4 | | * Copyright The Mbed TLS Contributors |
5 | | * SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later |
6 | | */ |
7 | | /* |
8 | | * The ARCFOUR algorithm was publicly disclosed on 94/09. |
9 | | * |
10 | | * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 |
11 | | */ |
12 | | |
13 | | #include "common.h" |
14 | | |
15 | | #if defined(MBEDTLS_ARC4_C) |
16 | | |
17 | | #include "mbedtls/arc4.h" |
18 | | #include "mbedtls/platform_util.h" |
19 | | |
20 | | #include <string.h> |
21 | | |
22 | | #include "mbedtls/platform.h" |
23 | | |
24 | | #if !defined(MBEDTLS_ARC4_ALT) |
25 | | |
26 | | void mbedtls_arc4_init(mbedtls_arc4_context *ctx) |
27 | 0 | { |
28 | 0 | memset(ctx, 0, sizeof(mbedtls_arc4_context)); |
29 | 0 | } |
30 | | |
31 | | void mbedtls_arc4_free(mbedtls_arc4_context *ctx) |
32 | 0 | { |
33 | 0 | if (ctx == NULL) { |
34 | 0 | return; |
35 | 0 | } |
36 | | |
37 | 0 | mbedtls_platform_zeroize(ctx, sizeof(mbedtls_arc4_context)); |
38 | 0 | } |
39 | | |
40 | | /* |
41 | | * ARC4 key schedule |
42 | | */ |
43 | | void mbedtls_arc4_setup(mbedtls_arc4_context *ctx, const unsigned char *key, |
44 | | unsigned int keylen) |
45 | 0 | { |
46 | 0 | int i, j, a; |
47 | 0 | unsigned int k; |
48 | 0 | unsigned char *m; |
49 | |
|
50 | 0 | ctx->x = 0; |
51 | 0 | ctx->y = 0; |
52 | 0 | m = ctx->m; |
53 | |
|
54 | 0 | for (i = 0; i < 256; i++) { |
55 | 0 | m[i] = (unsigned char) i; |
56 | 0 | } |
57 | |
|
58 | 0 | j = k = 0; |
59 | |
|
60 | 0 | for (i = 0; i < 256; i++, k++) { |
61 | 0 | if (k >= keylen) { |
62 | 0 | k = 0; |
63 | 0 | } |
64 | |
|
65 | 0 | a = m[i]; |
66 | 0 | j = (j + a + key[k]) & 0xFF; |
67 | 0 | m[i] = m[j]; |
68 | 0 | m[j] = (unsigned char) a; |
69 | 0 | } |
70 | 0 | } |
71 | | |
72 | | /* |
73 | | * ARC4 cipher function |
74 | | */ |
75 | | int mbedtls_arc4_crypt(mbedtls_arc4_context *ctx, size_t length, const unsigned char *input, |
76 | | unsigned char *output) |
77 | 0 | { |
78 | 0 | int x, y, a, b; |
79 | 0 | size_t i; |
80 | 0 | unsigned char *m; |
81 | |
|
82 | 0 | x = ctx->x; |
83 | 0 | y = ctx->y; |
84 | 0 | m = ctx->m; |
85 | |
|
86 | 0 | for (i = 0; i < length; i++) { |
87 | 0 | x = (x + 1) & 0xFF; a = m[x]; |
88 | 0 | y = (y + a) & 0xFF; b = m[y]; |
89 | |
|
90 | 0 | m[x] = (unsigned char) b; |
91 | 0 | m[y] = (unsigned char) a; |
92 | |
|
93 | 0 | output[i] = (unsigned char) |
94 | 0 | (input[i] ^ m[(unsigned char) (a + b)]); |
95 | 0 | } |
96 | |
|
97 | 0 | ctx->x = x; |
98 | 0 | ctx->y = y; |
99 | |
|
100 | 0 | return 0; |
101 | 0 | } |
102 | | |
103 | | #endif /* !MBEDTLS_ARC4_ALT */ |
104 | | |
105 | | #if defined(MBEDTLS_SELF_TEST) |
106 | | /* |
107 | | * ARC4 tests vectors as posted by Eric Rescorla in sep. 1994: |
108 | | * |
109 | | * http://groups.google.com/group/comp.security.misc/msg/10a300c9d21afca0 |
110 | | */ |
111 | | static const unsigned char arc4_test_key[3][8] = |
112 | | { |
113 | | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, |
114 | | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, |
115 | | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } |
116 | | }; |
117 | | |
118 | | static const unsigned char arc4_test_pt[3][8] = |
119 | | { |
120 | | { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }, |
121 | | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, |
122 | | { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } |
123 | | }; |
124 | | |
125 | | static const unsigned char arc4_test_ct[3][8] = |
126 | | { |
127 | | { 0x75, 0xB7, 0x87, 0x80, 0x99, 0xE0, 0xC5, 0x96 }, |
128 | | { 0x74, 0x94, 0xC2, 0xE7, 0x10, 0x4B, 0x08, 0x79 }, |
129 | | { 0xDE, 0x18, 0x89, 0x41, 0xA3, 0x37, 0x5D, 0x3A } |
130 | | }; |
131 | | |
132 | | /* |
133 | | * Checkup routine |
134 | | */ |
135 | | int mbedtls_arc4_self_test(int verbose) |
136 | 0 | { |
137 | 0 | int i, ret = 0; |
138 | 0 | unsigned char ibuf[8]; |
139 | 0 | unsigned char obuf[8]; |
140 | 0 | mbedtls_arc4_context ctx; |
141 | |
|
142 | 0 | mbedtls_arc4_init(&ctx); |
143 | |
|
144 | 0 | for (i = 0; i < 3; i++) { |
145 | 0 | if (verbose != 0) { |
146 | 0 | mbedtls_printf(" ARC4 test #%d: ", i + 1); |
147 | 0 | } |
148 | |
|
149 | 0 | memcpy(ibuf, arc4_test_pt[i], 8); |
150 | |
|
151 | 0 | mbedtls_arc4_setup(&ctx, arc4_test_key[i], 8); |
152 | 0 | mbedtls_arc4_crypt(&ctx, 8, ibuf, obuf); |
153 | |
|
154 | 0 | if (memcmp(obuf, arc4_test_ct[i], 8) != 0) { |
155 | 0 | if (verbose != 0) { |
156 | 0 | mbedtls_printf("failed\n"); |
157 | 0 | } |
158 | |
|
159 | 0 | ret = 1; |
160 | 0 | goto exit; |
161 | 0 | } |
162 | | |
163 | 0 | if (verbose != 0) { |
164 | 0 | mbedtls_printf("passed\n"); |
165 | 0 | } |
166 | 0 | } |
167 | | |
168 | 0 | if (verbose != 0) { |
169 | 0 | mbedtls_printf("\n"); |
170 | 0 | } |
171 | |
|
172 | 0 | exit: |
173 | 0 | mbedtls_arc4_free(&ctx); |
174 | |
|
175 | 0 | return ret; |
176 | 0 | } |
177 | | |
178 | | #endif /* MBEDTLS_SELF_TEST */ |
179 | | |
180 | | #endif /* MBEDTLS_ARC4_C */ |