Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.12 149 lines 4.3 kB view raw
1/* 2 * Shared async block cipher helpers 3 * 4 * Copyright (c) 2012 Jussi Kivilinna <jussi.kivilinna@mbnet.fi> 5 * 6 * Based on aesni-intel_glue.c by: 7 * Copyright (C) 2008, Intel Corp. 8 * Author: Huang Ying <ying.huang@intel.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 23 * USA 24 * 25 */ 26 27#include <linux/kernel.h> 28#include <linux/crypto.h> 29#include <linux/init.h> 30#include <linux/module.h> 31#include <crypto/algapi.h> 32#include <crypto/cryptd.h> 33#include <asm/i387.h> 34#include <asm/crypto/ablk_helper.h> 35 36int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, 37 unsigned int key_len) 38{ 39 struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); 40 struct crypto_ablkcipher *child = &ctx->cryptd_tfm->base; 41 int err; 42 43 crypto_ablkcipher_clear_flags(child, CRYPTO_TFM_REQ_MASK); 44 crypto_ablkcipher_set_flags(child, crypto_ablkcipher_get_flags(tfm) 45 & CRYPTO_TFM_REQ_MASK); 46 err = crypto_ablkcipher_setkey(child, key, key_len); 47 crypto_ablkcipher_set_flags(tfm, crypto_ablkcipher_get_flags(child) 48 & CRYPTO_TFM_RES_MASK); 49 return err; 50} 51EXPORT_SYMBOL_GPL(ablk_set_key); 52 53int __ablk_encrypt(struct ablkcipher_request *req) 54{ 55 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 56 struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); 57 struct blkcipher_desc desc; 58 59 desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); 60 desc.info = req->info; 61 desc.flags = 0; 62 63 return crypto_blkcipher_crt(desc.tfm)->encrypt( 64 &desc, req->dst, req->src, req->nbytes); 65} 66EXPORT_SYMBOL_GPL(__ablk_encrypt); 67 68int ablk_encrypt(struct ablkcipher_request *req) 69{ 70 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 71 struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); 72 73 if (!irq_fpu_usable()) { 74 struct ablkcipher_request *cryptd_req = 75 ablkcipher_request_ctx(req); 76 77 memcpy(cryptd_req, req, sizeof(*req)); 78 ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 79 80 return crypto_ablkcipher_encrypt(cryptd_req); 81 } else { 82 return __ablk_encrypt(req); 83 } 84} 85EXPORT_SYMBOL_GPL(ablk_encrypt); 86 87int ablk_decrypt(struct ablkcipher_request *req) 88{ 89 struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(req); 90 struct async_helper_ctx *ctx = crypto_ablkcipher_ctx(tfm); 91 92 if (!irq_fpu_usable()) { 93 struct ablkcipher_request *cryptd_req = 94 ablkcipher_request_ctx(req); 95 96 memcpy(cryptd_req, req, sizeof(*req)); 97 ablkcipher_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); 98 99 return crypto_ablkcipher_decrypt(cryptd_req); 100 } else { 101 struct blkcipher_desc desc; 102 103 desc.tfm = cryptd_ablkcipher_child(ctx->cryptd_tfm); 104 desc.info = req->info; 105 desc.flags = 0; 106 107 return crypto_blkcipher_crt(desc.tfm)->decrypt( 108 &desc, req->dst, req->src, req->nbytes); 109 } 110} 111EXPORT_SYMBOL_GPL(ablk_decrypt); 112 113void ablk_exit(struct crypto_tfm *tfm) 114{ 115 struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); 116 117 cryptd_free_ablkcipher(ctx->cryptd_tfm); 118} 119EXPORT_SYMBOL_GPL(ablk_exit); 120 121int ablk_init_common(struct crypto_tfm *tfm, const char *drv_name) 122{ 123 struct async_helper_ctx *ctx = crypto_tfm_ctx(tfm); 124 struct cryptd_ablkcipher *cryptd_tfm; 125 126 cryptd_tfm = cryptd_alloc_ablkcipher(drv_name, 0, 0); 127 if (IS_ERR(cryptd_tfm)) 128 return PTR_ERR(cryptd_tfm); 129 130 ctx->cryptd_tfm = cryptd_tfm; 131 tfm->crt_ablkcipher.reqsize = sizeof(struct ablkcipher_request) + 132 crypto_ablkcipher_reqsize(&cryptd_tfm->base); 133 134 return 0; 135} 136EXPORT_SYMBOL_GPL(ablk_init_common); 137 138int ablk_init(struct crypto_tfm *tfm) 139{ 140 char drv_name[CRYPTO_MAX_ALG_NAME]; 141 142 snprintf(drv_name, sizeof(drv_name), "__driver-%s", 143 crypto_tfm_alg_driver_name(tfm)); 144 145 return ablk_init_common(tfm, drv_name); 146} 147EXPORT_SYMBOL_GPL(ablk_init); 148 149MODULE_LICENSE("GPL");