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