Back to home page

LXR

 
 

    


0001 /*
0002  * ECB: Electronic CodeBook mode
0003  *
0004  * Copyright (c) 2006 Herbert Xu <herbert@gondor.apana.org.au>
0005  *
0006  * This program is free software; you can redistribute it and/or modify it
0007  * under the terms of the GNU General Public License as published by the Free
0008  * Software Foundation; either version 2 of the License, or (at your option)
0009  * any later version.
0010  *
0011  */
0012 
0013 #include <crypto/algapi.h>
0014 #include <linux/err.h>
0015 #include <linux/init.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/scatterlist.h>
0019 #include <linux/slab.h>
0020 
0021 struct crypto_ecb_ctx {
0022     struct crypto_cipher *child;
0023 };
0024 
0025 static int crypto_ecb_setkey(struct crypto_tfm *parent, const u8 *key,
0026                  unsigned int keylen)
0027 {
0028     struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(parent);
0029     struct crypto_cipher *child = ctx->child;
0030     int err;
0031 
0032     crypto_cipher_clear_flags(child, CRYPTO_TFM_REQ_MASK);
0033     crypto_cipher_set_flags(child, crypto_tfm_get_flags(parent) &
0034                        CRYPTO_TFM_REQ_MASK);
0035     err = crypto_cipher_setkey(child, key, keylen);
0036     crypto_tfm_set_flags(parent, crypto_cipher_get_flags(child) &
0037                      CRYPTO_TFM_RES_MASK);
0038     return err;
0039 }
0040 
0041 static int crypto_ecb_crypt(struct blkcipher_desc *desc,
0042                 struct blkcipher_walk *walk,
0043                 struct crypto_cipher *tfm,
0044                 void (*fn)(struct crypto_tfm *, u8 *, const u8 *))
0045 {
0046     int bsize = crypto_cipher_blocksize(tfm);
0047     unsigned int nbytes;
0048     int err;
0049 
0050     err = blkcipher_walk_virt(desc, walk);
0051 
0052     while ((nbytes = walk->nbytes)) {
0053         u8 *wsrc = walk->src.virt.addr;
0054         u8 *wdst = walk->dst.virt.addr;
0055 
0056         do {
0057             fn(crypto_cipher_tfm(tfm), wdst, wsrc);
0058 
0059             wsrc += bsize;
0060             wdst += bsize;
0061         } while ((nbytes -= bsize) >= bsize);
0062 
0063         err = blkcipher_walk_done(desc, walk, nbytes);
0064     }
0065 
0066     return err;
0067 }
0068 
0069 static int crypto_ecb_encrypt(struct blkcipher_desc *desc,
0070                   struct scatterlist *dst, struct scatterlist *src,
0071                   unsigned int nbytes)
0072 {
0073     struct blkcipher_walk walk;
0074     struct crypto_blkcipher *tfm = desc->tfm;
0075     struct crypto_ecb_ctx *ctx = crypto_blkcipher_ctx(tfm);
0076     struct crypto_cipher *child = ctx->child;
0077 
0078     blkcipher_walk_init(&walk, dst, src, nbytes);
0079     return crypto_ecb_crypt(desc, &walk, child,
0080                 crypto_cipher_alg(child)->cia_encrypt);
0081 }
0082 
0083 static int crypto_ecb_decrypt(struct blkcipher_desc *desc,
0084                   struct scatterlist *dst, struct scatterlist *src,
0085                   unsigned int nbytes)
0086 {
0087     struct blkcipher_walk walk;
0088     struct crypto_blkcipher *tfm = desc->tfm;
0089     struct crypto_ecb_ctx *ctx = crypto_blkcipher_ctx(tfm);
0090     struct crypto_cipher *child = ctx->child;
0091 
0092     blkcipher_walk_init(&walk, dst, src, nbytes);
0093     return crypto_ecb_crypt(desc, &walk, child,
0094                 crypto_cipher_alg(child)->cia_decrypt);
0095 }
0096 
0097 static int crypto_ecb_init_tfm(struct crypto_tfm *tfm)
0098 {
0099     struct crypto_instance *inst = (void *)tfm->__crt_alg;
0100     struct crypto_spawn *spawn = crypto_instance_ctx(inst);
0101     struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(tfm);
0102     struct crypto_cipher *cipher;
0103 
0104     cipher = crypto_spawn_cipher(spawn);
0105     if (IS_ERR(cipher))
0106         return PTR_ERR(cipher);
0107 
0108     ctx->child = cipher;
0109     return 0;
0110 }
0111 
0112 static void crypto_ecb_exit_tfm(struct crypto_tfm *tfm)
0113 {
0114     struct crypto_ecb_ctx *ctx = crypto_tfm_ctx(tfm);
0115     crypto_free_cipher(ctx->child);
0116 }
0117 
0118 static struct crypto_instance *crypto_ecb_alloc(struct rtattr **tb)
0119 {
0120     struct crypto_instance *inst;
0121     struct crypto_alg *alg;
0122     int err;
0123 
0124     err = crypto_check_attr_type(tb, CRYPTO_ALG_TYPE_BLKCIPHER);
0125     if (err)
0126         return ERR_PTR(err);
0127 
0128     alg = crypto_get_attr_alg(tb, CRYPTO_ALG_TYPE_CIPHER,
0129                   CRYPTO_ALG_TYPE_MASK);
0130     if (IS_ERR(alg))
0131         return ERR_CAST(alg);
0132 
0133     inst = crypto_alloc_instance("ecb", alg);
0134     if (IS_ERR(inst))
0135         goto out_put_alg;
0136 
0137     inst->alg.cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER;
0138     inst->alg.cra_priority = alg->cra_priority;
0139     inst->alg.cra_blocksize = alg->cra_blocksize;
0140     inst->alg.cra_alignmask = alg->cra_alignmask;
0141     inst->alg.cra_type = &crypto_blkcipher_type;
0142 
0143     inst->alg.cra_blkcipher.min_keysize = alg->cra_cipher.cia_min_keysize;
0144     inst->alg.cra_blkcipher.max_keysize = alg->cra_cipher.cia_max_keysize;
0145 
0146     inst->alg.cra_ctxsize = sizeof(struct crypto_ecb_ctx);
0147 
0148     inst->alg.cra_init = crypto_ecb_init_tfm;
0149     inst->alg.cra_exit = crypto_ecb_exit_tfm;
0150 
0151     inst->alg.cra_blkcipher.setkey = crypto_ecb_setkey;
0152     inst->alg.cra_blkcipher.encrypt = crypto_ecb_encrypt;
0153     inst->alg.cra_blkcipher.decrypt = crypto_ecb_decrypt;
0154 
0155 out_put_alg:
0156     crypto_mod_put(alg);
0157     return inst;
0158 }
0159 
0160 static void crypto_ecb_free(struct crypto_instance *inst)
0161 {
0162     crypto_drop_spawn(crypto_instance_ctx(inst));
0163     kfree(inst);
0164 }
0165 
0166 static struct crypto_template crypto_ecb_tmpl = {
0167     .name = "ecb",
0168     .alloc = crypto_ecb_alloc,
0169     .free = crypto_ecb_free,
0170     .module = THIS_MODULE,
0171 };
0172 
0173 static int __init crypto_ecb_module_init(void)
0174 {
0175     return crypto_register_template(&crypto_ecb_tmpl);
0176 }
0177 
0178 static void __exit crypto_ecb_module_exit(void)
0179 {
0180     crypto_unregister_template(&crypto_ecb_tmpl);
0181 }
0182 
0183 module_init(crypto_ecb_module_init);
0184 module_exit(crypto_ecb_module_exit);
0185 
0186 MODULE_LICENSE("GPL");
0187 MODULE_DESCRIPTION("ECB block cipher algorithm");
0188 MODULE_ALIAS_CRYPTO("ecb");