/* Crypto operations using stored keys * * Copyright (c) 2016, Intel Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */ #include #include #include #include #include "internal.h" /* * Public key or shared secret generation function [RFC2631 sec 2.1.1] * * ya = g^xa mod p; * or * ZZ = yb^xa mod p; * * where xa is the local private key, ya is the local public key, g is * the generator, p is the prime, yb is the remote public key, and ZZ * is the shared secret. * * Both are the same calculation, so g or yb are the "base" and ya or * ZZ are the "result". */ static int do_dh(MPI result, MPI base, MPI xa, MPI p) { return mpi_powm(result, base, xa, p); } static ssize_t mpi_from_key(key_serial_t keyid, size_t maxlen, MPI *mpi) { struct key *key; key_ref_t key_ref; long status; ssize_t ret; key_ref = lookup_user_key(keyid, 0, KEY_NEED_READ); if (IS_ERR(key_ref)) { ret = -ENOKEY; goto error; } key = key_ref_to_ptr(key_ref); ret = -EOPNOTSUPP; if (key->type == &key_type_user) { down_read(&key->sem); status = key_validate(key); if (status == 0) { const struct user_key_payload *payload; payload = user_key_payload(key); if (maxlen == 0) { *mpi = NULL; ret = payload->datalen; } else if (payload->datalen <= maxlen) { *mpi = mpi_read_raw_data(payload->data, payload->datalen); if (*mpi) ret = payload->datalen; } else { ret = -EINVAL; } } up_read(&key->sem); } key_put(key); error: return ret; } long keyctl_dh_compute(struct keyctl_dh_params __user *params, char __user *buffer, size_t buflen, void __user *reserved) { long ret; MPI base, private, prime, result; unsigned nbytes; struct keyctl_dh_params pcopy; uint8_t *kbuf; ssize_t keylen; size_t resultlen; if (!params || (!buffer && buflen)) { ret = -EINVAL; goto out; } if (copy_from_user(&pcopy, params, sizeof(pcopy)) != 0) { ret = -EFAULT; goto out; } if (reserved) { ret = -EINVAL; goto out; } keylen = mpi_from_key(pcopy.prime, buflen, &prime); if (keylen < 0 || !prime) { /* buflen == 0 may be used to query the required buffer size, * which is the prime key length. */ ret = keylen; goto out; } /* The result is never longer than the prime */ resultlen = keylen; keylen = mpi_from_key(pcopy.base, SIZE_MAX, &base); if (keylen < 0 || !base) { ret = keylen; goto error1; } keylen = mpi_from_key(pcopy.private, SIZE_MAX, &private); if (keylen < 0 || !private) { ret = keylen; goto error2; } result = mpi_alloc(0); if (!result) { ret = -ENOMEM; goto error3; } kbuf = kmalloc(resultlen, GFP_KERNEL); if (!kbuf) { ret = -ENOMEM; goto error4; } ret = do_dh(result, base, private, prime); if (ret) goto error5; ret = mpi_read_buffer(result, kbuf, resultlen, &nbytes, NULL); if (ret != 0) goto error5; ret = nbytes; if (copy_to_user(buffer, kbuf, nbytes) != 0) ret = -EFAULT; error5: kfree(kbuf); error4: mpi_free(result); error3: mpi_free(private); error2: mpi_free(base); error1: mpi_free(prime); out: return ret; } > 2017-02-07net: add confirm_neigh method to dst_opsJulian Anastasov3-0/+54 2017-02-07tcp: replace dst_confirm with sk_dst_confirmJulian Anastasov3-14/+7 2017-02-07sctp: add dst_pending_confirm flagJulian Anastasov7-12/+31 2017-02-07net: add dst_pending_confirm flag to skbuffJulian Anastasov2-1/+5 2017-02-07sock: add sk_dst_pending_confirm flagJulian Anastasov1-0/+2 2017-02-07ipv6: sr: fix non static symbol warningsWei Yongjun1-4/+4 2017-02-07net/sched: act_mirred: remove duplicated include from act_mirred.cWei Yongjun1-2/+0 2017-02-07net: dsa: Add support for platform dataFlorian Fainelli1-18/+84 2017-02-07net: dsa: Rename and export dev_to_net_device()Florian Fainelli1-2/+3 2017-02-06bridge: fdb: write to used and updated at most once per jiffyNikolay Aleksandrov2-2/+4 2017-02-06bridge: move write-heavy fdb members in their own cache lineNikolay Aleksandrov1-4/+6 2017-02-06bridge: move to workqueue gcNikolay Aleksandrov10-23/+29 2017-02-06bridge: modify bridge and port to have often accessed fields in one cache lineNikolay Aleksandrov1-23/+20 2017-02-06net: dsa: introduce bridge notifierVivien Didelot2-11/+61 2017-02-06net: dsa: add switch notifierVivien Didelot5-0/+70 2017-02-06net: dsa: change state setter scopeVivien Didelot1-6/+9 2017-02-06net: dsa: rollback bridging on errorVivien Didelot1-1/+13 2017-02-06net: dsa: simplify netdevice events handlingVivien Didelot1-28/+16 2017-02-06net: dsa: move netdevice notifier registrationVivien Didelot3-10/+26 2017-02-06net-next: treewide use is_vlan_dev() helper function.Parav Pandit1-1/+2 2017-02-06sctp: process fwd tsn chunk only when prsctp is enabledXin Long1-0/+6 2017-02-06net: remove ndo_neigh_{construct, destroy} from stacked devicesIdo Schimmel