18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Cryptographic API 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * ARC4 Cipher Algorithm 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Jon Oberheide <jon@oberheide.org> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <crypto/arc4.h> 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ciint arc4_setkey(struct arc4_ctx *ctx, const u8 *in_key, unsigned int key_len) 148c2ecf20Sopenharmony_ci{ 158c2ecf20Sopenharmony_ci int i, j = 0, k = 0; 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci ctx->x = 1; 188c2ecf20Sopenharmony_ci ctx->y = 0; 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci for (i = 0; i < 256; i++) 218c2ecf20Sopenharmony_ci ctx->S[i] = i; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci for (i = 0; i < 256; i++) { 248c2ecf20Sopenharmony_ci u32 a = ctx->S[i]; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci j = (j + in_key[k] + a) & 0xff; 278c2ecf20Sopenharmony_ci ctx->S[i] = ctx->S[j]; 288c2ecf20Sopenharmony_ci ctx->S[j] = a; 298c2ecf20Sopenharmony_ci if (++k >= key_len) 308c2ecf20Sopenharmony_ci k = 0; 318c2ecf20Sopenharmony_ci } 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci return 0; 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ciEXPORT_SYMBOL(arc4_setkey); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_civoid arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in, unsigned int len) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci u32 *const S = ctx->S; 408c2ecf20Sopenharmony_ci u32 x, y, a, b; 418c2ecf20Sopenharmony_ci u32 ty, ta, tb; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci if (len == 0) 448c2ecf20Sopenharmony_ci return; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci x = ctx->x; 478c2ecf20Sopenharmony_ci y = ctx->y; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci a = S[x]; 508c2ecf20Sopenharmony_ci y = (y + a) & 0xff; 518c2ecf20Sopenharmony_ci b = S[y]; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci do { 548c2ecf20Sopenharmony_ci S[y] = a; 558c2ecf20Sopenharmony_ci a = (a + b) & 0xff; 568c2ecf20Sopenharmony_ci S[x] = b; 578c2ecf20Sopenharmony_ci x = (x + 1) & 0xff; 588c2ecf20Sopenharmony_ci ta = S[x]; 598c2ecf20Sopenharmony_ci ty = (y + ta) & 0xff; 608c2ecf20Sopenharmony_ci tb = S[ty]; 618c2ecf20Sopenharmony_ci *out++ = *in++ ^ S[a]; 628c2ecf20Sopenharmony_ci if (--len == 0) 638c2ecf20Sopenharmony_ci break; 648c2ecf20Sopenharmony_ci y = ty; 658c2ecf20Sopenharmony_ci a = ta; 668c2ecf20Sopenharmony_ci b = tb; 678c2ecf20Sopenharmony_ci } while (true); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci ctx->x = x; 708c2ecf20Sopenharmony_ci ctx->y = y; 718c2ecf20Sopenharmony_ci} 728c2ecf20Sopenharmony_ciEXPORT_SYMBOL(arc4_crypt); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL"); 75