11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * Cryptographic API 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * ARC4 Cipher Algorithm 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * Jon Oberheide <jon@oberheide.org> 71da177e4SLinus Torvalds * 81da177e4SLinus Torvalds * This program is free software; you can redistribute it and/or modify 91da177e4SLinus Torvalds * it under the terms of the GNU General Public License as published by 101da177e4SLinus Torvalds * the Free Software Foundation; either version 2 of the License, or 111da177e4SLinus Torvalds * (at your option) any later version. 121da177e4SLinus Torvalds * 131da177e4SLinus Torvalds */ 141da177e4SLinus Torvalds #include <linux/module.h> 151da177e4SLinus Torvalds #include <linux/init.h> 161da177e4SLinus Torvalds #include <linux/crypto.h> 171da177e4SLinus Torvalds 181da177e4SLinus Torvalds #define ARC4_MIN_KEY_SIZE 1 191da177e4SLinus Torvalds #define ARC4_MAX_KEY_SIZE 256 201da177e4SLinus Torvalds #define ARC4_BLOCK_SIZE 1 211da177e4SLinus Torvalds 221da177e4SLinus Torvalds struct arc4_ctx { 231da177e4SLinus Torvalds u8 S[256]; 241da177e4SLinus Torvalds u8 x, y; 251da177e4SLinus Torvalds }; 261da177e4SLinus Torvalds 27*6c2bb98bSHerbert Xu static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key, 28*6c2bb98bSHerbert Xu unsigned int key_len, u32 *flags) 291da177e4SLinus Torvalds { 30*6c2bb98bSHerbert Xu struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); 311da177e4SLinus Torvalds int i, j = 0, k = 0; 321da177e4SLinus Torvalds 331da177e4SLinus Torvalds ctx->x = 1; 341da177e4SLinus Torvalds ctx->y = 0; 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds for(i = 0; i < 256; i++) 371da177e4SLinus Torvalds ctx->S[i] = i; 381da177e4SLinus Torvalds 391da177e4SLinus Torvalds for(i = 0; i < 256; i++) 401da177e4SLinus Torvalds { 411da177e4SLinus Torvalds u8 a = ctx->S[i]; 421da177e4SLinus Torvalds j = (j + in_key[k] + a) & 0xff; 431da177e4SLinus Torvalds ctx->S[i] = ctx->S[j]; 441da177e4SLinus Torvalds ctx->S[j] = a; 451da177e4SLinus Torvalds if(++k >= key_len) 461da177e4SLinus Torvalds k = 0; 471da177e4SLinus Torvalds } 481da177e4SLinus Torvalds 491da177e4SLinus Torvalds return 0; 501da177e4SLinus Torvalds } 511da177e4SLinus Torvalds 52*6c2bb98bSHerbert Xu static void arc4_crypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) 531da177e4SLinus Torvalds { 54*6c2bb98bSHerbert Xu struct arc4_ctx *ctx = crypto_tfm_ctx(tfm); 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds u8 *const S = ctx->S; 571da177e4SLinus Torvalds u8 x = ctx->x; 581da177e4SLinus Torvalds u8 y = ctx->y; 591da177e4SLinus Torvalds u8 a, b; 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds a = S[x]; 621da177e4SLinus Torvalds y = (y + a) & 0xff; 631da177e4SLinus Torvalds b = S[y]; 641da177e4SLinus Torvalds S[x] = b; 651da177e4SLinus Torvalds S[y] = a; 661da177e4SLinus Torvalds x = (x + 1) & 0xff; 671da177e4SLinus Torvalds *out++ = *in ^ S[(a + b) & 0xff]; 681da177e4SLinus Torvalds 691da177e4SLinus Torvalds ctx->x = x; 701da177e4SLinus Torvalds ctx->y = y; 711da177e4SLinus Torvalds } 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds static struct crypto_alg arc4_alg = { 741da177e4SLinus Torvalds .cra_name = "arc4", 751da177e4SLinus Torvalds .cra_flags = CRYPTO_ALG_TYPE_CIPHER, 761da177e4SLinus Torvalds .cra_blocksize = ARC4_BLOCK_SIZE, 771da177e4SLinus Torvalds .cra_ctxsize = sizeof(struct arc4_ctx), 781da177e4SLinus Torvalds .cra_module = THIS_MODULE, 791da177e4SLinus Torvalds .cra_list = LIST_HEAD_INIT(arc4_alg.cra_list), 801da177e4SLinus Torvalds .cra_u = { .cipher = { 811da177e4SLinus Torvalds .cia_min_keysize = ARC4_MIN_KEY_SIZE, 821da177e4SLinus Torvalds .cia_max_keysize = ARC4_MAX_KEY_SIZE, 831da177e4SLinus Torvalds .cia_setkey = arc4_set_key, 841da177e4SLinus Torvalds .cia_encrypt = arc4_crypt, 851da177e4SLinus Torvalds .cia_decrypt = arc4_crypt } } 861da177e4SLinus Torvalds }; 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds static int __init arc4_init(void) 891da177e4SLinus Torvalds { 901da177e4SLinus Torvalds return crypto_register_alg(&arc4_alg); 911da177e4SLinus Torvalds } 921da177e4SLinus Torvalds 931da177e4SLinus Torvalds 941da177e4SLinus Torvalds static void __exit arc4_exit(void) 951da177e4SLinus Torvalds { 961da177e4SLinus Torvalds crypto_unregister_alg(&arc4_alg); 971da177e4SLinus Torvalds } 981da177e4SLinus Torvalds 991da177e4SLinus Torvalds module_init(arc4_init); 1001da177e4SLinus Torvalds module_exit(arc4_exit); 1011da177e4SLinus Torvalds 1021da177e4SLinus Torvalds MODULE_LICENSE("GPL"); 1031da177e4SLinus Torvalds MODULE_DESCRIPTION("ARC4 Cipher Algorithm"); 1041da177e4SLinus Torvalds MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>"); 105