^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Public-key operation keyctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/keyctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/parser.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <keys/user-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static void keyctl_pkey_params_free(struct kernel_pkey_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) kfree(params->info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) key_put(params->key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) Opt_err,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) Opt_enc, /* "enc=<encoding>" eg. "enc=oaep" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) Opt_hash, /* "hash=<digest-name>" eg. "hash=sha1" */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static const match_table_t param_keys = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) { Opt_enc, "enc=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) { Opt_hash, "hash=%s" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { Opt_err, NULL }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * Parse the information string which consists of key=val pairs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) static int keyctl_pkey_params_parse(struct kernel_pkey_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) unsigned long token_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) substring_t args[MAX_OPT_ARGS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) char *c = params->info, *p, *q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) int token;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) while ((p = strsep(&c, " \t"))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) if (*p == '\0' || *p == ' ' || *p == '\t')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) token = match_token(p, param_keys, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) if (token == Opt_err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (__test_and_set_bit(token, &token_mask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) q = args[0].from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!q[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) switch (token) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) case Opt_enc:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) params->encoding = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) case Opt_hash:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) params->hash_algo = q;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Interpret parameters. Callers must always call the free function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * on params, even if an error is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static int keyctl_pkey_params_get(key_serial_t id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) const char __user *_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) struct kernel_pkey_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) key_ref_t key_ref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) memset(params, 0, sizeof(*params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) params->encoding = "raw";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) p = strndup_user(_info, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (IS_ERR(p))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return PTR_ERR(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) params->info = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) ret = keyctl_pkey_params_parse(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) key_ref = lookup_user_key(id, 0, KEY_NEED_SEARCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (IS_ERR(key_ref))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return PTR_ERR(key_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) params->key = key_ref_to_ptr(key_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (!params->key->type->asym_query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Get parameters from userspace. Callers must always call the free function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * on params, even if an error is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) static int keyctl_pkey_params_get_2(const struct keyctl_pkey_params __user *_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) const char __user *_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) struct kernel_pkey_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct keyctl_pkey_params uparams;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) struct kernel_pkey_query info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) memset(params, 0, sizeof(*params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) params->encoding = "raw";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (copy_from_user(&uparams, _params, sizeof(uparams)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) ret = keyctl_pkey_params_get(uparams.key_id, _info, params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) ret = params->key->type->asym_query(params, &info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) case KEYCTL_PKEY_ENCRYPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (uparams.in_len > info.max_dec_size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) uparams.out_len > info.max_enc_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) case KEYCTL_PKEY_DECRYPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if (uparams.in_len > info.max_enc_size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) uparams.out_len > info.max_dec_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) case KEYCTL_PKEY_SIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (uparams.in_len > info.max_data_size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) uparams.out_len > info.max_sig_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) case KEYCTL_PKEY_VERIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (uparams.in_len > info.max_data_size ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) uparams.in2_len > info.max_sig_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) params->in_len = uparams.in_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) params->out_len = uparams.out_len; /* Note: same as in2_len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) * Query information about an asymmetric key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) long keyctl_pkey_query(key_serial_t id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) const char __user *_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) struct keyctl_pkey_query __user *_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) struct kernel_pkey_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) struct kernel_pkey_query res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) memset(¶ms, 0, sizeof(params));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ret = keyctl_pkey_params_get(id, _info, ¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ret = params.key->type->asym_query(¶ms, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (copy_to_user(_res, &res, sizeof(res)) == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) clear_user(_res->__spare, sizeof(_res->__spare)) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) keyctl_pkey_params_free(¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * Encrypt/decrypt/sign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * Encrypt data, decrypt data or sign data using a public key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * _info is a string of supplementary information in key=val format. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * instance, it might contain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * "enc=pkcs1 hash=sha256"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * where enc= specifies the encoding and hash= selects the OID to go in that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * particular encoding if required. If enc= isn't supplied, it's assumed that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) * the caller is supplying raw values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * If successful, the amount of data written into the output buffer is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) long keyctl_pkey_e_d_s(int op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) const struct keyctl_pkey_params __user *_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) const char __user *_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) const void __user *_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) void __user *_out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct kernel_pkey_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) void *in, *out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) ret = keyctl_pkey_params_get_2(_params, _info, op, ¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) goto error_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (!params.key->type->asym_eds_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto error_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) switch (op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) case KEYCTL_PKEY_ENCRYPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) params.op = kernel_pkey_encrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) case KEYCTL_PKEY_DECRYPT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) params.op = kernel_pkey_decrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) case KEYCTL_PKEY_SIGN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) params.op = kernel_pkey_sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) in = memdup_user(_in, params.in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (IS_ERR(in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) ret = PTR_ERR(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) goto error_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) out = kmalloc(params.out_len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!out)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto error_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ret = params.key->type->asym_eds_op(¶ms, in, out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) goto error_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (copy_to_user(_out, out, ret) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) error_out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) kfree(out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) error_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) kfree(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) error_params:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) keyctl_pkey_params_free(¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * Verify a signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * Verify a public key signature using the given key, or if not given, search
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * for a matching key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * _info is a string of supplementary information in key=val format. For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) * instance, it might contain:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * "enc=pkcs1 hash=sha256"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * where enc= specifies the signature blob encoding and hash= selects the OID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * to go in that particular encoding. If enc= isn't supplied, it's assumed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * that the caller is supplying raw values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * If successful, 0 is returned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) long keyctl_pkey_verify(const struct keyctl_pkey_params __user *_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) const char __user *_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) const void __user *_in,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) const void __user *_in2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) struct kernel_pkey_params params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) void *in, *in2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) long ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ret = keyctl_pkey_params_get_2(_params, _info, KEYCTL_PKEY_VERIFY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) goto error_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ret = -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) if (!params.key->type->asym_verify_signature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) goto error_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) in = memdup_user(_in, params.in_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (IS_ERR(in)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) ret = PTR_ERR(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) goto error_params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) in2 = memdup_user(_in2, params.in2_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (IS_ERR(in2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) ret = PTR_ERR(in2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) goto error_in;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) params.op = kernel_pkey_verify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ret = params.key->type->asym_verify_signature(¶ms, in, in2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) kfree(in2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) error_in:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) kfree(in);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) error_params:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) keyctl_pkey_params_free(¶ms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }