linux/crypto/asymmetric_keys/signature.c
<<
>>
Prefs
   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 aymmetric 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);
 160