diff options
Diffstat (limited to 'security/keys')
-rw-r--r-- | security/keys/big_key.c | 30 | ||||
-rw-r--r-- | security/keys/compat.c | 2 | ||||
-rw-r--r-- | security/keys/dh.c | 8 | ||||
-rw-r--r-- | security/keys/internal.h | 5 | ||||
-rw-r--r-- | security/keys/key.c | 2 | ||||
-rw-r--r-- | security/keys/keyctl.c | 4 |
6 files changed, 32 insertions, 19 deletions
diff --git a/security/keys/big_key.c b/security/keys/big_key.c index 9e443fccad4c..c0b3030b5634 100644 --- a/security/keys/big_key.c +++ b/security/keys/big_key.c @@ -18,6 +18,7 @@ #include <keys/user-type.h> #include <keys/big_key-type.h> #include <crypto/rng.h> +#include <crypto/skcipher.h> /* * Layout of key payload words. @@ -74,7 +75,7 @@ static const char big_key_alg_name[] = "ecb(aes)"; * Crypto algorithms for big_key data encryption */ static struct crypto_rng *big_key_rng; -static struct crypto_blkcipher *big_key_blkcipher; +static struct crypto_skcipher *big_key_skcipher; /* * Generate random key to encrypt big_key data @@ -91,22 +92,26 @@ static int big_key_crypt(enum big_key_op op, u8 *data, size_t datalen, u8 *key) { int ret = -EINVAL; struct scatterlist sgio; - struct blkcipher_desc desc; + SKCIPHER_REQUEST_ON_STACK(req, big_key_skcipher); - if (crypto_blkcipher_setkey(big_key_blkcipher, key, ENC_KEY_SIZE)) { + if (crypto_skcipher_setkey(big_key_skcipher, key, ENC_KEY_SIZE)) { ret = -EAGAIN; goto error; } - desc.flags = 0; - desc.tfm = big_key_blkcipher; + skcipher_request_set_tfm(req, big_key_skcipher); + skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP, + NULL, NULL); sg_init_one(&sgio, data, datalen); + skcipher_request_set_crypt(req, &sgio, &sgio, datalen, NULL); if (op == BIG_KEY_ENC) - ret = crypto_blkcipher_encrypt(&desc, &sgio, &sgio, datalen); + ret = crypto_skcipher_encrypt(req); else - ret = crypto_blkcipher_decrypt(&desc, &sgio, &sgio, datalen); + ret = crypto_skcipher_decrypt(req); + + skcipher_request_zero(req); error: return ret; @@ -140,7 +145,7 @@ int big_key_preparse(struct key_preparsed_payload *prep) * * File content is stored encrypted with randomly generated key. */ - size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher)); + size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); /* prepare aligned data to encrypt */ data = kmalloc(enclen, GFP_KERNEL); @@ -288,7 +293,7 @@ long big_key_read(const struct key *key, char __user *buffer, size_t buflen) struct file *file; u8 *data; u8 *enckey = (u8 *)key->payload.data[big_key_data]; - size_t enclen = ALIGN(datalen, crypto_blkcipher_blocksize(big_key_blkcipher)); + size_t enclen = ALIGN(datalen, crypto_skcipher_blocksize(big_key_skcipher)); data = kmalloc(enclen, GFP_KERNEL); if (!data) @@ -359,9 +364,10 @@ static int __init big_key_crypto_init(void) goto error; /* init block cipher */ - big_key_blkcipher = crypto_alloc_blkcipher(big_key_alg_name, 0, 0); - if (IS_ERR(big_key_blkcipher)) { - big_key_blkcipher = NULL; + big_key_skcipher = crypto_alloc_skcipher(big_key_alg_name, + 0, CRYPTO_ALG_ASYNC); + if (IS_ERR(big_key_skcipher)) { + big_key_skcipher = NULL; ret = -EFAULT; goto error; } diff --git a/security/keys/compat.c b/security/keys/compat.c index c8783b3b628c..36c80bf5b89c 100644 --- a/security/keys/compat.c +++ b/security/keys/compat.c @@ -134,7 +134,7 @@ COMPAT_SYSCALL_DEFINE5(keyctl, u32, option, case KEYCTL_DH_COMPUTE: return keyctl_dh_compute(compat_ptr(arg2), compat_ptr(arg3), - arg4); + arg4, compat_ptr(arg5)); default: return -EOPNOTSUPP; diff --git a/security/keys/dh.c b/security/keys/dh.c index 880505a4b9f1..531ed2ec132f 100644 --- a/security/keys/dh.c +++ b/security/keys/dh.c @@ -78,7 +78,8 @@ error: } long keyctl_dh_compute(struct keyctl_dh_params __user *params, - char __user *buffer, size_t buflen) + char __user *buffer, size_t buflen, + void __user *reserved) { long ret; MPI base, private, prime, result; @@ -97,6 +98,11 @@ long keyctl_dh_compute(struct keyctl_dh_params __user *params, goto out; } + if (reserved) { + ret = -EINVAL; + goto out; + } + keylen = mpi_from_key(pcopy.prime, buflen, &prime); if (keylen < 0 || !prime) { /* buflen == 0 may be used to query the required buffer size, diff --git a/security/keys/internal.h b/security/keys/internal.h index 8ec7a528365d..a705a7d92ad7 100644 --- a/security/keys/internal.h +++ b/security/keys/internal.h @@ -260,10 +260,11 @@ static inline long keyctl_get_persistent(uid_t uid, key_serial_t destring) #ifdef CONFIG_KEY_DH_OPERATIONS extern long keyctl_dh_compute(struct keyctl_dh_params __user *, char __user *, - size_t); + size_t, void __user *); #else static inline long keyctl_dh_compute(struct keyctl_dh_params __user *params, - char __user *buffer, size_t buflen) + char __user *buffer, size_t buflen, + void __user *reserved) { return -EOPNOTSUPP; } diff --git a/security/keys/key.c b/security/keys/key.c index bd5a272f28a6..346fbf201c22 100644 --- a/security/keys/key.c +++ b/security/keys/key.c @@ -597,7 +597,7 @@ int key_reject_and_link(struct key *key, mutex_unlock(&key_construction_mutex); - if (keyring) + if (keyring && link_ret == 0) __key_link_end(keyring, &key->index_key, edit); /* wake up anyone waiting for a key to be constructed */ diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index 3b135a0af344..d580ad06b792 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c @@ -1688,8 +1688,8 @@ SYSCALL_DEFINE5(keyctl, int, option, unsigned long, arg2, unsigned long, arg3, case KEYCTL_DH_COMPUTE: return keyctl_dh_compute((struct keyctl_dh_params __user *) arg2, - (char __user *) arg3, - (size_t) arg4); + (char __user *) arg3, (size_t) arg4, + (void __user *) arg5); default: return -EOPNOTSUPP; |