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>
20 #include <linux/crypto.h>
21 #include <asm/fpu/api.h>
23 struct crypto_fpu_ctx
{
24 struct crypto_blkcipher
*child
;
27 static int crypto_fpu_setkey(struct crypto_tfm
*parent
, const u8
*key
,
30 struct crypto_fpu_ctx
*ctx
= crypto_tfm_ctx(parent
);
31 struct crypto_blkcipher
*child
= ctx
->child
;
34 crypto_blkcipher_clear_flags(child
, CRYPTO_TFM_REQ_MASK
);
35 crypto_blkcipher_set_flags(child
, crypto_tfm_get_flags(parent
) &
37 err
= crypto_blkcipher_setkey(child
, key
, keylen
);
38 crypto_tfm_set_flags(parent
, crypto_blkcipher_get_flags(child
) &
43 static int crypto_fpu_encrypt(struct blkcipher_desc
*desc_in
,
44 struct scatterlist
*dst
, struct scatterlist
*src
,
48 struct crypto_fpu_ctx
*ctx
= crypto_blkcipher_ctx(desc_in
->tfm
);
49 struct crypto_blkcipher
*child
= ctx
->child
;
50 struct blkcipher_desc desc
= {
52 .info
= desc_in
->info
,
53 .flags
= desc_in
->flags
& ~CRYPTO_TFM_REQ_MAY_SLEEP
,
57 err
= crypto_blkcipher_crt(desc
.tfm
)->encrypt(&desc
, dst
, src
, nbytes
);
62 static int crypto_fpu_decrypt(struct blkcipher_desc
*desc_in
,
63 struct scatterlist
*dst
, struct scatterlist
*src
,
67 struct crypto_fpu_ctx
*ctx
= crypto_blkcipher_ctx(desc_in
->tfm
);
68 struct crypto_blkcipher
*child
= ctx
->child
;
69 struct blkcipher_desc desc
= {
71 .info
= desc_in
->info
,
72 .flags
= desc_in
->flags
& ~CRYPTO_TFM_REQ_MAY_SLEEP
,
76 err
= crypto_blkcipher_crt(desc
.tfm
)->decrypt(&desc
, dst
, src
, nbytes
);
81 static int crypto_fpu_init_tfm(struct crypto_tfm
*tfm
)
83 struct crypto_instance
*inst
= crypto_tfm_alg_instance(tfm
);
84 struct crypto_spawn
*spawn
= crypto_instance_ctx(inst
);
85 struct crypto_fpu_ctx
*ctx
= crypto_tfm_ctx(tfm
);
86 struct crypto_blkcipher
*cipher
;
88 cipher
= crypto_spawn_blkcipher(spawn
);
90 return PTR_ERR(cipher
);
96 static void crypto_fpu_exit_tfm(struct crypto_tfm
*tfm
)
98 struct crypto_fpu_ctx
*ctx
= crypto_tfm_ctx(tfm
);
99 crypto_free_blkcipher(ctx
->child
);
102 static struct crypto_instance
*crypto_fpu_alloc(struct rtattr
**tb
)
104 struct crypto_instance
*inst
;
105 struct crypto_alg
*alg
;
108 err
= crypto_check_attr_type(tb
, CRYPTO_ALG_TYPE_BLKCIPHER
);
112 alg
= crypto_get_attr_alg(tb
, CRYPTO_ALG_TYPE_BLKCIPHER
,
113 CRYPTO_ALG_TYPE_MASK
);
115 return ERR_CAST(alg
);
117 inst
= crypto_alloc_instance("fpu", alg
);
121 inst
->alg
.cra_flags
= alg
->cra_flags
;
122 inst
->alg
.cra_priority
= alg
->cra_priority
;
123 inst
->alg
.cra_blocksize
= alg
->cra_blocksize
;
124 inst
->alg
.cra_alignmask
= alg
->cra_alignmask
;
125 inst
->alg
.cra_type
= alg
->cra_type
;
126 inst
->alg
.cra_blkcipher
.ivsize
= alg
->cra_blkcipher
.ivsize
;
127 inst
->alg
.cra_blkcipher
.min_keysize
= alg
->cra_blkcipher
.min_keysize
;
128 inst
->alg
.cra_blkcipher
.max_keysize
= alg
->cra_blkcipher
.max_keysize
;
129 inst
->alg
.cra_ctxsize
= sizeof(struct crypto_fpu_ctx
);
130 inst
->alg
.cra_init
= crypto_fpu_init_tfm
;
131 inst
->alg
.cra_exit
= crypto_fpu_exit_tfm
;
132 inst
->alg
.cra_blkcipher
.setkey
= crypto_fpu_setkey
;
133 inst
->alg
.cra_blkcipher
.encrypt
= crypto_fpu_encrypt
;
134 inst
->alg
.cra_blkcipher
.decrypt
= crypto_fpu_decrypt
;
141 static void crypto_fpu_free(struct crypto_instance
*inst
)
143 crypto_drop_spawn(crypto_instance_ctx(inst
));
147 static struct crypto_template crypto_fpu_tmpl
= {
149 .alloc
= crypto_fpu_alloc
,
150 .free
= crypto_fpu_free
,
151 .module
= THIS_MODULE
,
154 int __init
crypto_fpu_init(void)
156 return crypto_register_template(&crypto_fpu_tmpl
);
159 void crypto_fpu_exit(void)
161 crypto_unregister_template(&crypto_fpu_tmpl
);
164 MODULE_ALIAS_CRYPTO("fpu");