^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) /* Signature verification with an asymmetric key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * See Documentation/crypto/asymmetric-keys.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #define pr_fmt(fmt) "SIG: "fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <keys/asymmetric-subtype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/keyctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <crypto/public_key.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <keys/user-type.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "asymmetric_keys.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Destroy a public key signature.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) void public_key_signature_free(struct public_key_signature *sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) if (sig) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) kfree(sig->auth_ids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) kfree(sig->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) kfree(sig->digest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) kfree(sig);
^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) EXPORT_SYMBOL_GPL(public_key_signature_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * query_asymmetric_key - Get information about an aymmetric key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * @params: Various parameters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * @info: Where to put the information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) int query_asymmetric_key(const struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) struct kernel_pkey_query *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) const struct asymmetric_key_subtype *subtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct key *key = params->key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) pr_devel("==>%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (key->type != &key_type_asymmetric)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) subtype = asymmetric_key_subtype(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (!subtype ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) !key->payload.data[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if (!subtype->query)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) ret = subtype->query(params, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) pr_devel("<==%s() = %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) EXPORT_SYMBOL_GPL(query_asymmetric_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * encrypt_blob - Encrypt data using an asymmetric key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * @params: Various parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * @data: Data blob to be encrypted, length params->data_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * @enc: Encrypted data buffer, length params->enc_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) * Encrypt the specified data blob using the private key specified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * params->key. The encrypted data is wrapped in an encoding if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * params->encoding is specified (eg. "pkcs1").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * Returns the length of the data placed in the encrypted data buffer or an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int encrypt_blob(struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const void *data, void *enc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) params->op = kernel_pkey_encrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return asymmetric_key_eds_op(params, data, enc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) EXPORT_SYMBOL_GPL(encrypt_blob);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * decrypt_blob - Decrypt data using an asymmetric key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * @params: Various parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * @enc: Encrypted data to be decrypted, length params->enc_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * @data: Decrypted data buffer, length params->data_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * Decrypt the specified data blob using the private key specified by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * params->key. The decrypted data is wrapped in an encoding if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * params->encoding is specified (eg. "pkcs1").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * Returns the length of the data placed in the decrypted data buffer or an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) int decrypt_blob(struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) const void *enc, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) params->op = kernel_pkey_decrypt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return asymmetric_key_eds_op(params, enc, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) EXPORT_SYMBOL_GPL(decrypt_blob);
^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) * create_signature - Sign some data using an asymmetric key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * @params: Various parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * @data: Data blob to be signed, length params->data_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * @enc: Signature buffer, length params->enc_len
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * Sign the specified data blob using the private key specified by params->key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * The signature is wrapped in an encoding if params->encoding is specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) * (eg. "pkcs1"). If the encoding needs to know the digest type, this can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) * passed through params->hash_algo (eg. "sha1").
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) * Returns the length of the data placed in the signature buffer or an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) int create_signature(struct kernel_pkey_params *params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) const void *data, void *enc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) params->op = kernel_pkey_sign;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return asymmetric_key_eds_op(params, data, enc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) EXPORT_SYMBOL_GPL(create_signature);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * verify_signature - Initiate the use of an asymmetric key to verify a signature
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * @key: The asymmetric key to verify against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * @sig: The signature to check
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * Returns 0 if successful or else an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) int verify_signature(const struct key *key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) const struct public_key_signature *sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) const struct asymmetric_key_subtype *subtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) pr_devel("==>%s()\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (key->type != &key_type_asymmetric)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) subtype = asymmetric_key_subtype(key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (!subtype ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) !key->payload.data[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) if (!subtype->verify_signature)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) return -ENOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) ret = subtype->verify_signature(key, sig);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) pr_devel("<==%s() = %d\n", __func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) EXPORT_SYMBOL_GPL(verify_signature);