Signed-off-by: Dmitry Kasatkin <dmitry.kasat...@nokia.com> --- cryptodev.h | 85 ++++++------ cryptodev_cipher.c | 109 +++++++++------- cryptodev_int.h | 50 ++++--- cryptodev_main.c | 367 ++++++++++++++++++++++++++++------------------------ 4 files changed, 330 insertions(+), 281 deletions(-)
diff --git a/cryptodev.h b/cryptodev.h index 34537d0..ea6503f 100644 --- a/cryptodev.h +++ b/cryptodev.h @@ -1,4 +1,4 @@ -/* This is a source compatible implementation with the original API of +/* This is a source compatible implementation with the original API of * cryptodev by Angelos D. Keromytis, found at openbsd cryptodev.h. * Placed under public domain */ @@ -16,38 +16,39 @@ /* All the supported algorithms */ -typedef enum { - CRYPTO_DES_CBC=1, - CRYPTO_3DES_CBC=2, - CRYPTO_BLF_CBC=3, - CRYPTO_CAST_CBC=4, - CRYPTO_SKIPJACK_CBC=5, - CRYPTO_MD5_HMAC=6, - CRYPTO_SHA1_HMAC=7, - CRYPTO_RIPEMD160_HMAC=8, - CRYPTO_MD5_KPDK=9, - CRYPTO_SHA1_KPDK=10, - CRYPTO_RIJNDAEL128_CBC=11, - CRYPTO_AES_CBC=CRYPTO_RIJNDAEL128_CBC, - CRYPTO_ARC4=12, - CRYPTO_MD5=13, - CRYPTO_SHA1=14, - CRYPTO_DEFLATE_COMP=15, - CRYPTO_NULL=16, - CRYPTO_LZS_COMP=17, - CRYPTO_SHA2_256_HMAC=18, - CRYPTO_SHA2_384_HMAC=19, - CRYPTO_SHA2_512_HMAC=20, - CRYPTO_AES_CTR=21, - CRYPTO_AES_XTS=22, - - CRYPTO_CAMELLIA_CBC=101, +enum cryptodev_crypto_op_t { + CRYPTO_DES_CBC = 1, + CRYPTO_3DES_CBC = 2, + CRYPTO_BLF_CBC = 3, + CRYPTO_CAST_CBC = 4, + CRYPTO_SKIPJACK_CBC = 5, + CRYPTO_MD5_HMAC = 6, + CRYPTO_SHA1_HMAC = 7, + CRYPTO_RIPEMD160_HMAC = 8, + CRYPTO_MD5_KPDK = 9, + CRYPTO_SHA1_KPDK = 10, + CRYPTO_RIJNDAEL128_CBC = 11, + CRYPTO_AES_CBC = CRYPTO_RIJNDAEL128_CBC, + CRYPTO_ARC4 = 12, + CRYPTO_MD5 = 13, + CRYPTO_SHA1 = 14, + CRYPTO_DEFLATE_COMP = 15, + CRYPTO_NULL = 16, + CRYPTO_LZS_COMP = 17, + CRYPTO_SHA2_256_HMAC = 18, + CRYPTO_SHA2_384_HMAC = 19, + CRYPTO_SHA2_512_HMAC = 20, + CRYPTO_AES_CTR = 21, + CRYPTO_AES_XTS = 22, + + CRYPTO_CAMELLIA_CBC = 101, CRYPTO_RIPEMD160, CRYPTO_SHA2_256, CRYPTO_SHA2_384, CRYPTO_SHA2_512, CRYPTO_ALGORITHM_ALL, /* Keep updated - see below */ -} cryptodev_crypto_op_t; +}; + #define CRYPTO_ALGORITHM_MAX (CRYPTO_ALGORITHM_ALL - 1) /* Values for ciphers */ @@ -90,10 +91,12 @@ struct session_op { __u16 op; /* COP_ENCRYPT or COP_DECRYPT */ __u16 flags; /* no usage so far, use 0 */ __u32 len; /* length of source data */ - __u8 __user *src; /* source data */ - __u8 __user *dst; /* pointer to output data */ - __u8 __user *mac; /* pointer to output data for hash/MAC operations */ - __u8 __user *iv; /* initialization vector for encryption operations */ + __u8 __user *src; /* source data */ + __u8 __user *dst; /* pointer to output data */ + /* pointer to output data for hash/MAC operations */ + __u8 __user *mac; + /* initialization vector for encryption operations */ + __u8 __user *iv; }; /* struct crypt_op flags */ @@ -110,7 +113,7 @@ struct session_op { #define CRYPTO_ALG_FLAG_DSA_SHA 4 struct crparam { - __u8* crp_p; + __u8 *crp_p; __u32 crp_nbits; }; @@ -126,16 +129,16 @@ struct crypt_kop { struct crparam crk_param[CRK_MAXPARAM]; }; -typedef enum { - CRK_MOD_EXP=0, - CRK_MOD_EXP_CRT=1, - CRK_DSA_SIGN=2, - CRK_DSA_VERIFY=3, - CRK_DH_COMPUTE_KEY=4, +enum cryptodev_crk_op_t { + CRK_MOD_EXP = 0, + CRK_MOD_EXP_CRT = 1, + CRK_DSA_SIGN = 2, + CRK_DSA_VERIFY = 3, + CRK_DH_COMPUTE_KEY = 4, CRK_ALGORITHM_ALL -} cryptodev_crk_op_t; +}; -#define CRK_ALGORITHM_MAX CRK_ALGORITHM_ALL-1 +#define CRK_ALGORITHM_MAX (CRK_ALGORITHM_ALL-1) /* features to be queried with CIOCASYMFEAT ioctl */ diff --git a/cryptodev_cipher.c b/cryptodev_cipher.c index 5377ba3..b214aee 100644 --- a/cryptodev_cipher.c +++ b/cryptodev_cipher.c @@ -11,15 +11,16 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include <linux/crypto.h> @@ -51,17 +52,18 @@ static void cryptodev_complete(struct crypto_async_request *req, int err) complete(&res->completion); } -int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t * keyp, size_t keylen) +int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name, + uint8_t *keyp, size_t keylen) { - struct ablkcipher_alg* alg; + struct ablkcipher_alg *alg; int ret; memset(out, 0, sizeof(*out)); out->async.s = crypto_alloc_ablkcipher(alg_name, 0, 0); if (unlikely(IS_ERR(out->async.s))) { - dprintk(1,KERN_DEBUG,"%s: Failed to load cipher %s\n", __func__, - alg_name); + dprintk(1, KERN_DEBUG, "%s: Failed to load cipher %s\n", + __func__, alg_name); return -EINVAL; } @@ -69,10 +71,13 @@ int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t if (alg != NULL) { /* Was correct key length supplied? */ - if (alg->max_keysize > 0 && unlikely((keylen < alg->min_keysize) || - (keylen > alg->max_keysize))) { - dprintk(1,KERN_DEBUG,"Wrong keylen '%zu' for algorithm '%s'. Use %u to %u.\n", - keylen, alg_name, alg->min_keysize, + if (alg->max_keysize > 0 && + unlikely((keylen < alg->min_keysize) || + (keylen > alg->max_keysize))) { + dprintk(1, KERN_DEBUG, + "Wrong keylen '%zu' for algorithm '%s'. \ + Use %u to %u.\n", + keylen, alg_name, alg->min_keysize, alg->max_keysize); ret = -EINVAL; goto error; @@ -81,7 +86,7 @@ int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t ret = crypto_ablkcipher_setkey(out->async.s, keyp, keylen); if (unlikely(ret)) { - dprintk(1,KERN_DEBUG,"Setting key failed for %s-%zu.\n", + dprintk(1, KERN_DEBUG, "Setting key failed for %s-%zu.\n", alg_name, keylen*8); ret = -EINVAL; goto error; @@ -101,12 +106,13 @@ int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t out->async.request = ablkcipher_request_alloc(out->async.s, GFP_KERNEL); if (unlikely(!out->async.request)) { - dprintk(1,KERN_ERR,"error allocating async crypto request\n"); + dprintk(1, KERN_ERR, "error allocating async crypto request\n"); ret = -ENOMEM; goto error; } - ablkcipher_request_set_callback(out->async.request, CRYPTO_TFM_REQ_MAY_BACKLOG, + ablkcipher_request_set_callback(out->async.request, + CRYPTO_TFM_REQ_MAY_BACKLOG, cryptodev_complete, out->async.result); out->init = 1; @@ -121,7 +127,7 @@ error: return ret; } -void cryptodev_cipher_deinit(struct cipher_data* cdata) +void cryptodev_cipher_deinit(struct cipher_data *cdata) { if (cdata->init) { if (cdata->async.request) @@ -134,12 +140,13 @@ void cryptodev_cipher_deinit(struct cipher_data* cdata) } } -void cryptodev_cipher_set_iv(struct cipher_data* cdata, void *iv, size_t iv_size) +void cryptodev_cipher_set_iv(struct cipher_data *cdata, + void *iv, size_t iv_size) { - memcpy(cdata->async.iv, iv, min(iv_size,sizeof(cdata->async.iv))); + memcpy(cdata->async.iv, iv, min(iv_size, sizeof(cdata->async.iv))); } -static inline int waitfor (struct cryptodev_result* cr, ssize_t ret) +static inline int waitfor(struct cryptodev_result *cr, ssize_t ret) { switch (ret) { case 0: @@ -154,8 +161,9 @@ static inline int waitfor (struct cryptodev_result* cr, ssize_t ret) * another request. */ if (unlikely(cr->err)) { - dprintk(0,KERN_ERR,"error from async request: %d \n", cr->err); - return cr->err; + dprintk(0, KERN_ERR, "error from async request: %d\n", + cr->err); + return cr->err; } break; @@ -166,24 +174,30 @@ static inline int waitfor (struct cryptodev_result* cr, ssize_t ret) return 0; } -ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len) +ssize_t cryptodev_cipher_encrypt(struct cipher_data *cdata, + const struct scatterlist *sg1, struct scatterlist *sg2, + size_t len) { int ret; INIT_COMPLETION(cdata->async.result->completion); - ablkcipher_request_set_crypt(cdata->async.request, (struct scatterlist*)sg1, sg2, + ablkcipher_request_set_crypt(cdata->async.request, + (struct scatterlist *)sg1, sg2, len, cdata->async.iv); ret = crypto_ablkcipher_encrypt(cdata->async.request); - return waitfor(cdata->async.result,ret); + return waitfor(cdata->async.result, ret); } -ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len) +ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata, + const struct scatterlist *sg1, struct scatterlist *sg2, + size_t len) { int ret; INIT_COMPLETION(cdata->async.result->completion); - ablkcipher_request_set_crypt(cdata->async.request, (struct scatterlist*)sg1, sg2, + ablkcipher_request_set_crypt(cdata->async.request, + (struct scatterlist *)sg1, sg2, len, cdata->async.iv); ret = crypto_ablkcipher_decrypt(cdata->async.request); @@ -192,14 +206,15 @@ ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, const struct scatte /* Hash functions */ -int cryptodev_hash_init( struct hash_data* hdata, const char* alg_name, int hmac_mode, void * mackey, size_t mackeylen) +int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name, + int hmac_mode, void *mackey, size_t mackeylen) { -int ret; + int ret; hdata->async.s = crypto_alloc_ahash(alg_name, 0, 0); if (unlikely(IS_ERR(hdata->async.s))) { - dprintk(1,KERN_DEBUG,"%s: Failed to load transform for %s\n", __func__, - alg_name); + dprintk(1, KERN_DEBUG, "%s: Failed to load transform for %s\n", + __func__, alg_name); return -EINVAL; } @@ -207,7 +222,8 @@ int ret; if (hmac_mode != 0) { ret = crypto_ahash_setkey(hdata->async.s, mackey, mackeylen); if (unlikely(ret)) { - dprintk(1,KERN_DEBUG,"Setting hmac key failed for %s-%zu.\n", + dprintk(1, KERN_DEBUG, + "Setting hmac key failed for %s-%zu.\n", alg_name, mackeylen*8); ret = -EINVAL; goto error; @@ -227,18 +243,18 @@ int ret; hdata->async.request = ahash_request_alloc(hdata->async.s, GFP_KERNEL); if (unlikely(!hdata->async.request)) { - dprintk(0,KERN_ERR,"error allocating async crypto request\n"); + dprintk(0, KERN_ERR, "error allocating async crypto request\n"); ret = -ENOMEM; goto error; } - ahash_request_set_callback(hdata->async.request, CRYPTO_TFM_REQ_MAY_BACKLOG, - cryptodev_complete, hdata->async.result); + ahash_request_set_callback(hdata->async.request, + CRYPTO_TFM_REQ_MAY_BACKLOG, + cryptodev_complete, hdata->async.result); ret = crypto_ahash_init(hdata->async.request); if (unlikely(ret)) { - dprintk(0,KERN_ERR, - "error in crypto_hash_init()\n"); + dprintk(0, KERN_ERR, "error in crypto_hash_init()\n"); goto error_request; } @@ -253,7 +269,7 @@ error: return ret; } -void cryptodev_hash_deinit(struct hash_data* hdata) +void cryptodev_hash_deinit(struct hash_data *hdata) { if (hdata->init) { if (hdata->async.request) @@ -265,13 +281,13 @@ void cryptodev_hash_deinit(struct hash_data* hdata) } } -int cryptodev_hash_reset( struct hash_data* hdata) +int cryptodev_hash_reset(struct hash_data *hdata) { -int ret; + int ret; + ret = crypto_ahash_init(hdata->async.request); if (unlikely(ret)) { - dprintk(0,KERN_ERR, - "error in crypto_hash_init()\n"); + dprintk(0, KERN_ERR, "error in crypto_hash_init()\n"); return ret; } @@ -279,20 +295,20 @@ int ret; } -ssize_t cryptodev_hash_update( struct hash_data* hdata, struct scatterlist *sg, size_t len) +ssize_t cryptodev_hash_update(struct hash_data *hdata, + struct scatterlist *sg, size_t len) { int ret; INIT_COMPLETION(hdata->async.result->completion); - ahash_request_set_crypt(hdata->async.request, sg, NULL, - len); + ahash_request_set_crypt(hdata->async.request, sg, NULL, len); ret = crypto_ahash_update(hdata->async.request); - return waitfor(hdata->async.result,ret); + return waitfor(hdata->async.result, ret); } -int cryptodev_hash_final( struct hash_data* hdata, void* output) +int cryptodev_hash_final(struct hash_data *hdata, void* output) { int ret; @@ -301,5 +317,6 @@ int cryptodev_hash_final( struct hash_data* hdata, void* output) ret = crypto_ahash_final(hdata->async.request); - return waitfor(hdata->async.result,ret); + return waitfor(hdata->async.result, ret); } + diff --git a/cryptodev_int.h b/cryptodev_int.h index 1bf309c..15eb5bf 100644 --- a/cryptodev_int.h +++ b/cryptodev_int.h @@ -14,9 +14,9 @@ #include "cryptodev.h" #define PFX "cryptodev: " -#define dprintk(level,severity,format,a...) \ - do { \ - if (level <= cryptodev_verbosity) \ +#define dprintk(level, severity, format, a...) \ + do { \ + if (level <= cryptodev_verbosity) \ printk(severity PFX "%s[%u]: " format, \ current->comm, current->pid, \ ##a); \ @@ -31,34 +31,38 @@ void release_user_pages(struct page **pg, int pagecount); /* last page - first page + 1 */ #define PAGECOUNT(buf, buflen) \ - ((((unsigned long)(buf + buflen - 1) & PAGE_MASK) >> PAGE_SHIFT) - \ - (((unsigned long) buf & PAGE_MASK) >> PAGE_SHIFT) + 1) + ((((unsigned long)(buf + buflen - 1) & PAGE_MASK) >> PAGE_SHIFT) - \ + (((unsigned long) buf & PAGE_MASK) >> PAGE_SHIFT) + 1) #define DEFAULT_PREALLOC_PAGES 32 -struct cipher_data -{ +struct cipher_data { int init; /* 0 uninitialized */ int blocksize; int ivsize; struct { - struct crypto_ablkcipher* s; + struct crypto_ablkcipher *s; struct cryptodev_result *result; struct ablkcipher_request *request; uint8_t iv[EALG_MAX_BLOCK_LEN]; } async; }; -int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t * key, size_t keylen); -void cryptodev_cipher_deinit(struct cipher_data* cdata); -ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len); -ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, const struct scatterlist *sg1, struct scatterlist *sg2, size_t len); +int cryptodev_cipher_init(struct cipher_data *out, const char *alg_name, + uint8_t *key, size_t keylen); +void cryptodev_cipher_deinit(struct cipher_data *cdata); +ssize_t cryptodev_cipher_decrypt(struct cipher_data *cdata, + const struct scatterlist *sg1, + struct scatterlist *sg2, size_t len); +ssize_t cryptodev_cipher_encrypt(struct cipher_data *cdata, + const struct scatterlist *sg1, + struct scatterlist *sg2, size_t len); -void cryptodev_cipher_set_iv(struct cipher_data* cdata, void* iv, size_t iv_size); +void cryptodev_cipher_set_iv(struct cipher_data *cdata, + void *iv, size_t iv_size); /* hash stuff */ -struct hash_data -{ +struct hash_data { int init; /* 0 uninitialized */ int digestsize; struct { @@ -68,11 +72,13 @@ struct hash_data } async; }; -int cryptodev_hash_final( struct hash_data* hdata, void* output); -ssize_t cryptodev_hash_update( struct hash_data* hdata, struct scatterlist *sg, size_t len); -int cryptodev_hash_reset( struct hash_data* hdata); -void cryptodev_hash_deinit(struct hash_data* hdata); -int cryptodev_hash_init( struct hash_data* hdata, const char* alg_name, int hmac_mode, void* mackey, size_t mackeylen); +int cryptodev_hash_final(struct hash_data *hdata, void *output); +ssize_t cryptodev_hash_update(struct hash_data *hdata, + struct scatterlist *sg, size_t len); +int cryptodev_hash_reset(struct hash_data *hdata); +void cryptodev_hash_deinit(struct hash_data *hdata); +int cryptodev_hash_init(struct hash_data *hdata, const char *alg_name, + int hmac_mode, void *mackey, size_t mackeylen); /* compatibility stuff */ #ifdef CONFIG_COMPAT @@ -101,8 +107,8 @@ struct compat_session_op { uint32_t len; /* length of source data */ compat_uptr_t src; /* source data */ compat_uptr_t dst; /* pointer to output data */ - compat_uptr_t mac; /* pointer to output data for hash/MAC operations */ - compat_uptr_t iv; /* initialization vector for encryption operations */ + compat_uptr_t mac;/* pointer to output data for hash/MAC operations */ + compat_uptr_t iv;/* initialization vector for encryption operations */ }; /* compat ioctls, defined for the above structs */ diff --git a/cryptodev_main.c b/cryptodev_main.c index 35b90cc..d29660f 100644 --- a/cryptodev_main.c +++ b/cryptodev_main.c @@ -10,15 +10,16 @@ * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ /* @@ -54,12 +55,12 @@ MODULE_LICENSE("GPL"); /* ====== Module parameters ====== */ -int cryptodev_verbosity = 0; +int cryptodev_verbosity; module_param(cryptodev_verbosity, int, 0644); MODULE_PARM_DESC(cryptodev_verbosity, "0: normal, 1: verbose, 2: debug"); #ifdef CRYPTODEV_STATS -static int enable_stats = 0; +static int enable_stats; module_param(enable_stats, int, 0644); MODULE_PARM_DESC(enable_stats, "collect statictics about cryptodev usage"); #endif @@ -71,11 +72,10 @@ struct fcrypt { }; struct crypt_priv { - void * ncr; struct fcrypt fcrypt; }; -#define FILL_SG(sg,ptr,len) \ +#define FILL_SG(sg, ptr, len) \ do { \ (sg)->page = virt_to_page(ptr); \ (sg)->offset = offset_in_page(ptr); \ @@ -90,7 +90,7 @@ struct csession { struct hash_data hdata; uint32_t sid; #ifdef CRYPTODEV_STATS -#if ! ((COP_ENCRYPT < 2) && (COP_DECRYPT < 2)) +#if !((COP_ENCRYPT < 2) && (COP_DECRYPT < 2)) #error Struct csession.stat uses COP_{ENCRYPT,DECRYPT} as indices. Do something! #endif unsigned long long stat[2]; @@ -107,110 +107,112 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) { struct csession *ses_new = NULL, *ses_ptr; int ret = 0; - const char *alg_name=NULL; - const char *hash_name=NULL; + const char *alg_name = NULL; + const char *hash_name = NULL; int hmac_mode = 1; /* Does the request make sense? */ if (unlikely(!sop->cipher && !sop->mac)) { - dprintk(1,KERN_DEBUG,"Both 'cipher' and 'mac' unset.\n"); + dprintk(1, KERN_DEBUG, "Both 'cipher' and 'mac' unset.\n"); return -EINVAL; } switch (sop->cipher) { - case 0: - break; - case CRYPTO_DES_CBC: - alg_name = "cbc(des)"; - break; - case CRYPTO_3DES_CBC: - alg_name = "cbc(des3_ede)"; - break; - case CRYPTO_BLF_CBC: - alg_name = "cbc(blowfish)"; - break; - case CRYPTO_AES_CBC: - alg_name = "cbc(aes)"; - break; - case CRYPTO_CAMELLIA_CBC: - alg_name = "cbc(camelia)"; - break; - case CRYPTO_AES_CTR: - alg_name = "ctr(aes)"; - break; - case CRYPTO_NULL: - alg_name = "ecb(cipher_null)"; - break; - default: - dprintk(1,KERN_DEBUG,"%s: bad cipher: %d\n", __func__, sop->cipher); - return -EINVAL; + case 0: + break; + case CRYPTO_DES_CBC: + alg_name = "cbc(des)"; + break; + case CRYPTO_3DES_CBC: + alg_name = "cbc(des3_ede)"; + break; + case CRYPTO_BLF_CBC: + alg_name = "cbc(blowfish)"; + break; + case CRYPTO_AES_CBC: + alg_name = "cbc(aes)"; + break; + case CRYPTO_CAMELLIA_CBC: + alg_name = "cbc(camelia)"; + break; + case CRYPTO_AES_CTR: + alg_name = "ctr(aes)"; + break; + case CRYPTO_NULL: + alg_name = "ecb(cipher_null)"; + break; + default: + dprintk(1, KERN_DEBUG, "%s: bad cipher: %d\n", __func__, + sop->cipher); + return -EINVAL; } switch (sop->mac) { - case 0: - break; - case CRYPTO_MD5_HMAC: - hash_name = "hmac(md5)"; - break; - case CRYPTO_RIPEMD160_HMAC: - hash_name = "hmac(rmd160)"; - break; - case CRYPTO_SHA1_HMAC: - hash_name = "hmac(sha1)"; - break; - case CRYPTO_SHA2_256_HMAC: - hash_name = "hmac(sha256)"; - break; - case CRYPTO_SHA2_384_HMAC: - hash_name = "hmac(sha384)"; - break; - case CRYPTO_SHA2_512_HMAC: - hash_name = "hmac(sha512)"; - break; - - /* non-hmac cases */ - case CRYPTO_MD5: - hash_name = "md5"; - hmac_mode = 0; - break; - case CRYPTO_RIPEMD160: - hash_name = "rmd160"; - hmac_mode = 0; - break; - case CRYPTO_SHA1: - hash_name = "sha1"; - hmac_mode = 0; - break; - case CRYPTO_SHA2_256: - hash_name = "sha256"; - hmac_mode = 0; - break; - case CRYPTO_SHA2_384: - hash_name = "sha384"; - hmac_mode = 0; - break; - case CRYPTO_SHA2_512: - hash_name = "sha512"; - hmac_mode = 0; - break; + case 0: + break; + case CRYPTO_MD5_HMAC: + hash_name = "hmac(md5)"; + break; + case CRYPTO_RIPEMD160_HMAC: + hash_name = "hmac(rmd160)"; + break; + case CRYPTO_SHA1_HMAC: + hash_name = "hmac(sha1)"; + break; + case CRYPTO_SHA2_256_HMAC: + hash_name = "hmac(sha256)"; + break; + case CRYPTO_SHA2_384_HMAC: + hash_name = "hmac(sha384)"; + break; + case CRYPTO_SHA2_512_HMAC: + hash_name = "hmac(sha512)"; + break; + + /* non-hmac cases */ + case CRYPTO_MD5: + hash_name = "md5"; + hmac_mode = 0; + break; + case CRYPTO_RIPEMD160: + hash_name = "rmd160"; + hmac_mode = 0; + break; + case CRYPTO_SHA1: + hash_name = "sha1"; + hmac_mode = 0; + break; + case CRYPTO_SHA2_256: + hash_name = "sha256"; + hmac_mode = 0; + break; + case CRYPTO_SHA2_384: + hash_name = "sha384"; + hmac_mode = 0; + break; + case CRYPTO_SHA2_512: + hash_name = "sha512"; + hmac_mode = 0; + break; - default: - dprintk(1,KERN_DEBUG,"%s: bad mac: %d\n", __func__, sop->mac); - return -EINVAL; + default: + dprintk(1, KERN_DEBUG, "%s: bad mac: %d\n", __func__, + sop->mac); + return -EINVAL; } /* Create a session and put it to the list. */ ses_new = kzalloc(sizeof(*ses_new), GFP_KERNEL); - if(!ses_new) { + if (!ses_new) return -ENOMEM; - } /* Set-up crypto transform. */ if (alg_name) { uint8_t keyp[CRYPTO_CIPHER_MAX_KEY_LEN]; if (unlikely(sop->keylen > CRYPTO_CIPHER_MAX_KEY_LEN)) { - dprintk(1,KERN_DEBUG,"Setting key failed for %s-%zu.\n", + dprintk(1, KERN_DEBUG, + "Setting key failed for %s-%zu.\n", alg_name, (size_t)sop->keylen*8); ret = -EINVAL; goto error_cipher; @@ -221,10 +223,12 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) goto error_cipher; } - ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, keyp, sop->keylen); + ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, keyp, + sop->keylen); if (ret < 0) { - dprintk(1,KERN_DEBUG,"%s: Failed to load cipher for %s\n", __func__, - alg_name); + dprintk(1, KERN_DEBUG, + "%s: Failed to load cipher for %s\n", + __func__, alg_name); ret = -EINVAL; goto error_cipher; } @@ -234,22 +238,25 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) uint8_t keyp[CRYPTO_HMAC_MAX_KEY_LEN]; if (unlikely(sop->mackeylen > CRYPTO_HMAC_MAX_KEY_LEN)) { - dprintk(1,KERN_DEBUG,"Setting key failed for %s-%zu.\n", + dprintk(1, KERN_DEBUG, + "Setting key failed for %s-%zu.\n", alg_name, (size_t)sop->mackeylen*8); ret = -EINVAL; goto error_hash; } - + if (unlikely(copy_from_user(keyp, sop->mackey, sop->mackeylen))) { ret = -EFAULT; goto error_hash; } - ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode, keyp, sop->mackeylen); + ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode, + keyp, sop->mackeylen); if (ret != 0) { - dprintk(1,KERN_DEBUG,"%s: Failed to load hash for %s\n", __func__, - hash_name); + dprintk(1, KERN_DEBUG, + "%s: Failed to load hash for %s\n", + __func__, hash_name); ret = -EINVAL; goto error_hash; } @@ -263,7 +270,7 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) ses_new->sg = kzalloc(ses_new->array_size * sizeof(struct scatterlist), GFP_KERNEL); if (ses_new->sg == NULL || ses_new->pages == NULL) { - dprintk(0,KERN_DEBUG,"Memory error\n"); + dprintk(0, KERN_DEBUG, "Memory error\n"); ret = -ENOMEM; goto error_hash; } @@ -278,7 +285,7 @@ restart: /* Check for duplicate SID */ if (unlikely(ses_new->sid == ses_ptr->sid)) { get_random_bytes(&ses_new->sid, sizeof(ses_new->sid)); - /* Unless we have a broken RNG this + /* Unless we have a broken RNG this shouldn't loop forever... ;-) */ goto restart; } @@ -293,11 +300,11 @@ restart: return 0; error_hash: - cryptodev_cipher_deinit( &ses_new->cdata); + cryptodev_cipher_deinit(&ses_new->cdata); kfree(ses_new->sg); kfree(ses_new->pages); error_cipher: - if (ses_new) kfree(ses_new); + kfree(ses_new); return ret; @@ -307,20 +314,21 @@ error_cipher: static inline void crypto_destroy_session(struct csession *ses_ptr) { - if(down_trylock(&ses_ptr->sem)) { + if (down_trylock(&ses_ptr->sem)) { dprintk(2, KERN_DEBUG, "Waiting for semaphore of sid=0x%08X\n", ses_ptr->sid); down(&ses_ptr->sem); } dprintk(2, KERN_DEBUG, "Removed session 0x%08X\n", ses_ptr->sid); #if defined(CRYPTODEV_STATS) - if(enable_stats) + if (enable_stats) dprintk(2, KERN_DEBUG, - "Usage in Bytes: enc=%llu, dec=%llu, max=%zu, avg=%lu, cnt=%zu\n", + "Usage in Bytes: enc=%llu, dec=%llu, \ + max=%zu, avg=%lu, cnt=%zu\n", ses_ptr->stat[COP_ENCRYPT], ses_ptr->stat[COP_DECRYPT], ses_ptr->stat_max_size, ses_ptr->stat_count > 0 ? ((unsigned long)(ses_ptr->stat[COP_ENCRYPT]+ - ses_ptr->stat[COP_DECRYPT]) / + ses_ptr->stat[COP_DECRYPT]) / ses_ptr->stat_count) : 0, ses_ptr->stat_count); #endif @@ -345,7 +353,7 @@ crypto_finish_session(struct fcrypt *fcr, uint32_t sid) down(&fcr->sem); head = &fcr->list; list_for_each_entry_safe(ses_ptr, tmp, head, entry) { - if(ses_ptr->sid == sid) { + if (ses_ptr->sid == sid) { list_del(&ses_ptr->entry); crypto_destroy_session(ses_ptr); break; @@ -353,7 +361,8 @@ crypto_finish_session(struct fcrypt *fcr, uint32_t sid) } if (unlikely(!ses_ptr)) { - dprintk(1, KERN_ERR, "Session with sid=0x%08X not found!\n", sid); + dprintk(1, KERN_ERR, "Session with sid=0x%08X not found!\n", + sid); ret = -ENOENT; } up(&fcr->sem); @@ -388,7 +397,7 @@ crypto_get_session_by_sid(struct fcrypt *fcr, uint32_t sid) down(&fcr->sem); list_for_each_entry(ses_ptr, &fcr->list, entry) { - if(ses_ptr->sid == sid) { + if (ses_ptr->sid == sid) { down(&ses_ptr->sem); break; } @@ -400,7 +409,8 @@ crypto_get_session_by_sid(struct fcrypt *fcr, uint32_t sid) static int hash_n_crypt(struct csession *ses_ptr, struct crypt_op *cop, - struct scatterlist *src_sg, struct scatterlist *dst_sg, uint32_t len) + struct scatterlist *src_sg, struct scatterlist *dst_sg, + uint32_t len) { int ret; @@ -409,33 +419,37 @@ hash_n_crypt(struct csession *ses_ptr, struct crypt_op *cop, */ if (cop->op == COP_ENCRYPT) { if (ses_ptr->hdata.init != 0) { - ret = cryptodev_hash_update(&ses_ptr->hdata, src_sg, len); + ret = cryptodev_hash_update(&ses_ptr->hdata, + src_sg, len); if (unlikely(ret)) goto out_err; } if (ses_ptr->cdata.init != 0) { - ret = cryptodev_cipher_encrypt( &ses_ptr->cdata, src_sg, dst_sg, len); + ret = cryptodev_cipher_encrypt(&ses_ptr->cdata, + src_sg, dst_sg, len); if (unlikely(ret)) goto out_err; } } else { if (ses_ptr->cdata.init != 0) { - ret = cryptodev_cipher_decrypt( &ses_ptr->cdata, src_sg, dst_sg, len); + ret = cryptodev_cipher_decrypt(&ses_ptr->cdata, + src_sg, dst_sg, len); if (unlikely(ret)) goto out_err; } if (ses_ptr->hdata.init != 0) { - ret = cryptodev_hash_update(&ses_ptr->hdata, dst_sg, len); + ret = cryptodev_hash_update(&ses_ptr->hdata, + dst_sg, len); if (unlikely(ret)) goto out_err; } } return 0; out_err: - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); + dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n", ret); return ret; } @@ -452,17 +466,17 @@ __crypto_run_std(struct csession *ses_ptr, struct crypt_op *cop) int ret = 0; nbytes = cop->len; - data = (char*)__get_free_page(GFP_KERNEL); + data = (char *)__get_free_page(GFP_KERNEL); - if (unlikely(!data)) { + if (unlikely(!data)) return -ENOMEM; - } + bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes; src = cop->src; dst = cop->dst; - while(nbytes > 0) { + while (nbytes > 0) { size_t current_len = nbytes > bufsize ? bufsize : nbytes; if (unlikely(copy_from_user(data, src, current_len))) { @@ -543,17 +557,16 @@ static int get_userbuf(struct csession *ses, { int src_pagecount, dst_pagecount = 0, pagecount, write_src = 1; - if (cop->src == NULL) { + if (cop->src == NULL) return -EINVAL; - } src_pagecount = PAGECOUNT(cop->src, cop->len); if (!ses->cdata.init) { /* hashing only */ write_src = 0; } else if (cop->src != cop->dst) { /* non-in-situ transformation */ - if (cop->dst == NULL) { + if (cop->dst == NULL) return -EINVAL; - } + dst_pagecount = PAGECOUNT(cop->dst, cop->len); write_src = 0; } @@ -585,7 +598,8 @@ static int get_userbuf(struct csession *ses, if (__get_userbuf(cop->src, cop->len, write_src, src_pagecount, ses->pages, ses->sg)) { - dprintk(1, KERN_ERR, "failed to get user pages for data input\n"); + dprintk(1, KERN_ERR, + "failed to get user pages for data input\n"); return -EINVAL; } (*src_sg) = (*dst_sg) = ses->sg; @@ -595,7 +609,8 @@ static int get_userbuf(struct csession *ses, if (__get_userbuf(cop->dst, cop->len, 1, dst_pagecount, ses->pages + src_pagecount, *dst_sg)) { - dprintk(1, KERN_ERR, "failed to get user pages for data output\n"); + dprintk(1, KERN_ERR, + "failed to get user pages for data output\n"); release_user_pages(ses->pages, src_pagecount); return -EINVAL; } @@ -612,7 +627,8 @@ __crypto_run_zc(struct csession *ses_ptr, struct crypt_op *cop) ret = get_userbuf(ses_ptr, cop, &src_sg, &dst_sg, &pagecount); if (unlikely(ret)) { - dprintk(1, KERN_ERR, "Error getting user pages. Falling back to non zero copy.\n"); + dprintk(1, KERN_ERR, "Error getting user pages. \ + Falling back to non zero copy.\n"); return __crypto_run_std(ses_ptr, cop); } @@ -656,7 +672,8 @@ static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop) if (unlikely(cop->len % blocksize)) { dprintk(1, KERN_ERR, - "data size (%u) isn't a multiple of block size (%u)\n", + "data size (%u) isn't a multiple \ + of block size (%u)\n", cop->len, blocksize); ret = -EINVAL; goto out_unlock; @@ -665,14 +682,19 @@ static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop) if (cop->iv) { uint8_t iv[EALG_MAX_BLOCK_LEN]; - ret = copy_from_user(iv, cop->iv, min( (int)sizeof(iv), (ses_ptr->cdata.ivsize))); + ret = copy_from_user(iv, cop->iv, + min((int)sizeof(iv), (ses_ptr->cdata.ivsize))); if (unlikely(ret)) { - dprintk(1, KERN_ERR, "error copying IV (%d bytes)\n", min( (int)sizeof(iv), (ses_ptr->cdata.ivsize))); + dprintk(1, KERN_ERR, + "error copying IV (%d bytes)\n", + min((int)sizeof(iv), + (ses_ptr->cdata.ivsize))); ret = -EFAULT; goto out_unlock; } - cryptodev_cipher_set_iv(&ses_ptr->cdata, iv, ses_ptr->cdata.ivsize); + cryptodev_cipher_set_iv(&ses_ptr->cdata, iv, + ses_ptr->cdata.ivsize); } } @@ -687,11 +709,12 @@ static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop) if (ses_ptr->hdata.init != 0) { ret = cryptodev_hash_final(&ses_ptr->hdata, hash_output); if (unlikely(ret)) { - dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret); + dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n", ret); goto out_unlock; } - if (unlikely(copy_to_user(cop->mac, hash_output, ses_ptr->hdata.digestsize))) { + if (unlikely(copy_to_user(cop->mac, hash_output, + ses_ptr->hdata.digestsize))) { ret = -EFAULT; goto out_unlock; } @@ -720,13 +743,13 @@ cryptodev_open(struct inode *inode, struct file *filp) struct crypt_priv *pcr; pcr = kmalloc(sizeof(*pcr), GFP_KERNEL); - if(!pcr) + if (!pcr) return -ENOMEM; memset(pcr, 0, sizeof(*pcr)); init_MUTEX(&pcr->fcrypt.sem); INIT_LIST_HEAD(&pcr->fcrypt.list); - + filp->private_data = pcr; return 0; } @@ -736,7 +759,7 @@ cryptodev_release(struct inode *inode, struct file *filp) { struct crypt_priv *pcr = filp->private_data; - if(pcr) { + if (pcr) { crypto_finish_all_sessions(&pcr->fcrypt); kfree(pcr); filp->private_data = NULL; @@ -766,7 +789,7 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) struct session_op sop; struct crypt_op cop; struct crypt_priv *pcr = filp->private_data; - struct fcrypt * fcr; + struct fcrypt *fcr; uint32_t ses; int ret, fd; @@ -776,48 +799,48 @@ cryptodev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg_) fcr = &pcr->fcrypt; switch (cmd) { - case CIOCASYMFEAT: - return put_user(0, p); - case CRIOGET: - fd = clonefd(filp); - ret = put_user(fd, p); - if (unlikely(ret)) { - sys_close(fd); - return ret; - } + case CIOCASYMFEAT: + return put_user(0, p); + case CRIOGET: + fd = clonefd(filp); + ret = put_user(fd, p); + if (unlikely(ret)) { + sys_close(fd); return ret; - case CIOCGSESSION: - if (unlikely(copy_from_user(&sop, arg, sizeof(sop)))) - return -EFAULT; + } + return ret; + case CIOCGSESSION: + if (unlikely(copy_from_user(&sop, arg, sizeof(sop)))) + return -EFAULT; - ret = crypto_create_session(fcr, &sop); - if (unlikely(ret)) - return ret; - ret = copy_to_user(arg, &sop, sizeof(sop)); - if (unlikely(ret)) { - crypto_finish_session(fcr, sop.ses); - return -EFAULT; - } + ret = crypto_create_session(fcr, &sop); + if (unlikely(ret)) return ret; - case CIOCFSESSION: - ret = get_user(ses, (uint32_t __user *)arg); - if (unlikely(ret)) - return ret; - ret = crypto_finish_session(fcr, ses); + ret = copy_to_user(arg, &sop, sizeof(sop)); + if (unlikely(ret)) { + crypto_finish_session(fcr, sop.ses); + return -EFAULT; + } + return ret; + case CIOCFSESSION: + ret = get_user(ses, (uint32_t __user *)arg); + if (unlikely(ret)) return ret; - case CIOCCRYPT: - if (unlikely(copy_from_user(&cop, arg, sizeof(cop)))) - return -EFAULT; + ret = crypto_finish_session(fcr, ses); + return ret; + case CIOCCRYPT: + if (unlikely(copy_from_user(&cop, arg, sizeof(cop)))) + return -EFAULT; - ret = crypto_run(fcr, &cop); - if (unlikely(ret)) - return ret; - if (unlikely(copy_to_user(arg, &cop, sizeof(cop)))) - return -EFAULT; - return 0; + ret = crypto_run(fcr, &cop); + if (unlikely(ret)) + return ret; + if (unlikely(copy_to_user(arg, &cop, sizeof(cop)))) + return -EFAULT; + return 0; - default: - return -EINVAL; + default: + return -EINVAL; } } @@ -961,7 +984,7 @@ cryptodev_register(void) { int rc; - rc = misc_register (&cryptodev); + rc = misc_register(&cryptodev); if (unlikely(rc)) { printk(KERN_ERR PFX "registration of /dev/crypto failed\n"); return rc; -- 1.7.0.4 _______________________________________________ Cryptodev-linux-devel mailing list Cryptodev-linux-devel@gna.org https://mail.gna.org/listinfo/cryptodev-linux-devel