The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/crypto/arc4.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Cryptographic API
    3  *
    4  * ARC4 Cipher Algorithm
    5  *
    6  * Jon Oberheide <jon@oberheide.org>
    7  *
    8  * This program is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
   10  * the Free Software Foundation; either version 2 of the License, or
   11  * (at your option) any later version.
   12  *
   13  */
   14 
   15 #include <linux/module.h>
   16 #include <linux/init.h>
   17 #include <linux/crypto.h>
   18 #include <crypto/algapi.h>
   19 
   20 #define ARC4_MIN_KEY_SIZE       1
   21 #define ARC4_MAX_KEY_SIZE       256
   22 #define ARC4_BLOCK_SIZE         1
   23 
   24 struct arc4_ctx {
   25         u32 S[256];
   26         u32 x, y;
   27 };
   28 
   29 static int arc4_set_key(struct crypto_tfm *tfm, const u8 *in_key,
   30                         unsigned int key_len)
   31 {
   32         struct arc4_ctx *ctx = crypto_tfm_ctx(tfm);
   33         int i, j = 0, k = 0;
   34 
   35         ctx->x = 1;
   36         ctx->y = 0;
   37 
   38         for (i = 0; i < 256; i++)
   39                 ctx->S[i] = i;
   40 
   41         for (i = 0; i < 256; i++) {
   42                 u32 a = ctx->S[i];
   43                 j = (j + in_key[k] + a) & 0xff;
   44                 ctx->S[i] = ctx->S[j];
   45                 ctx->S[j] = a;
   46                 if (++k >= key_len)
   47                         k = 0;
   48         }
   49 
   50         return 0;
   51 }
   52 
   53 static void arc4_crypt(struct arc4_ctx *ctx, u8 *out, const u8 *in,
   54                        unsigned int len)
   55 {
   56         u32 *const S = ctx->S;
   57         u32 x, y, a, b;
   58         u32 ty, ta, tb;
   59 
   60         if (len == 0)
   61                 return;
   62 
   63         x = ctx->x;
   64         y = ctx->y;
   65 
   66         a = S[x];
   67         y = (y + a) & 0xff;
   68         b = S[y];
   69 
   70         do {
   71                 S[y] = a;
   72                 a = (a + b) & 0xff;
   73                 S[x] = b;
   74                 x = (x + 1) & 0xff;
   75                 ta = S[x];
   76                 ty = (y + ta) & 0xff;
   77                 tb = S[ty];
   78                 *out++ = *in++ ^ S[a];
   79                 if (--len == 0)
   80                         break;
   81                 y = ty;
   82                 a = ta;
   83                 b = tb;
   84         } while (true);
   85 
   86         ctx->x = x;
   87         ctx->y = y;
   88 }
   89 
   90 static void arc4_crypt_one(struct crypto_tfm *tfm, u8 *out, const u8 *in)
   91 {
   92         arc4_crypt(crypto_tfm_ctx(tfm), out, in, 1);
   93 }
   94 
   95 static int ecb_arc4_crypt(struct blkcipher_desc *desc, struct scatterlist *dst,
   96                           struct scatterlist *src, unsigned int nbytes)
   97 {
   98         struct arc4_ctx *ctx = crypto_blkcipher_ctx(desc->tfm);
   99         struct blkcipher_walk walk;
  100         int err;
  101 
  102         blkcipher_walk_init(&walk, dst, src, nbytes);
  103 
  104         err = blkcipher_walk_virt(desc, &walk);
  105 
  106         while (walk.nbytes > 0) {
  107                 u8 *wsrc = walk.src.virt.addr;
  108                 u8 *wdst = walk.dst.virt.addr;
  109 
  110                 arc4_crypt(ctx, wdst, wsrc, walk.nbytes);
  111 
  112                 err = blkcipher_walk_done(desc, &walk, 0);
  113         }
  114 
  115         return err;
  116 }
  117 
  118 static struct crypto_alg arc4_algs[2] = { {
  119         .cra_name               =       "arc4",
  120         .cra_flags              =       CRYPTO_ALG_TYPE_CIPHER,
  121         .cra_blocksize          =       ARC4_BLOCK_SIZE,
  122         .cra_ctxsize            =       sizeof(struct arc4_ctx),
  123         .cra_module             =       THIS_MODULE,
  124         .cra_u                  =       {
  125                 .cipher = {
  126                         .cia_min_keysize        =       ARC4_MIN_KEY_SIZE,
  127                         .cia_max_keysize        =       ARC4_MAX_KEY_SIZE,
  128                         .cia_setkey             =       arc4_set_key,
  129                         .cia_encrypt            =       arc4_crypt_one,
  130                         .cia_decrypt            =       arc4_crypt_one,
  131                 },
  132         },
  133 }, {
  134         .cra_name               =       "ecb(arc4)",
  135         .cra_priority           =       100,
  136         .cra_flags              =       CRYPTO_ALG_TYPE_BLKCIPHER,
  137         .cra_blocksize          =       ARC4_BLOCK_SIZE,
  138         .cra_ctxsize            =       sizeof(struct arc4_ctx),
  139         .cra_alignmask          =       0,
  140         .cra_type               =       &crypto_blkcipher_type,
  141         .cra_module             =       THIS_MODULE,
  142         .cra_u                  =       {
  143                 .blkcipher = {
  144                         .min_keysize    =       ARC4_MIN_KEY_SIZE,
  145                         .max_keysize    =       ARC4_MAX_KEY_SIZE,
  146                         .setkey         =       arc4_set_key,
  147                         .encrypt        =       ecb_arc4_crypt,
  148                         .decrypt        =       ecb_arc4_crypt,
  149                 },
  150         },
  151 } };
  152 
  153 static int __init arc4_init(void)
  154 {
  155         return crypto_register_algs(arc4_algs, ARRAY_SIZE(arc4_algs));
  156 }
  157 
  158 static void __exit arc4_exit(void)
  159 {
  160         crypto_unregister_algs(arc4_algs, ARRAY_SIZE(arc4_algs));
  161 }
  162 
  163 module_init(arc4_init);
  164 module_exit(arc4_exit);
  165 
  166 MODULE_LICENSE("GPL");
  167 MODULE_DESCRIPTION("ARC4 Cipher Algorithm");
  168 MODULE_AUTHOR("Jon Oberheide <jon@oberheide.org>");

Cache object: 2942ac36f01e3a929a2944cc4139dfe1


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.