linux/security/keys/dh.c
<<
>>
Prefs
   1/* Crypto operations using stored keys
   2 *
   3 * Copyright (c) 2016, Intel Corporation
   4 *
   5 * This program is free software; you can redistribute it and/or
   6 * modify it under the terms of the GNU General Public License
   7 * as published by the Free Software Foundation; either version
   8 * 2 of the License, or (at your option) any later version.
   9 */
  10
  11#include <linux/slab.h>
  12#include <linux/uaccess.h>
  13#include <linux/scatterlist.h>
  14#include <linux/crypto.h>
  15#include <crypto/hash.h>
  16#include <crypto/kpp.h>
  17#include <crypto/dh.h>
  18#include <keys/user-type.h>
  19#include "internal.h"
  20
  21static ssize_t dh_data_from_key(key_serial_t keyid, void **data)
  22{
  23        struct key *key;
  24        key_ref_t key_ref;
  25        long status;
  26        ssize_t ret;
  27
  28        key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ);
  29        if (IS_ERR(key_ref)) {
  30                ret = -ENOKEY;
  31                goto error;
  32        }
  33
  34        key = key_ref_to_ptr(key_ref);
  35
  36        ret = -EOPNOTSUPP;
  37        if (key->type == &key_type_user) {
  38                down_read(&key->sem);
  39                status = key_validate(key);
  40                if (status == 0) {
  41                        const struct user_key_payload *payload;
  42                        uint8_t *duplicate;
  43
  44                        payload = user_key_payload_locked(key);
  45
  46                        duplicate = kmemdup(payload->data, payload->datalen,
  47                                            GFP_KERNEL);
  48                        if (duplicate) {
  49                                *data = duplicate;
  50                                ret = payload->datalen;
  51                        } else {
  52                                ret = -ENOMEM;
  53                        }
  54                }
  55                up_read(&key->sem);
  56        }
  57
  58        key_put(key);
  59error:
  60        return ret;
  61}
  62
  63static void dh_free_data(struct dh *dh)
  64{
  65        kzfree(dh->key);
  66        kzfree(dh->p);
  67        kzfree(dh->g);
  68}
  69
  70struct dh_completion {
  71        struct completion completion;
  72        int err;
  73};
  74
  75static void dh_crypto_done(struct crypto_async_request *req, int err)
  76{
  77        struct dh_completion *compl = req->data;
  78
  79        if (err == -EINPROGRESS)
  80                return;
  81
  82        compl->err = err;
  83        complete(&compl->completion);
  84}
  85
  86struct kdf_sdesc {
  87        struct shash_desc shash;
  88        char ctx[];
  89};
  90
  91static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname)
  92{
  93        struct crypto_shash *tfm;
  94        struct kdf_sdesc *sdesc;
  95        int size;
  96        int err;
  97
  98        /* allocate synchronous hash */
  99        tfm = crypto_alloc_shash(hashname, 0, 0);
 100        if (IS_ERR(tfm)) {
 101                pr_info("could not allocate digest TFM handle %s\n", hashname);
 102                return PTR_ERR(tfm);
 103        }
 104
 105        err = -EINVAL;
 106        if (crypto_shash_digestsize(tfm) == 0)
 107                goto out_free_tfm;
 108
 109        err = -ENOMEM;
 110        size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm);
 111        sdesc = kmalloc(size, GFP_KERNEL);
 112        if (!sdesc)
 113                goto out_free_tfm;
 114        sdesc->shash.tfm = tfm;
 115        sdesc->shash.flags = 0x0;
 116
 117        *sdesc_ret = sdesc;
 118
 119        return 0;
 120
 121out_free_tfm:
 122        crypto_free_shash(tfm);
 123        return err;
 124}
 125
 126static void kdf_dealloc(struct kdf_sdesc *sdesc)
 127{
 128        if (!sdesc)
 129                return;
 130
 131        if (sdesc->shash.tfm)
 132                crypto_free_shash(sdesc->shash.tfm);
 133
 134        kzfree(sdesc);
 135}
 136
 137/*
 138 * Implementation of the KDF in counter mode according to SP800-108 section 5.1
 139 * as well as SP800-56A section 5.8.1 (Single-step KDF).
 140 *
 141 * SP800-56A:
 142 * The src pointer is defined as Z || other info where Z is the shared secret
 143 * from DH and other info is an arbitrary string (see SP800-56A section
 144 * 5.8.1.2).
 145 */
 146static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen,
 147                   u8 *dst, unsigned int dlen, unsigned int zlen)
 148{
 149        struct shash_desc *desc = &sdesc->shash;
 150        unsigned int h = crypto_shash_digestsize(desc->tfm);
 151        int err = 0;
 152        u8 *dst_orig = dst;
 153        __be32 counter = cpu_to_be32(1);
 154
 155        while (dlen) {
 156                err = crypto_shash_init(desc);
 157                if (err)
 158                        goto err;
 159
 160                err = crypto_shash_update(desc, (u8 *)&counter, sizeof(__be32));
 161                if (err)
 162                        goto err;
 163
 164                if (zlen && h) {
 165                        u8 tmpbuffer[h];
 166                        size_t chunk = min_t(size_t, zlen, h);
 167                        memset(tmpbuffer, 0, chunk);
 168
 169                        do {
 170                                err = crypto_shash_update(desc, tmpbuffer,
 171                                                          chunk);
 172                                if (err)
 173                                        goto err;
 174
 175                                zlen -= chunk;
 176                                chunk = min_t(size_t, zlen, h);
 177                        } while (zlen);
 178                }
 179
 180                if (src && slen) {
 181                        err = crypto_shash_update(desc, src, slen);
 182                        if (err)
 183                                goto err;
 184                }
 185
 186                if (dlen < h) {
 187                        u8 tmpbuffer[h];
 188
 189                        err = crypto_shash_final(desc, tmpbuffer);
 190                        if (err)
 191                                goto err;
 192                        memcpy(dst, tmpbuffer, dlen);
 193                        memzero_explicit(tmpbuffer, h);
 194                        return 0;
 195                } else {
 196                        err = crypto_shash_final(desc, dst);
 197                        if (err)
 198                                goto err;
 199
 200                        dlen -= h;
 201                        dst += h;
 202                        counter = cpu_to_be32(be32_to_cpu(counter) + 1);
 203                }
 204        }
 205
 206        return 0;
 207
 208err:
 209        memzero_explicit(dst_orig, dlen);
 210        return err;
 211}
 212
 213static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc,
 214                                 char __user *buffer, size_t buflen,
 215                                 uint8_t *kbuf, size_t kbuflen, size_t lzero)
 216{
 217        uint8_t *outbuf = NULL;
 218        int ret;
 219
 220        outbuf = kmalloc(buflen, GFP_KERNEL);
 221        if (!outbuf) {
 222                ret = -ENOMEM;
 223                goto err;
 224        }
 225
 226        ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, buflen, lzero);
 227        if (ret)
 228                goto err;
 229
 230        ret = buflen;
 231        if (copy_to_user(buffer, outbuf, buflen) != 0)
 232                ret = -EFAULT;
 233
 234err:
 235        kzfree(outbuf);
 236        return ret;
 237}
 238
 239long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
 240                         char __user *buffer, size_t buflen,
 241                         struct keyctl_kdf_params *kdfcopy)
 242{
 243        long ret;
 244        ssize_t dlen;
 245        int secretlen;
 246        int outlen;
 247        struct keyctl_dh_params pcopy;
 248        struct dh dh_inputs;
 249        struct scatterlist outsg;
 250        struct dh_completion compl;
 251        struct crypto_kpp *tfm;
 252        struct kpp_request *req;
 253        uint8_t *secret;
 254        uint8_t *outbuf;
 255        struct kdf_sdesc *sdesc = NULL;
 256
 257        if (!params || (!buffer && buflen)) {
 258                ret = -EINVAL;
 259                goto out1;
 260        }
 261        if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) {
 262                ret = -EFAULT;
 263                goto out1;
 264        }
 265
 266        if (kdfcopy) {
 267                char *hashname;
 268
 269                if (memchr_inv(kdfcopy->__spare, 0, sizeof(kdfcopy->__spare))) {
 270                        ret = -EINVAL;
 271                        goto out1;
 272                }
 273
 274                if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN ||
 275                    kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) {
 276                        ret = -EMSGSIZE;
 277                        goto out1;
 278                }
 279
 280                /* get KDF name string */
 281                hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME);
 282                if (IS_ERR(hashname)) {
 283                        ret = PTR_ERR(hashname);
 284                        goto out1;
 285                }
 286
 287                /* allocate KDF from the kernel crypto API */
 288                ret = kdf_alloc(&sdesc, hashname);
 289                kfree(hashname);
 290                if (ret)
 291                        goto out1;
 292        }
 293
 294        memset(&dh_inputs, 0, sizeof(dh_inputs));
 295
 296        dlen = dh_data_from_key(pcopy.prime, &dh_inputs.p);
 297        if (dlen < 0) {
 298                ret = dlen;
 299                goto out1;
 300        }
 301        dh_inputs.p_size = dlen;
 302
 303        dlen = dh_data_from_key(pcopy.base, &dh_inputs.g);
 304        if (dlen < 0) {
 305                ret = dlen;
 306                goto out2;
 307        }
 308        dh_inputs.g_size = dlen;
 309
 310        dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
 311        if (dlen < 0) {
 312                ret = dlen;
 313                goto out2;
 314        }
 315        dh_inputs.key_size = dlen;
 316
 317        secretlen = crypto_dh_key_len(&dh_inputs);
 318        secret = kmalloc(secretlen, GFP_KERNEL);
 319        if (!secret) {
 320                ret = -ENOMEM;
 321                goto out2;
 322        }
 323        ret = crypto_dh_encode_key(secret, secretlen, &dh_inputs);
 324        if (ret)
 325                goto out3;
 326
 327        tfm = crypto_alloc_kpp("dh", CRYPTO_ALG_TYPE_KPP, 0);
 328        if (IS_ERR(tfm)) {
 329                ret = PTR_ERR(tfm);
 330                goto out3;
 331        }
 332
 333        ret = crypto_kpp_set_secret(tfm, secret, secretlen);
 334        if (ret)
 335                goto out4;
 336
 337        outlen = crypto_kpp_maxsize(tfm);
 338
 339        if (!kdfcopy) {
 340                /*
 341                 * When not using a KDF, buflen 0 is used to read the
 342                 * required buffer length
 343                 */
 344                if (buflen == 0) {
 345                        ret = outlen;
 346                        goto out4;
 347                } else if (outlen > buflen) {
 348                        ret = -EOVERFLOW;
 349                        goto out4;
 350                }
 351        }
 352
 353        outbuf = kzalloc(kdfcopy ? (outlen + kdfcopy->otherinfolen) : outlen,
 354                         GFP_KERNEL);
 355        if (!outbuf) {
 356                ret = -ENOMEM;
 357                goto out4;
 358        }
 359
 360        sg_init_one(&outsg, outbuf, outlen);
 361
 362        req = kpp_request_alloc(tfm, GFP_KERNEL);
 363        if (!req) {
 364                ret = -ENOMEM;
 365                goto out5;
 366        }
 367
 368        kpp_request_set_input(req, NULL, 0);
 369        kpp_request_set_output(req, &outsg, outlen);
 370        init_completion(&compl.completion);
 371        kpp_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG |
 372                                 CRYPTO_TFM_REQ_MAY_SLEEP,
 373                                 dh_crypto_done, &compl);
 374
 375        /*
 376         * For DH, generate_public_key and generate_shared_secret are
 377         * the same calculation
 378         */
 379        ret = crypto_kpp_generate_public_key(req);
 380        if (ret == -EINPROGRESS) {
 381                wait_for_completion(&compl.completion);
 382                ret = compl.err;
 383                if (ret)
 384                        goto out6;
 385        }
 386
 387        if (kdfcopy) {
 388                /*
 389                 * Concatenate SP800-56A otherinfo past DH shared secret -- the
 390                 * input to the KDF is (DH shared secret || otherinfo)
 391                 */
 392                if (copy_from_user(outbuf + req->dst_len, kdfcopy->otherinfo,
 393                                   kdfcopy->otherinfolen) != 0) {
 394                        ret = -EFAULT;
 395                        goto out6;
 396                }
 397
 398                ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, outbuf,
 399                                            req->dst_len + kdfcopy->otherinfolen,
 400                                            outlen - req->dst_len);
 401        } else if (copy_to_user(buffer, outbuf, req->dst_len) == 0) {
 402                ret = req->dst_len;
 403        } else {
 404                ret = -EFAULT;
 405        }
 406
 407out6:
 408        kpp_request_free(req);
 409out5:
 410        kzfree(outbuf);
 411out4:
 412        crypto_free_kpp(tfm);
 413out3:
 414        kzfree(secret);
 415out2:
 416        dh_free_data(&dh_inputs);
 417out1:
 418        kdf_dealloc(sdesc);
 419        return ret;
 420}
 421
 422long keyctl_dh_compute(struct keyctl_dh_params __user *params,
 423                       char __user *buffer, size_t buflen,
 424                       struct keyctl_kdf_params __user *kdf)
 425{
 426        struct keyctl_kdf_params kdfcopy;
 427
 428        if (!kdf)
 429                return __keyctl_dh_compute(params, buffer, buflen, NULL);
 430
 431        if (copy_from_user(&kdfcopy, kdf, sizeof(kdfcopy)) != 0)
 432                return -EFAULT;
 433
 434        return __keyctl_dh_compute(params, buffer, buflen, &kdfcopy);
 435}
 436