From a211bb8337d741fef585782213e504c333d7e69c Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Tue, 6 Jul 2010 13:24:09 +0200 Subject: [PATCH] Internal functions no longer work with __user buffers. --- cryptodev_cipher.c | 35 ++++++----------------------------- cryptodev_int.h | 6 +++--- cryptodev_main.c | 43 ++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 49 insertions(+), 35 deletions(-) diff --git a/cryptodev_cipher.c b/cryptodev_cipher.c index 2f52f46..5462f03 100644 --- a/cryptodev_cipher.c +++ b/cryptodev_cipher.c @@ -48,9 +48,9 @@ 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 __user * key, size_t keylen) +int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t * keyp, size_t keylen) { - uint8_t keyp[CRYPTO_CIPHER_MAX_KEY_LEN]; + struct ablkcipher_alg* alg; int ret; @@ -58,17 +58,6 @@ int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, uint8_t out->init = 1; - if (unlikely(keylen > CRYPTO_CIPHER_MAX_KEY_LEN)) { - dprintk(1,KERN_DEBUG,"Setting key failed for %s-%zu.\n", - alg_name, keylen*8); - return -EINVAL; - } - /* Copy the key from user and set to TFM. */ - if (unlikely(copy_from_user(keyp, key, keylen))) { - dprintk(1, KERN_DEBUG, "copy_from_user() failed for key\n"); - return -EINVAL; - } - 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__, @@ -138,9 +127,9 @@ void cryptodev_cipher_deinit(struct cipher_data* cdata) cdata->init = 0; } -int cryptodev_cipher_set_iv(struct cipher_data* cdata, void __user* iv, size_t iv_size) +void cryptodev_cipher_set_iv(struct cipher_data* cdata, void __user* iv, size_t iv_size) { - return copy_from_user(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) @@ -196,23 +185,12 @@ ssize_t cryptodev_cipher_decrypt( struct cipher_data* cdata, struct scatterlist /* Hash functions */ -int cryptodev_hash_init( struct hash_data* hdata, const char* alg_name, int hmac_mode, void __user* 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; -uint8_t hkeyp[CRYPTO_HMAC_MAX_KEY_LEN]; hdata->init = 1; - if (unlikely(mackeylen > CRYPTO_HMAC_MAX_KEY_LEN)) { - dprintk(1,KERN_DEBUG,"Setting hmac key failed for %s-%zu.\n", - alg_name, mackeylen*8); - return -EINVAL; - } - if (unlikely(copy_from_user(hkeyp, mackey, mackeylen))) { - dprintk(1, KERN_DEBUG, "copy_from_user() failed for mackey\n"); - return -EINVAL; - } - 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__, @@ -222,8 +200,7 @@ uint8_t hkeyp[CRYPTO_HMAC_MAX_KEY_LEN]; /* Copy the key from user and set to TFM. */ if (hmac_mode != 0) { - - ret = crypto_ahash_setkey(hdata->async.s, hkeyp, mackeylen); + ret = crypto_ahash_setkey(hdata->async.s, mackey, mackeylen); if (unlikely(ret)) { dprintk(1,KERN_DEBUG,"Setting hmac key failed for %s-%zu.\n", alg_name, mackeylen*8); diff --git a/cryptodev_int.h b/cryptodev_int.h index 0b82017..bc3b586 100644 --- a/cryptodev_int.h +++ b/cryptodev_int.h @@ -37,11 +37,11 @@ struct cipher_data } async; }; -int cryptodev_cipher_init(struct cipher_data* out, const char* alg_name, __user uint8_t * key, size_t keylen); +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, struct scatterlist *sg1, struct scatterlist *sg2, size_t len); ssize_t cryptodev_cipher_encrypt( struct cipher_data* cdata, struct scatterlist *sg1, struct scatterlist *sg2, size_t len); -int 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 @@ -59,7 +59,7 @@ 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, __user 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); /* compatibility stuff */ #ifdef CONFIG_COMPAT diff --git a/cryptodev_main.c b/cryptodev_main.c index 0da4582..df0a8ba 100644 --- a/cryptodev_main.c +++ b/cryptodev_main.c @@ -200,7 +200,22 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) /* Set-up crypto transform. */ if (alg_name) { - ret = cryptodev_cipher_init(&ses_new->cdata, alg_name, sop->key, sop->keylen); + 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", + alg_name, (size_t)sop->keylen*8); + ret = -EINVAL; + goto error_cipher; + } + + ret = copy_from_user(keyp, sop->key, sop->keylen); + if (unlikely(ret)) { + goto error_cipher; + } + + 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); @@ -210,7 +225,21 @@ crypto_create_session(struct fcrypt *fcr, struct session_op *sop) } if (hash_name) { - ret = cryptodev_hash_init(&ses_new->hdata, hash_name, hmac_mode, sop->mackey, sop->mackeylen); + 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", + alg_name, (size_t)sop->mackeylen*8); + ret = -EINVAL; + goto error_hash; + } + + ret = copy_from_user(keyp, sop->mackey, sop->mackeylen); + if (unlikely(ret)) { + goto error_hash; + } + + 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); @@ -603,7 +632,15 @@ static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop) } if (cop->iv) { - cryptodev_cipher_set_iv(&ses_ptr->cdata, cop->iv, ses_ptr->cdata.ivsize); + uint8_t iv[EALG_MAX_BLOCK_LEN]; + + ret = copy_from_user(iv, cop->iv, min( (int)sizeof(iv), (ses_ptr->cdata.ivsize))); + dprintk(1, KERN_ERR, "error copying IV\n"); + if (unlikely(ret)) { + goto out_unlock; + } + + cryptodev_cipher_set_iv(&ses_ptr->cdata, iv, ses_ptr->cdata.ivsize); } } -- 2.11.4.GIT