cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

signature.c (4487B)


      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 */
     23void 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}
     35EXPORT_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 */
     42int 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}
     65EXPORT_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 */
     80int 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}
     86EXPORT_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 */
    101int 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}
    107EXPORT_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 */
    122int 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}
    128EXPORT_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 */
    137int 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}
    159EXPORT_SYMBOL_GPL(verify_signature);