]> nv-tegra.nvidia Code Review - linux-3.10.git/blobdiff - crypto/ablkcipher.c
[CRYPTO] skcipher: Add givcrypt operations and givcipher type
[linux-3.10.git] / crypto / ablkcipher.c
index 3dbb1cc6eab52f5eeba3767f52a6e8225c8d4173..e403d8137ecd01cdb81e05a62ab03547ee6dec0e 100644 (file)
  *
  */
 
-#include <crypto/algapi.h>
-#include <linux/errno.h>
+#include <crypto/internal/skcipher.h>
+#include <linux/err.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/slab.h>
 #include <linux/seq_file.h>
 
-static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int keylen)
+#include "internal.h"
+
+static int setkey_unaligned(struct crypto_ablkcipher *tfm, const u8 *key,
+                           unsigned int keylen)
 {
        struct ablkcipher_alg *cipher = crypto_ablkcipher_alg(tfm);
        unsigned long alignmask = crypto_ablkcipher_alignmask(tfm);
@@ -91,10 +96,6 @@ static void crypto_ablkcipher_show(struct seq_file *m, struct crypto_alg *alg)
        seq_printf(m, "min keysize  : %u\n", ablkcipher->min_keysize);
        seq_printf(m, "max keysize  : %u\n", ablkcipher->max_keysize);
        seq_printf(m, "ivsize       : %u\n", ablkcipher->ivsize);
-       if (ablkcipher->queue) {
-               seq_printf(m, "qlen         : %u\n", ablkcipher->queue->qlen);
-               seq_printf(m, "max qlen     : %u\n", ablkcipher->queue->max_qlen);
-       }
 }
 
 const struct crypto_type crypto_ablkcipher_type = {
@@ -106,5 +107,70 @@ const struct crypto_type crypto_ablkcipher_type = {
 };
 EXPORT_SYMBOL_GPL(crypto_ablkcipher_type);
 
+static int no_givdecrypt(struct skcipher_givcrypt_request *req)
+{
+       return -ENOSYS;
+}
+
+static int crypto_init_givcipher_ops(struct crypto_tfm *tfm, u32 type,
+                                     u32 mask)
+{
+       struct ablkcipher_alg *alg = &tfm->__crt_alg->cra_ablkcipher;
+       struct ablkcipher_tfm *crt = &tfm->crt_ablkcipher;
+
+       if (alg->ivsize > PAGE_SIZE / 8)
+               return -EINVAL;
+
+       crt->setkey = setkey;
+       crt->encrypt = alg->encrypt;
+       crt->decrypt = alg->decrypt;
+       crt->givencrypt = alg->givencrypt;
+       crt->givdecrypt = alg->givdecrypt ?: no_givdecrypt;
+       crt->ivsize = alg->ivsize;
+
+       return 0;
+}
+
+static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
+       __attribute__ ((unused));
+static void crypto_givcipher_show(struct seq_file *m, struct crypto_alg *alg)
+{
+       struct ablkcipher_alg *ablkcipher = &alg->cra_ablkcipher;
+
+       seq_printf(m, "type         : givcipher\n");
+       seq_printf(m, "blocksize    : %u\n", alg->cra_blocksize);
+       seq_printf(m, "min keysize  : %u\n", ablkcipher->min_keysize);
+       seq_printf(m, "max keysize  : %u\n", ablkcipher->max_keysize);
+       seq_printf(m, "ivsize       : %u\n", ablkcipher->ivsize);
+}
+
+const struct crypto_type crypto_givcipher_type = {
+       .ctxsize = crypto_ablkcipher_ctxsize,
+       .init = crypto_init_givcipher_ops,
+#ifdef CONFIG_PROC_FS
+       .show = crypto_givcipher_show,
+#endif
+};
+EXPORT_SYMBOL_GPL(crypto_givcipher_type);
+
+int crypto_grab_skcipher(struct crypto_skcipher_spawn *spawn, const char *name,
+                        u32 type, u32 mask)
+{
+       struct crypto_alg *alg;
+       int err;
+
+       type = crypto_skcipher_type(type);
+       mask = crypto_skcipher_mask(mask);
+
+       alg = crypto_alg_mod_lookup(name, type, mask);
+       if (IS_ERR(alg))
+               return PTR_ERR(alg);
+
+       err = crypto_init_spawn(&spawn->base, alg, spawn->base.inst, mask);
+       crypto_mod_put(alg);
+       return err;
+}
+EXPORT_SYMBOL_GPL(crypto_grab_skcipher);
+
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Asynchronous block chaining cipher type");