Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0-or-later 2 : : /* Signature verification with an asymmetric key 3 : : * 4 : : * See Documentation/crypto/asymmetric-keys.txt 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 : 1616 : void public_key_signature_free(struct public_key_signature *sig) 24 : : { 25 : : int i; 26 : : 27 [ + + ]: 1616 : if (sig) { 28 [ + + ]: 2424 : for (i = 0; i < ARRAY_SIZE(sig->auth_ids); i++) 29 : 2424 : kfree(sig->auth_ids[i]); 30 : 1212 : kfree(sig->s); 31 : 1212 : kfree(sig->digest); 32 : 1212 : kfree(sig); 33 : : } 34 : 1616 : } 35 : : EXPORT_SYMBOL_GPL(public_key_signature_free); 36 : : 37 : : /** 38 : : * query_asymmetric_key - Get information about an aymmetric key. 39 : : * @params: Various parameters. 40 : : * @info: Where to put the information. 41 : : */ 42 : 0 : 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 : 0 : struct key *key = params->key; 47 : : int ret; 48 : : 49 : : pr_devel("==>%s()\n", __func__); 50 : : 51 [ # # ]: 0 : if (key->type != &key_type_asymmetric) 52 : : return -EINVAL; 53 : : subtype = asymmetric_key_subtype(key); 54 [ # # # # ]: 0 : if (!subtype || 55 : 0 : !key->payload.data[0]) 56 : : return -EINVAL; 57 [ # # ]: 0 : if (!subtype->query) 58 : : return -ENOTSUPP; 59 : : 60 : 0 : ret = subtype->query(params, info); 61 : : 62 : : pr_devel("<==%s() = %d\n", __func__, ret); 63 : 0 : 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 : 0 : int encrypt_blob(struct kernel_pkey_params *params, 81 : : const void *data, void *enc) 82 : : { 83 : 0 : params->op = kernel_pkey_encrypt; 84 : 0 : 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 : 0 : int decrypt_blob(struct kernel_pkey_params *params, 102 : : const void *enc, void *data) 103 : : { 104 : 0 : params->op = kernel_pkey_decrypt; 105 : 0 : 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 : 0 : int create_signature(struct kernel_pkey_params *params, 123 : : const void *data, void *enc) 124 : : { 125 : 0 : params->op = kernel_pkey_sign; 126 : 0 : 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 : 404 : 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 [ + - ]: 404 : if (key->type != &key_type_asymmetric) 146 : : return -EINVAL; 147 : : subtype = asymmetric_key_subtype(key); 148 [ + - + - ]: 808 : if (!subtype || 149 : 404 : !key->payload.data[0]) 150 : : return -EINVAL; 151 [ + - ]: 404 : if (!subtype->verify_signature) 152 : : return -ENOTSUPP; 153 : : 154 : 404 : ret = subtype->verify_signature(key, sig); 155 : : 156 : : pr_devel("<==%s() = %d\n", __func__, ret); 157 : 404 : return ret; 158 : : } 159 : : EXPORT_SYMBOL_GPL(verify_signature);