2 * FPU: Wrapper for blkcipher touching fpu
4 * Copyright (c) Intel Corp.
5 * Author: Huang Ying <ying.huang@intel.com>
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
14 #include <crypto/algapi.h>
15 #include <linux/err.h>
16 #include <linux/init.h>
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/slab.h>
22 struct crypto_fpu_ctx
{
23 struct crypto_blkcipher
*child
;
26 static int crypto_fpu_setkey(struct crypto_tfm
*parent
, const u8
*key
,
29 struct crypto_fpu_ctx
*ctx
= crypto_tfm_ctx(parent
);
30 struct crypto_blkcipher
*child
= ctx
->child
;
33 crypto_blkcipher_clear_flags(child
, CRYPTO_TFM_REQ_MASK
);
34 crypto_blkcipher_set_flags(child
, crypto_tfm_get_flags(parent
) &
36 err
= crypto_blkcipher_setkey(child
, key
, keylen
);
37 crypto_tfm_set_flags(parent
, crypto_blkcipher_get_flags(child
) &
42 static int crypto_fpu_encrypt(struct blkcipher_desc
*desc_in
,
43 struct scatterlist
*dst
, struct scatterlist
*src
,
47 struct crypto_fpu_ctx
*ctx
= crypto_blkcipher_ctx(desc_in
->tfm
);
48 struct crypto_blkcipher
*child
= ctx
->child
;
49 struct blkcipher_desc desc
= {
51 .info
= desc_in
->info
,
52 .flags
= desc_in
->flags
& ~CRYPTO_TFM_REQ_MAY_SLEEP
,
56 err
= crypto_blkcipher_crt(desc
.tfm
)->encrypt(&desc
, dst
, src
, nbytes
);
61 static int crypto_fpu_decrypt(struct blkcipher_desc
*desc_in
,
62 struct scatterlist
*dst
, struct scatterlist
*src
,
66 struct crypto_fpu_ctx
*ctx
= crypto_blkcipher_ctx(desc_in
->tfm
);
67 struct crypto_blkcipher
*child
= ctx
->child
;
68 struct blkcipher_desc desc
= {
70 .info
= desc_in
->info
,
71 .flags
= desc_in
->flags
& ~CRYPTO_TFM_REQ_MAY_SLEEP
,
75 err
= crypto_blkcipher_crt(desc
.tfm
)->decrypt(&desc
, dst
, src
, nbytes
);
80 static int crypto_fpu_init_tfm(struct crypto_tfm
*tfm
)
82 struct crypto_instance
*inst
= crypto_tfm_alg_instance(tfm
);
83 struct crypto_spawn
*spawn
= crypto_instance_ctx(inst
);
84 struct crypto_fpu_ctx
*ctx
= crypto_tfm_ctx(tfm
);
85 struct crypto_blkcipher
*cipher
;
87 cipher
= crypto_spawn_blkcipher(spawn
);
89 return PTR_ERR(cipher
);
95 static void crypto_fpu_exit_tfm(struct crypto_tfm
*tfm
)
97 struct crypto_fpu_ctx
*ctx
= crypto_tfm_ctx(tfm
);
98 crypto_free_blkcipher(ctx
->child
);
101 static struct crypto_instance
*crypto_fpu_alloc(struct rtattr
**tb
)
103 struct crypto_instance
*inst
;
104 struct crypto_alg
*alg
;
107 err
= crypto_check_attr_type(tb
, CRYPTO_ALG_TYPE_BLKCIPHER
);
111 alg
= crypto_get_attr_alg(tb
, CRYPTO_ALG_TYPE_BLKCIPHER
,
112 CRYPTO_ALG_TYPE_MASK
);
114 return ERR_CAST(alg
);
116 inst
= crypto_alloc_instance("fpu", alg
);
120 inst
->alg
.cra_flags
= alg
->cra_flags
;
121 inst
->alg
.cra_priority
= alg
->cra_priority
;
122 inst
->alg
.cra_blocksize
= alg
->cra_blocksize
;
123 inst
->alg
.cra_alignmask
= alg
->cra_alignmask
;
124 inst
->alg
.cra_type
= alg
->cra_type
;
125 inst
->alg
.cra_blkcipher
.ivsize
= alg
->cra_blkcipher
.ivsize
;
126 inst
->alg
.cra_blkcipher
.min_keysize
= alg
->cra_blkcipher
.min_keysize
;
127 inst
->alg
.cra_blkcipher
.max_keysize
= alg
->cra_blkcipher
.max_keysize
;
128 inst
->alg
.cra_ctxsize
= sizeof(struct crypto_fpu_ctx
);
129 inst
->alg
.cra_init
= crypto_fpu_init_tfm
;
130 inst
->alg
.cra_exit
= crypto_fpu_exit_tfm
;
131 inst
->alg
.cra_blkcipher
.setkey
= crypto_fpu_setkey
;
132 inst
->alg
.cra_blkcipher
.encrypt
= crypto_fpu_encrypt
;
133 inst
->alg
.cra_blkcipher
.decrypt
= crypto_fpu_decrypt
;
140 static void crypto_fpu_free(struct crypto_instance
*inst
)
142 crypto_drop_spawn(crypto_instance_ctx(inst
));
146 static struct crypto_template crypto_fpu_tmpl
= {
148 .alloc
= crypto_fpu_alloc
,
149 .free
= crypto_fpu_free
,
150 .module
= THIS_MODULE
,
153 static int __init
crypto_fpu_module_init(void)
155 return crypto_register_template(&crypto_fpu_tmpl
);
158 static void __exit
crypto_fpu_module_exit(void)
160 crypto_unregister_template(&crypto_fpu_tmpl
);
163 module_init(crypto_fpu_module_init
);
164 module_exit(crypto_fpu_module_exit
);
166 MODULE_LICENSE("GPL");
167 MODULE_DESCRIPTION("FPU block cipher wrapper");