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/mpi.h> 12 #include <linux/slab.h> 13 #include <linux/uaccess.h> 14 #include <keys/user-type.h> 15 #include "internal.h" 16 17 /* 18 * Public key or shared secret generation function [RFC2631 sec 2.1.1] 19 * 20 * ya = g^xa mod p; 21 * or 22 * ZZ = yb^xa mod p; 23 * 24 * where xa is the local private key, ya is the local public key, g is 25 * the generator, p is the prime, yb is the remote public key, and ZZ 26 * is the shared secret. 27 * 28 * Both are the same calculation, so g or yb are the "base" and ya or 29 * ZZ are the "result". 30 */ 31 static int do_dh(MPI result, MPI base, MPI xa, MPI p) 32 { 33 return mpi_powm(result, base, xa, p); 34 } 35 36 static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi) 37 { 38 struct key *key; 39 key_ref_t key_ref; 40 long status; 41 ssize_t ret; 42 43 key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ); 44 if (IS_ERR(key_ref)) { 45 ret = -ENOKEY; 46 goto error; 47 } 48 49 key = key_ref_to_ptr(key_ref); 50 51 ret = -EOPNOTSUPP; 52 if (key->type == &key_type_user) { 53 down_read(&key->sem); 54 status = key_validate(key); 55 if (status == 0) { 56 const struct user_key_payload *payload; 57 58 payload = user_key_payload(key); 59 60 if (maxlen == 0) { 61 *mpi = NULL; 62 ret = payload->datalen; 63 } else if (payload->datalen <= maxlen) { 64 *mpi = mpi_read_raw_data(payload->data, 65 payload->datalen); 66 if (*mpi) 67 ret = payload->datalen; 68 } else { 69 ret = -EINVAL; 70 } 71 } 72 up_read(&key->sem); 73 } 74 75 key_put(key); 76 error: 77 return ret; 78 } 79 80 long keyctl_dh_compute(struct keyctl_dh_params __user *params, 81 char __user *buffer, size_t buflen, 82 void __user *reserved) 83 { 84 long ret; 85 MPI base, private, prime, result; 86 unsigned nbytes; 87 struct keyctl_dh_params pcopy; 88 uint8_t *kbuf; 89 ssize_t keylen; 90 size_t resultlen; 91 92 if (!params || (!buffer && buflen)) { 93 ret = -EINVAL; 94 goto out; 95 } 96 if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) { 97 ret = -EFAULT; 98 goto out; 99 } 100 101 if (reserved) { 102 ret = -EINVAL; 103 goto out; 104 } 105 106 keylen = mpi_from_key(pcopy.prime, buflen, &prime); 107 if (keylen < 0 || !prime) { 108 /* buflen == 0 may be used to query the required buffer size, 109 * which is the prime key length. 110 */ 111 ret = keylen; 112 goto out; 113 } 114 115 /* The result is never longer than the prime */ 116 resultlen = keylen; 117 118 keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base); 119 if (keylen < 0 || !base) { 120 ret = keylen; 121 goto error1; 122 } 123 124 keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private); 125 if (keylen < 0 || !private) { 126 ret = keylen; 127 goto error2; 128 } 129 130 result = mpi_alloc(0); 131 if (!result) { 132 ret = -ENOMEM; 133 goto error3; 134 } 135 136 kbuf = kmalloc(resultlen, GFP_KERNEL); 137 if (!kbuf) { 138 ret = -ENOMEM; 139 goto error4; 140 } 141 142 ret = do_dh(result, base, private, prime); 143 if (ret) 144 goto error5; 145 146 ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL); 147 if (ret != 0) 148 goto error5; 149 150 ret = nbytes; 151 if (copy_to_user(buffer, kbuf, nbytes) != 0) 152 ret = -EFAULT; 153 154 error5: 155 kfree(kbuf); 156 error4: 157 mpi_free(result); 158 error3: 159 mpi_free(private); 160 error2: 161 mpi_free(base); 162 error1: 163 mpi_free(prime); 164 out: 165 return ret; 166 } 167