Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* Crypto operations using stored keys
0003  *
0004  * Copyright (c) 2016, Intel Corporation
0005  */
0006 
0007 #include <linux/slab.h>
0008 #include <linux/uaccess.h>
0009 #include <linux/scatterlist.h>
0010 #include <linux/crypto.h>
0011 #include <crypto/hash.h>
0012 #include <crypto/kpp.h>
0013 #include <crypto/dh.h>
0014 #include <crypto/kdf_sp800108.h>
0015 #include <keys/user-type.h>
0016 #include "internal.h"
0017 
0018 static ssize_t dh_data_from_key(key_serial_t keyid, const void **data)
0019 {
0020     struct key *key;
0021     key_ref_t key_ref;
0022     long status;
0023     ssize_t ret;
0024 
0025     key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);
0026     if (IS_ERR(key_ref)) {
0027         ret = -ENOKEY;
0028         goto error;
0029     }
0030 
0031     key = key_ref_to_ptr(key_ref);
0032 
0033     ret = -EOPNOTSUPP;
0034     if (key->type == &key_type_user) {
0035         down_read(&key->sem);
0036         status = key_validate(key);
0037         if (status == 0) {
0038             const struct user_key_payload *payload;
0039             uint8_t *duplicate;
0040 
0041             payload = user_key_payload_locked(key);
0042 
0043             duplicate = kmemdup(payload->data, payload->datalen,
0044                         GFP_KERNEL);
0045             if (duplicate) {
0046                 *data = duplicate;
0047                 ret = payload->datalen;
0048             } else {
0049                 ret = -ENOMEM;
0050             }
0051         }
0052         up_read(&key->sem);
0053     }
0054 
0055     key_put(key);
0056 error:
0057     return ret;
0058 }
0059 
0060 static void dh_free_data(struct dh *dh)
0061 {
0062     kfree_sensitive(dh->key);
0063     kfree_sensitive(dh->p);
0064     kfree_sensitive(dh->g);
0065 }
0066 
0067 struct dh_completion {
0068     struct completion completion;
0069     int err;
0070 };
0071 
0072 static void dh_crypto_done(struct crypto_async_request *req, int err)
0073 {
0074     struct dh_completion *compl = req->data;
0075 
0076     if (err == -EINPROGRESS)
0077         return;
0078 
0079     compl->err = err;
0080     complete(&compl->completion);
0081 }
0082 
0083 static int kdf_alloc(struct crypto_shash **hash, char *hashname)
0084 {
0085     struct crypto_shash *tfm;
0086 
0087     /* allocate synchronous hash */
0088     tfm = crypto_alloc_shash(hashname, 0, 0);
0089     if (IS_ERR(tfm)) {
0090         pr_info("could not allocate digest TFM handle %s\n", hashname);
0091         return PTR_ERR(tfm);
0092     }
0093 
0094     if (crypto_shash_digestsize(tfm) == 0) {
0095         crypto_free_shash(tfm);
0096         return -EINVAL;
0097     }
0098 
0099     *hash = tfm;
0100 
0101     return 0;
0102 }
0103 
0104 static void kdf_dealloc(struct crypto_shash *hash)
0105 {
0106     if (hash)
0107         crypto_free_shash(hash);
0108 }
0109 
0110 static int keyctl_dh_compute_kdf(struct crypto_shash *hash,
0111                  char __user *buffer, size_t buflen,
0112                  uint8_t *kbuf, size_t kbuflen)
0113 {
0114     struct kvec kbuf_iov = { .iov_base = kbuf, .iov_len = kbuflen };
0115     uint8_t *outbuf = NULL;
0116     int ret;
0117     size_t outbuf_len = roundup(buflen, crypto_shash_digestsize(hash));
0118 
0119     outbuf = kmalloc(outbuf_len, GFP_KERNEL);
0120     if (!outbuf) {
0121         ret = -ENOMEM;
0122         goto err;
0123     }
0124 
0125     ret = crypto_kdf108_ctr_generate(hash, &kbuf_iov, 1, outbuf, outbuf_len);
0126     if (ret)
0127         goto err;
0128 
0129     ret = buflen;
0130     if (copy_to_user(buffer, outbuf, buflen) != 0)
0131         ret = -EFAULT;
0132 
0133 err:
0134     kfree_sensitive(outbuf);
0135     return ret;
0136 }
0137 
0138 long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
0139              char __user *buffer, size_t buflen,
0140              struct keyctl_kdf_params *kdfcopy)
0141 {
0142     long ret;
0143     ssize_t dlen;
0144     int secretlen;
0145     int outlen;
0146     struct keyctl_dh_params pcopy;
0147     struct dh dh_inputs;
0148     struct scatterlist outsg;
0149     struct dh_completion compl;
0150     struct crypto_kpp *tfm;
0151     struct kpp_request *req;
0152     uint8_t *secret;
0153     uint8_t *outbuf;
0154     struct crypto_shash *hash = NULL;
0155 
0156     if (!params || (!buffer && buflen)) {
0157         ret = -EINVAL;
0158         goto out1;
0159     }
0160     if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
0161         ret = -EFAULT;
0162         goto out1;
0163     }
0164 
0165     if (kdfcopy) {
0166         char *hashname;
0167 
0168         if (memchr_inv(kdfcopy->__spare, 0, sizeof(kdfcopy->__spare))) {
0169             ret = -EINVAL;
0170             goto out1;
0171         }
0172 
0173         if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN ||
0174             kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) {
0175             ret = -EMSGSIZE;
0176             goto out1;
0177         }
0178 
0179         /* get KDF name string */
0180         hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME);
0181         if (IS_ERR(hashname)) {
0182             ret = PTR_ERR(hashname);
0183             goto out1;
0184         }
0185 
0186         /* allocate KDF from the kernel crypto API */
0187         ret = kdf_alloc(&hash, hashname);
0188         kfree(hashname);
0189         if (ret)
0190             goto out1;
0191     }
0192 
0193     memset(&dh_inputs, 0, sizeof(dh_inputs));
0194 
0195     dlen = dh_data_from_key(pcopy.prime, &dh_inputs.p);
0196     if (dlen < 0) {
0197         ret = dlen;
0198         goto out1;
0199     }
0200     dh_inputs.p_size = dlen;
0201 
0202     dlen = dh_data_from_key(pcopy.base, &dh_inputs.g);
0203     if (dlen < 0) {
0204         ret = dlen;
0205         goto out2;
0206     }
0207     dh_inputs.g_size = dlen;
0208 
0209     dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
0210     if (dlen < 0) {
0211         ret = dlen;
0212         goto out2;
0213     }
0214     dh_inputs.key_size = dlen;
0215 
0216     secretlen = crypto_dh_key_len(&dh_inputs);
0217     secret = kmalloc(secretlen, GFP_KERNEL);
0218     if (!secret) {
0219         ret = -ENOMEM;
0220         goto out2;
0221     }
0222     ret = crypto_dh_encode_key(secret, secretlen, &dh_inputs);
0223     if (ret)
0224         goto out3;
0225 
0226     tfm = crypto_alloc_kpp("dh", 0, 0);
0227     if (IS_ERR(tfm)) {
0228         ret = PTR_ERR(tfm);
0229         goto out3;
0230     }
0231 
0232     ret = crypto_kpp_set_secret(tfm, secret, secretlen);
0233     if (ret)
0234         goto out4;
0235 
0236     outlen = crypto_kpp_maxsize(tfm);
0237 
0238     if (!kdfcopy) {
0239         /*
0240          * When not using a KDF, buflen 0 is used to read the
0241          * required buffer length
0242          */
0243         if (buflen == 0) {
0244             ret = outlen;
0245             goto out4;
0246         } else if (outlen > buflen) {
0247             ret = -EOVERFLOW;
0248             goto out4;
0249         }
0250     }
0251 
0252     outbuf = kzalloc(kdfcopy ? (outlen + kdfcopy->otherinfolen) : outlen,
0253              GFP_KERNEL);
0254     if (!outbuf) {
0255         ret = -ENOMEM;
0256         goto out4;
0257     }
0258 
0259     sg_init_one(&outsg, outbuf, outlen);
0260 
0261     req = kpp_request_alloc(tfm, GFP_KERNEL);
0262     if (!req) {
0263         ret = -ENOMEM;
0264         goto out5;
0265     }
0266 
0267     kpp_request_set_input(req, NULL, 0);
0268     kpp_request_set_output(req, &outsg, outlen);
0269     init_completion(&compl.completion);
0270     kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
0271                  CRYPTO_TFM_REQ_MAY_SLEEP,
0272                  dh_crypto_done, &compl);
0273 
0274     /*
0275      * For DH, generate_public_key and generate_shared_secret are
0276      * the same calculation
0277      */
0278     ret = crypto_kpp_generate_public_key(req);
0279     if (ret == -EINPROGRESS) {
0280         wait_for_completion(&compl.completion);
0281         ret = compl.err;
0282         if (ret)
0283             goto out6;
0284     }
0285 
0286     if (kdfcopy) {
0287         /*
0288          * Concatenate SP800-56A otherinfo past DH shared secret -- the
0289          * input to the KDF is (DH shared secret || otherinfo)
0290          */
0291         if (copy_from_user(outbuf + req->dst_len, kdfcopy->otherinfo,
0292                    kdfcopy->otherinfolen) != 0) {
0293             ret = -EFAULT;
0294             goto out6;
0295         }
0296 
0297         ret = keyctl_dh_compute_kdf(hash, buffer, buflen, outbuf,
0298                         req->dst_len + kdfcopy->otherinfolen);
0299     } else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) {
0300         ret = req->dst_len;
0301     } else {
0302         ret = -EFAULT;
0303     }
0304 
0305 out6:
0306     kpp_request_free(req);
0307 out5:
0308     kfree_sensitive(outbuf);
0309 out4:
0310     crypto_free_kpp(tfm);
0311 out3:
0312     kfree_sensitive(secret);
0313 out2:
0314     dh_free_data(&dh_inputs);
0315 out1:
0316     kdf_dealloc(hash);
0317     return ret;
0318 }
0319 
0320 long keyctl_dh_compute(struct keyctl_dh_params __user *params,
0321                char __user *buffer, size_t buflen,
0322                struct keyctl_kdf_params __user *kdf)
0323 {
0324     struct keyctl_kdf_params kdfcopy;
0325 
0326     if (!kdf)
0327         return __keyctl_dh_compute(params, buffer, buflen, NULL);
0328 
0329     if (copy_from_user(&kdfcopy, kdf, sizeof(kdfcopy)) != 0)
0330         return -EFAULT;
0331 
0332     return __keyctl_dh_compute(params, buffer, buflen, &kdfcopy);
0333 }