Merge tag 'v3.10.108' into update
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / security / keys / encrypted-keys / encrypted.c
index 2d1bb8af7696d5d431394cfbe8ac6d5e40f24da2..b7d7cffe73493fd5577f3ca05d2ae19d08beaac2 100644 (file)
@@ -315,6 +315,13 @@ static struct key *request_user_key(const char *master_desc, u8 **master_key,
 
        down_read(&ukey->sem);
        upayload = ukey->payload.data;
+       if (!upayload) {
+               /* key was revoked before we acquired its semaphore */
+               up_read(&ukey->sem);
+               key_put(ukey);
+               ukey = ERR_PTR(-EKEYREVOKED);
+               goto error;
+       }
        *master_key = upayload->data;
        *master_keylen = upayload->datalen;
 error:
@@ -428,7 +435,7 @@ static int init_blkcipher_desc(struct blkcipher_desc *desc, const u8 *key,
 static struct key *request_master_key(struct encrypted_key_payload *epayload,
                                      u8 **master_key, size_t *master_keylen)
 {
-       struct key *mkey = NULL;
+       struct key *mkey = ERR_PTR(-EINVAL);
 
        if (!strncmp(epayload->master_desc, KEY_TRUSTED_PREFIX,
                     KEY_TRUSTED_PREFIX_LEN)) {
@@ -773,8 +780,8 @@ static int encrypted_init(struct encrypted_key_payload *epayload,
  *
  * On success, return 0. Otherwise return errno.
  */
-static int encrypted_instantiate(struct key *key, const void *data,
-                                size_t datalen)
+static int encrypted_instantiate(struct key *key,
+                                struct key_preparsed_payload *prep)
 {
        struct encrypted_key_payload *epayload = NULL;
        char *datablob = NULL;
@@ -782,16 +789,17 @@ static int encrypted_instantiate(struct key *key, const void *data,
        char *master_desc = NULL;
        char *decrypted_datalen = NULL;
        char *hex_encoded_iv = NULL;
+       size_t datalen = prep->datalen;
        int ret;
 
-       if (datalen <= 0 || datalen > 32767 || !data)
+       if (datalen <= 0 || datalen > 32767 || !prep->data)
                return -EINVAL;
 
        datablob = kmalloc(datalen + 1, GFP_KERNEL);
        if (!datablob)
                return -ENOMEM;
        datablob[datalen] = 0;
-       memcpy(datablob, data, datalen);
+       memcpy(datablob, prep->data, datalen);
        ret = datablob_parse(datablob, &format, &master_desc,
                             &decrypted_datalen, &hex_encoded_iv);
        if (ret < 0)
@@ -834,16 +842,17 @@ static void encrypted_rcu_free(struct rcu_head *rcu)
  *
  * On success, return 0. Otherwise return errno.
  */
-static int encrypted_update(struct key *key, const void *data, size_t datalen)
+static int encrypted_update(struct key *key, struct key_preparsed_payload *prep)
 {
        struct encrypted_key_payload *epayload = key->payload.data;
        struct encrypted_key_payload *new_epayload;
        char *buf;
        char *new_master_desc = NULL;
        const char *format = NULL;
+       size_t datalen = prep->datalen;
        int ret = 0;
 
-       if (datalen <= 0 || datalen > 32767 || !data)
+       if (datalen <= 0 || datalen > 32767 || !prep->data)
                return -EINVAL;
 
        buf = kmalloc(datalen + 1, GFP_KERNEL);
@@ -851,7 +860,7 @@ static int encrypted_update(struct key *key, const void *data, size_t datalen)
                return -ENOMEM;
 
        buf[datalen] = 0;
-       memcpy(buf, data, datalen);
+       memcpy(buf, prep->data, datalen);
        ret = datablob_parse(buf, &format, &new_master_desc, NULL, NULL);
        if (ret < 0)
                goto out;
@@ -1016,10 +1025,13 @@ static int __init init_encrypted(void)
        ret = encrypted_shash_alloc();
        if (ret < 0)
                return ret;
+       ret = aes_get_sizes();
+       if (ret < 0)
+               goto out;
        ret = register_key_type(&key_type_encrypted);
        if (ret < 0)
                goto out;
-       return aes_get_sizes();
+       return 0;
 out:
        encrypted_shash_release();
        return ret;