1ddbb4114SMat Martineau /* Crypto operations using stored keys 2ddbb4114SMat Martineau * 3ddbb4114SMat Martineau * Copyright (c) 2016, Intel Corporation 4ddbb4114SMat Martineau * 5ddbb4114SMat Martineau * This program is free software; you can redistribute it and/or 6ddbb4114SMat Martineau * modify it under the terms of the GNU General Public License 7ddbb4114SMat Martineau * as published by the Free Software Foundation; either version 8ddbb4114SMat Martineau * 2 of the License, or (at your option) any later version. 9ddbb4114SMat Martineau */ 10ddbb4114SMat Martineau 11ddbb4114SMat Martineau #include <linux/mpi.h> 12ddbb4114SMat Martineau #include <linux/slab.h> 13ddbb4114SMat Martineau #include <linux/uaccess.h> 14*f1c316a3SStephan Mueller #include <linux/crypto.h> 15*f1c316a3SStephan Mueller #include <crypto/hash.h> 16ddbb4114SMat Martineau #include <keys/user-type.h> 17ddbb4114SMat Martineau #include "internal.h" 18ddbb4114SMat Martineau 19ddbb4114SMat Martineau /* 20ddbb4114SMat Martineau * Public key or shared secret generation function [RFC2631 sec 2.1.1] 21ddbb4114SMat Martineau * 22ddbb4114SMat Martineau * ya = g^xa mod p; 23ddbb4114SMat Martineau * or 24ddbb4114SMat Martineau * ZZ = yb^xa mod p; 25ddbb4114SMat Martineau * 26ddbb4114SMat Martineau * where xa is the local private key, ya is the local public key, g is 27ddbb4114SMat Martineau * the generator, p is the prime, yb is the remote public key, and ZZ 28ddbb4114SMat Martineau * is the shared secret. 29ddbb4114SMat Martineau * 30ddbb4114SMat Martineau * Both are the same calculation, so g or yb are the "base" and ya or 31ddbb4114SMat Martineau * ZZ are the "result". 32ddbb4114SMat Martineau */ 33ddbb4114SMat Martineau static int do_dh(MPI result, MPI base, MPI xa, MPI p) 34ddbb4114SMat Martineau { 35ddbb4114SMat Martineau return mpi_powm(result, base, xa, p); 36ddbb4114SMat Martineau } 37ddbb4114SMat Martineau 38ddbb4114SMat Martineau static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi) 39ddbb4114SMat Martineau { 40ddbb4114SMat Martineau struct key *key; 41ddbb4114SMat Martineau key_ref_t key_ref; 42ddbb4114SMat Martineau long status; 43ddbb4114SMat Martineau ssize_t ret; 44ddbb4114SMat Martineau 45ddbb4114SMat Martineau key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ); 46ddbb4114SMat Martineau if (IS_ERR(key_ref)) { 47ddbb4114SMat Martineau ret = -ENOKEY; 48ddbb4114SMat Martineau goto error; 49ddbb4114SMat Martineau } 50ddbb4114SMat Martineau 51ddbb4114SMat Martineau key = key_ref_to_ptr(key_ref); 52ddbb4114SMat Martineau 53ddbb4114SMat Martineau ret = -EOPNOTSUPP; 54ddbb4114SMat Martineau if (key->type == &key_type_user) { 55ddbb4114SMat Martineau down_read(&key->sem); 56ddbb4114SMat Martineau status = key_validate(key); 57ddbb4114SMat Martineau if (status == 0) { 58ddbb4114SMat Martineau const struct user_key_payload *payload; 59ddbb4114SMat Martineau 600837e49aSDavid Howells payload = user_key_payload_locked(key); 61ddbb4114SMat Martineau 62ddbb4114SMat Martineau if (maxlen == 0) { 63ddbb4114SMat Martineau *mpi = NULL; 64ddbb4114SMat Martineau ret = payload->datalen; 65ddbb4114SMat Martineau } else if (payload->datalen <= maxlen) { 66ddbb4114SMat Martineau *mpi = mpi_read_raw_data(payload->data, 67ddbb4114SMat Martineau payload->datalen); 68ddbb4114SMat Martineau if (*mpi) 69ddbb4114SMat Martineau ret = payload->datalen; 70ddbb4114SMat Martineau } else { 71ddbb4114SMat Martineau ret = -EINVAL; 72ddbb4114SMat Martineau } 73ddbb4114SMat Martineau } 74ddbb4114SMat Martineau up_read(&key->sem); 75ddbb4114SMat Martineau } 76ddbb4114SMat Martineau 77ddbb4114SMat Martineau key_put(key); 78ddbb4114SMat Martineau error: 79ddbb4114SMat Martineau return ret; 80ddbb4114SMat Martineau } 81ddbb4114SMat Martineau 82*f1c316a3SStephan Mueller struct kdf_sdesc { 83*f1c316a3SStephan Mueller struct shash_desc shash; 84*f1c316a3SStephan Mueller char ctx[]; 85*f1c316a3SStephan Mueller }; 86*f1c316a3SStephan Mueller 87*f1c316a3SStephan Mueller static int kdf_alloc(struct kdf_sdesc **sdesc_ret, char *hashname) 88*f1c316a3SStephan Mueller { 89*f1c316a3SStephan Mueller struct crypto_shash *tfm; 90*f1c316a3SStephan Mueller struct kdf_sdesc *sdesc; 91*f1c316a3SStephan Mueller int size; 92*f1c316a3SStephan Mueller 93*f1c316a3SStephan Mueller /* allocate synchronous hash */ 94*f1c316a3SStephan Mueller tfm = crypto_alloc_shash(hashname, 0, 0); 95*f1c316a3SStephan Mueller if (IS_ERR(tfm)) { 96*f1c316a3SStephan Mueller pr_info("could not allocate digest TFM handle %s\n", hashname); 97*f1c316a3SStephan Mueller return PTR_ERR(tfm); 98*f1c316a3SStephan Mueller } 99*f1c316a3SStephan Mueller 100*f1c316a3SStephan Mueller size = sizeof(struct shash_desc) + crypto_shash_descsize(tfm); 101*f1c316a3SStephan Mueller sdesc = kmalloc(size, GFP_KERNEL); 102*f1c316a3SStephan Mueller if (!sdesc) 103*f1c316a3SStephan Mueller return -ENOMEM; 104*f1c316a3SStephan Mueller sdesc->shash.tfm = tfm; 105*f1c316a3SStephan Mueller sdesc->shash.flags = 0x0; 106*f1c316a3SStephan Mueller 107*f1c316a3SStephan Mueller *sdesc_ret = sdesc; 108*f1c316a3SStephan Mueller 109*f1c316a3SStephan Mueller return 0; 110*f1c316a3SStephan Mueller } 111*f1c316a3SStephan Mueller 112*f1c316a3SStephan Mueller static void kdf_dealloc(struct kdf_sdesc *sdesc) 113*f1c316a3SStephan Mueller { 114*f1c316a3SStephan Mueller if (!sdesc) 115*f1c316a3SStephan Mueller return; 116*f1c316a3SStephan Mueller 117*f1c316a3SStephan Mueller if (sdesc->shash.tfm) 118*f1c316a3SStephan Mueller crypto_free_shash(sdesc->shash.tfm); 119*f1c316a3SStephan Mueller 120*f1c316a3SStephan Mueller kzfree(sdesc); 121*f1c316a3SStephan Mueller } 122*f1c316a3SStephan Mueller 123*f1c316a3SStephan Mueller /* convert 32 bit integer into its string representation */ 124*f1c316a3SStephan Mueller static inline void crypto_kw_cpu_to_be32(u32 val, u8 *buf) 125*f1c316a3SStephan Mueller { 126*f1c316a3SStephan Mueller __be32 *a = (__be32 *)buf; 127*f1c316a3SStephan Mueller 128*f1c316a3SStephan Mueller *a = cpu_to_be32(val); 129*f1c316a3SStephan Mueller } 130*f1c316a3SStephan Mueller 131*f1c316a3SStephan Mueller /* 132*f1c316a3SStephan Mueller * Implementation of the KDF in counter mode according to SP800-108 section 5.1 133*f1c316a3SStephan Mueller * as well as SP800-56A section 5.8.1 (Single-step KDF). 134*f1c316a3SStephan Mueller * 135*f1c316a3SStephan Mueller * SP800-56A: 136*f1c316a3SStephan Mueller * The src pointer is defined as Z || other info where Z is the shared secret 137*f1c316a3SStephan Mueller * from DH and other info is an arbitrary string (see SP800-56A section 138*f1c316a3SStephan Mueller * 5.8.1.2). 139*f1c316a3SStephan Mueller */ 140*f1c316a3SStephan Mueller static int kdf_ctr(struct kdf_sdesc *sdesc, const u8 *src, unsigned int slen, 141*f1c316a3SStephan Mueller u8 *dst, unsigned int dlen) 142*f1c316a3SStephan Mueller { 143*f1c316a3SStephan Mueller struct shash_desc *desc = &sdesc->shash; 144*f1c316a3SStephan Mueller unsigned int h = crypto_shash_digestsize(desc->tfm); 145*f1c316a3SStephan Mueller int err = 0; 146*f1c316a3SStephan Mueller u8 *dst_orig = dst; 147*f1c316a3SStephan Mueller u32 i = 1; 148*f1c316a3SStephan Mueller u8 iteration[sizeof(u32)]; 149*f1c316a3SStephan Mueller 150*f1c316a3SStephan Mueller while (dlen) { 151*f1c316a3SStephan Mueller err = crypto_shash_init(desc); 152*f1c316a3SStephan Mueller if (err) 153*f1c316a3SStephan Mueller goto err; 154*f1c316a3SStephan Mueller 155*f1c316a3SStephan Mueller crypto_kw_cpu_to_be32(i, iteration); 156*f1c316a3SStephan Mueller err = crypto_shash_update(desc, iteration, sizeof(u32)); 157*f1c316a3SStephan Mueller if (err) 158*f1c316a3SStephan Mueller goto err; 159*f1c316a3SStephan Mueller 160*f1c316a3SStephan Mueller if (src && slen) { 161*f1c316a3SStephan Mueller err = crypto_shash_update(desc, src, slen); 162*f1c316a3SStephan Mueller if (err) 163*f1c316a3SStephan Mueller goto err; 164*f1c316a3SStephan Mueller } 165*f1c316a3SStephan Mueller 166*f1c316a3SStephan Mueller if (dlen < h) { 167*f1c316a3SStephan Mueller u8 tmpbuffer[h]; 168*f1c316a3SStephan Mueller 169*f1c316a3SStephan Mueller err = crypto_shash_final(desc, tmpbuffer); 170*f1c316a3SStephan Mueller if (err) 171*f1c316a3SStephan Mueller goto err; 172*f1c316a3SStephan Mueller memcpy(dst, tmpbuffer, dlen); 173*f1c316a3SStephan Mueller memzero_explicit(tmpbuffer, h); 174*f1c316a3SStephan Mueller return 0; 175*f1c316a3SStephan Mueller } else { 176*f1c316a3SStephan Mueller err = crypto_shash_final(desc, dst); 177*f1c316a3SStephan Mueller if (err) 178*f1c316a3SStephan Mueller goto err; 179*f1c316a3SStephan Mueller 180*f1c316a3SStephan Mueller dlen -= h; 181*f1c316a3SStephan Mueller dst += h; 182*f1c316a3SStephan Mueller i++; 183*f1c316a3SStephan Mueller } 184*f1c316a3SStephan Mueller } 185*f1c316a3SStephan Mueller 186*f1c316a3SStephan Mueller return 0; 187*f1c316a3SStephan Mueller 188*f1c316a3SStephan Mueller err: 189*f1c316a3SStephan Mueller memzero_explicit(dst_orig, dlen); 190*f1c316a3SStephan Mueller return err; 191*f1c316a3SStephan Mueller } 192*f1c316a3SStephan Mueller 193*f1c316a3SStephan Mueller static int keyctl_dh_compute_kdf(struct kdf_sdesc *sdesc, 1944693fc73SStephan Mueller char __user *buffer, size_t buflen, 195*f1c316a3SStephan Mueller uint8_t *kbuf, size_t kbuflen) 196*f1c316a3SStephan Mueller { 197*f1c316a3SStephan Mueller uint8_t *outbuf = NULL; 198*f1c316a3SStephan Mueller int ret; 199*f1c316a3SStephan Mueller 200*f1c316a3SStephan Mueller outbuf = kmalloc(buflen, GFP_KERNEL); 201*f1c316a3SStephan Mueller if (!outbuf) { 202*f1c316a3SStephan Mueller ret = -ENOMEM; 203*f1c316a3SStephan Mueller goto err; 204*f1c316a3SStephan Mueller } 205*f1c316a3SStephan Mueller 206*f1c316a3SStephan Mueller ret = kdf_ctr(sdesc, kbuf, kbuflen, outbuf, buflen); 207*f1c316a3SStephan Mueller if (ret) 208*f1c316a3SStephan Mueller goto err; 209*f1c316a3SStephan Mueller 210*f1c316a3SStephan Mueller ret = buflen; 211*f1c316a3SStephan Mueller if (copy_to_user(buffer, outbuf, buflen) != 0) 212*f1c316a3SStephan Mueller ret = -EFAULT; 213*f1c316a3SStephan Mueller 214*f1c316a3SStephan Mueller err: 215*f1c316a3SStephan Mueller kzfree(outbuf); 216*f1c316a3SStephan Mueller return ret; 217*f1c316a3SStephan Mueller } 218*f1c316a3SStephan Mueller 219*f1c316a3SStephan Mueller long __keyctl_dh_compute(struct keyctl_dh_params __user *params, 220*f1c316a3SStephan Mueller char __user *buffer, size_t buflen, 221*f1c316a3SStephan Mueller struct keyctl_kdf_params *kdfcopy) 222ddbb4114SMat Martineau { 223ddbb4114SMat Martineau long ret; 224ddbb4114SMat Martineau MPI base, private, prime, result; 225ddbb4114SMat Martineau unsigned nbytes; 226ddbb4114SMat Martineau struct keyctl_dh_params pcopy; 227ddbb4114SMat Martineau uint8_t *kbuf; 228ddbb4114SMat Martineau ssize_t keylen; 229ddbb4114SMat Martineau size_t resultlen; 230*f1c316a3SStephan Mueller struct kdf_sdesc *sdesc = NULL; 231ddbb4114SMat Martineau 232ddbb4114SMat Martineau if (!params || (!buffer && buflen)) { 233ddbb4114SMat Martineau ret = -EINVAL; 234ddbb4114SMat Martineau goto out; 235ddbb4114SMat Martineau } 236ddbb4114SMat Martineau if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) { 237ddbb4114SMat Martineau ret = -EFAULT; 238ddbb4114SMat Martineau goto out; 239ddbb4114SMat Martineau } 240ddbb4114SMat Martineau 241*f1c316a3SStephan Mueller if (kdfcopy) { 242*f1c316a3SStephan Mueller char *hashname; 243*f1c316a3SStephan Mueller 244*f1c316a3SStephan Mueller if (buflen > KEYCTL_KDF_MAX_OUTPUT_LEN || 245*f1c316a3SStephan Mueller kdfcopy->otherinfolen > KEYCTL_KDF_MAX_OI_LEN) { 246*f1c316a3SStephan Mueller ret = -EMSGSIZE; 2474693fc73SStephan Mueller goto out; 2484693fc73SStephan Mueller } 2494693fc73SStephan Mueller 250*f1c316a3SStephan Mueller /* get KDF name string */ 251*f1c316a3SStephan Mueller hashname = strndup_user(kdfcopy->hashname, CRYPTO_MAX_ALG_NAME); 252*f1c316a3SStephan Mueller if (IS_ERR(hashname)) { 253*f1c316a3SStephan Mueller ret = PTR_ERR(hashname); 254*f1c316a3SStephan Mueller goto out; 255*f1c316a3SStephan Mueller } 256*f1c316a3SStephan Mueller 257*f1c316a3SStephan Mueller /* allocate KDF from the kernel crypto API */ 258*f1c316a3SStephan Mueller ret = kdf_alloc(&sdesc, hashname); 259*f1c316a3SStephan Mueller kfree(hashname); 260*f1c316a3SStephan Mueller if (ret) 261*f1c316a3SStephan Mueller goto out; 262*f1c316a3SStephan Mueller } 263*f1c316a3SStephan Mueller 264*f1c316a3SStephan Mueller /* 265*f1c316a3SStephan Mueller * If the caller requests postprocessing with a KDF, allow an 266*f1c316a3SStephan Mueller * arbitrary output buffer size since the KDF ensures proper truncation. 267*f1c316a3SStephan Mueller */ 268*f1c316a3SStephan Mueller keylen = mpi_from_key(pcopy.prime, kdfcopy ? SIZE_MAX : buflen, &prime); 269ddbb4114SMat Martineau if (keylen < 0 || !prime) { 270ddbb4114SMat Martineau /* buflen == 0 may be used to query the required buffer size, 271ddbb4114SMat Martineau * which is the prime key length. 272ddbb4114SMat Martineau */ 273ddbb4114SMat Martineau ret = keylen; 274ddbb4114SMat Martineau goto out; 275ddbb4114SMat Martineau } 276ddbb4114SMat Martineau 277ddbb4114SMat Martineau /* The result is never longer than the prime */ 278ddbb4114SMat Martineau resultlen = keylen; 279ddbb4114SMat Martineau 280ddbb4114SMat Martineau keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base); 281ddbb4114SMat Martineau if (keylen < 0 || !base) { 282ddbb4114SMat Martineau ret = keylen; 283ddbb4114SMat Martineau goto error1; 284ddbb4114SMat Martineau } 285ddbb4114SMat Martineau 286ddbb4114SMat Martineau keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private); 287ddbb4114SMat Martineau if (keylen < 0 || !private) { 288ddbb4114SMat Martineau ret = keylen; 289ddbb4114SMat Martineau goto error2; 290ddbb4114SMat Martineau } 291ddbb4114SMat Martineau 292ddbb4114SMat Martineau result = mpi_alloc(0); 293ddbb4114SMat Martineau if (!result) { 294ddbb4114SMat Martineau ret = -ENOMEM; 295ddbb4114SMat Martineau goto error3; 296ddbb4114SMat Martineau } 297ddbb4114SMat Martineau 298*f1c316a3SStephan Mueller /* allocate space for DH shared secret and SP800-56A otherinfo */ 299*f1c316a3SStephan Mueller kbuf = kmalloc(kdfcopy ? (resultlen + kdfcopy->otherinfolen) : resultlen, 300*f1c316a3SStephan Mueller GFP_KERNEL); 301ddbb4114SMat Martineau if (!kbuf) { 302ddbb4114SMat Martineau ret = -ENOMEM; 303ddbb4114SMat Martineau goto error4; 304ddbb4114SMat Martineau } 305ddbb4114SMat Martineau 306*f1c316a3SStephan Mueller /* 307*f1c316a3SStephan Mueller * Concatenate SP800-56A otherinfo past DH shared secret -- the 308*f1c316a3SStephan Mueller * input to the KDF is (DH shared secret || otherinfo) 309*f1c316a3SStephan Mueller */ 310*f1c316a3SStephan Mueller if (kdfcopy && kdfcopy->otherinfo && 311*f1c316a3SStephan Mueller copy_from_user(kbuf + resultlen, kdfcopy->otherinfo, 312*f1c316a3SStephan Mueller kdfcopy->otherinfolen) != 0) { 313*f1c316a3SStephan Mueller ret = -EFAULT; 314*f1c316a3SStephan Mueller goto error5; 315*f1c316a3SStephan Mueller } 316*f1c316a3SStephan Mueller 317ddbb4114SMat Martineau ret = do_dh(result, base, private, prime); 318ddbb4114SMat Martineau if (ret) 319ddbb4114SMat Martineau goto error5; 320ddbb4114SMat Martineau 321ddbb4114SMat Martineau ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL); 322ddbb4114SMat Martineau if (ret != 0) 323ddbb4114SMat Martineau goto error5; 324ddbb4114SMat Martineau 325*f1c316a3SStephan Mueller if (kdfcopy) { 326*f1c316a3SStephan Mueller ret = keyctl_dh_compute_kdf(sdesc, buffer, buflen, kbuf, 327*f1c316a3SStephan Mueller resultlen + kdfcopy->otherinfolen); 328*f1c316a3SStephan Mueller } else { 329ddbb4114SMat Martineau ret = nbytes; 330ddbb4114SMat Martineau if (copy_to_user(buffer, kbuf, nbytes) != 0) 331ddbb4114SMat Martineau ret = -EFAULT; 332*f1c316a3SStephan Mueller } 333ddbb4114SMat Martineau 334ddbb4114SMat Martineau error5: 335*f1c316a3SStephan Mueller kzfree(kbuf); 336ddbb4114SMat Martineau error4: 337ddbb4114SMat Martineau mpi_free(result); 338ddbb4114SMat Martineau error3: 339ddbb4114SMat Martineau mpi_free(private); 340ddbb4114SMat Martineau error2: 341ddbb4114SMat Martineau mpi_free(base); 342ddbb4114SMat Martineau error1: 343ddbb4114SMat Martineau mpi_free(prime); 344ddbb4114SMat Martineau out: 345*f1c316a3SStephan Mueller kdf_dealloc(sdesc); 346ddbb4114SMat Martineau return ret; 347ddbb4114SMat Martineau } 348*f1c316a3SStephan Mueller 349*f1c316a3SStephan Mueller long keyctl_dh_compute(struct keyctl_dh_params __user *params, 350*f1c316a3SStephan Mueller char __user *buffer, size_t buflen, 351*f1c316a3SStephan Mueller struct keyctl_kdf_params __user *kdf) 352*f1c316a3SStephan Mueller { 353*f1c316a3SStephan Mueller struct keyctl_kdf_params kdfcopy; 354*f1c316a3SStephan Mueller 355*f1c316a3SStephan Mueller if (!kdf) 356*f1c316a3SStephan Mueller return __keyctl_dh_compute(params, buffer, buflen, NULL); 357*f1c316a3SStephan Mueller 358*f1c316a3SStephan Mueller if (copy_from_user(&kdfcopy, kdf, sizeof(kdfcopy)) != 0) 359*f1c316a3SStephan Mueller return -EFAULT; 360*f1c316a3SStephan Mueller 361*f1c316a3SStephan Mueller return __keyctl_dh_compute(params, buffer, buflen, &kdfcopy); 362*f1c316a3SStephan Mueller } 363