crypto: seqiv - Add seqniv
[firefly-linux-kernel-4.4.55.git] / crypto / seqiv.c
index 27dbab8a80a914d6c22e22ff805dde9562cd5d56..a9bfbda4f36a809f34554224d997fa2afbe9241a 100644 (file)
@@ -584,6 +584,7 @@ static void seqiv_aead_exit(struct crypto_tfm *tfm)
 }
 
 static struct crypto_template seqiv_tmpl;
+static struct crypto_template seqniv_tmpl;
 
 static struct crypto_instance *seqiv_ablkcipher_alloc(struct rtattr **tb)
 {
@@ -710,6 +711,51 @@ put_rng:
        goto out;
 }
 
+static struct crypto_instance *seqniv_alloc(struct rtattr **tb)
+{
+       struct aead_instance *inst;
+       struct crypto_aead_spawn *spawn;
+       struct aead_alg *alg;
+       int err;
+
+       err = crypto_get_default_rng();
+       if (err)
+               return ERR_PTR(err);
+
+       inst = aead_geniv_alloc(&seqniv_tmpl, tb, 0, 0);
+
+       if (IS_ERR(inst))
+               goto put_rng;
+
+       if (inst->alg.ivsize < sizeof(u64)) {
+               aead_geniv_free(inst);
+               inst = ERR_PTR(-EINVAL);
+               goto put_rng;
+       }
+
+       spawn = aead_instance_ctx(inst);
+       alg = crypto_spawn_aead_alg(spawn);
+
+       inst->alg.setkey = seqiv_aead_setkey;
+       inst->alg.setauthsize = seqiv_aead_setauthsize;
+       inst->alg.encrypt = seqiv_aead_encrypt_compat_first;
+       inst->alg.decrypt = seqiv_aead_decrypt_compat;
+
+       inst->alg.base.cra_init = seqiv_aead_compat_init;
+       inst->alg.base.cra_exit = seqiv_aead_compat_exit;
+
+       inst->alg.base.cra_alignmask |= __alignof__(u32) - 1;
+       inst->alg.base.cra_ctxsize = sizeof(struct seqiv_aead_ctx);
+       inst->alg.base.cra_ctxsize += inst->alg.base.cra_aead.ivsize;
+
+out:
+       return aead_crypto_instance(inst);
+
+put_rng:
+       crypto_put_default_rng();
+       goto out;
+}
+
 static void seqiv_free(struct crypto_instance *inst)
 {
        if ((inst->alg.cra_flags ^ CRYPTO_ALG_TYPE_AEAD) & CRYPTO_ALG_TYPE_MASK)
@@ -726,9 +772,31 @@ static struct crypto_template seqiv_tmpl = {
        .module = THIS_MODULE,
 };
 
+static struct crypto_template seqniv_tmpl = {
+       .name = "seqniv",
+       .alloc = seqniv_alloc,
+       .free = seqiv_free,
+       .module = THIS_MODULE,
+};
+
 static int __init seqiv_module_init(void)
 {
-       return crypto_register_template(&seqiv_tmpl);
+       int err;
+
+       err = crypto_register_template(&seqiv_tmpl);
+       if (err)
+               goto out;
+
+       err = crypto_register_template(&seqniv_tmpl);
+       if (err)
+               goto out_undo_niv;
+
+out:
+       return err;
+
+out_undo_niv:
+       crypto_unregister_template(&seqiv_tmpl);
+       goto out;
 }
 
 static void __exit seqiv_module_exit(void)
@@ -742,3 +810,4 @@ module_exit(seqiv_module_exit);
 MODULE_LICENSE("GPL");
 MODULE_DESCRIPTION("Sequence Number IV Generator");
 MODULE_ALIAS_CRYPTO("seqiv");
+MODULE_ALIAS_CRYPTO("seqniv");