2019-05-20 20:08:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2012-09-22 02:25:04 +04:00
/* Signature verification with an asymmetric key
*
2020-06-15 09:50:08 +03:00
* See Documentation / crypto / asymmetric - keys . rst
2012-09-22 02:25:04 +04:00
*
* Copyright ( C ) 2012 Red Hat , Inc . All Rights Reserved .
* Written by David Howells ( dhowells @ redhat . com )
*/
2014-09-02 16:52:15 +04:00
# define pr_fmt(fmt) "SIG: "fmt
2012-09-22 02:25:04 +04:00
# include <keys/asymmetric-subtype.h>
2015-12-09 23:05:28 +03:00
# include <linux/export.h>
2012-09-22 02:25:04 +04:00
# include <linux/err.h>
2016-04-06 18:13:33 +03:00
# include <linux/slab.h>
2018-10-09 19:47:07 +03:00
# include <linux/keyctl.h>
2012-09-22 02:25:04 +04:00
# include <crypto/public_key.h>
2018-10-09 19:47:07 +03:00
# include <keys/user-type.h>
2012-09-22 02:25:04 +04:00
# include "asymmetric_keys.h"
2016-04-06 18:13:33 +03:00
/*
* Destroy a public key signature .
*/
void public_key_signature_free ( struct public_key_signature * sig )
{
2016-04-06 18:13:33 +03:00
int i ;
2016-04-06 18:13:33 +03:00
if ( sig ) {
2016-04-06 18:13:33 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( sig - > auth_ids ) ; i + + )
kfree ( sig - > auth_ids [ i ] ) ;
2016-04-06 18:13:33 +03:00
kfree ( sig - > s ) ;
kfree ( sig - > digest ) ;
kfree ( sig ) ;
}
}
EXPORT_SYMBOL_GPL ( public_key_signature_free ) ;
2018-10-09 19:47:07 +03:00
/**
2022-02-22 01:31:18 +03:00
* query_asymmetric_key - Get information about an asymmetric key .
2018-10-09 19:47:07 +03:00
* @ params : Various parameters .
* @ info : Where to put the information .
*/
int query_asymmetric_key ( const struct kernel_pkey_params * params ,
struct kernel_pkey_query * info )
{
const struct asymmetric_key_subtype * subtype ;
struct key * key = params - > key ;
int ret ;
pr_devel ( " ==>%s() \n " , __func__ ) ;
if ( key - > type ! = & key_type_asymmetric )
return - EINVAL ;
subtype = asymmetric_key_subtype ( key ) ;
if ( ! subtype | |
! key - > payload . data [ 0 ] )
return - EINVAL ;
if ( ! subtype - > query )
return - ENOTSUPP ;
ret = subtype - > query ( params , info ) ;
pr_devel ( " <==%s() = %d \n " , __func__ , ret ) ;
return ret ;
}
EXPORT_SYMBOL_GPL ( query_asymmetric_key ) ;
/**
* encrypt_blob - Encrypt data using an asymmetric key
* @ params : Various parameters
* @ data : Data blob to be encrypted , length params - > data_len
* @ enc : Encrypted data buffer , length params - > enc_len
*
* Encrypt the specified data blob using the private key specified by
* params - > key . The encrypted data is wrapped in an encoding if
* params - > encoding is specified ( eg . " pkcs1 " ) .
*
* Returns the length of the data placed in the encrypted data buffer or an
* error .
*/
int encrypt_blob ( struct kernel_pkey_params * params ,
const void * data , void * enc )
{
params - > op = kernel_pkey_encrypt ;
return asymmetric_key_eds_op ( params , data , enc ) ;
}
EXPORT_SYMBOL_GPL ( encrypt_blob ) ;
/**
* decrypt_blob - Decrypt data using an asymmetric key
* @ params : Various parameters
* @ enc : Encrypted data to be decrypted , length params - > enc_len
* @ data : Decrypted data buffer , length params - > data_len
*
* Decrypt the specified data blob using the private key specified by
* params - > key . The decrypted data is wrapped in an encoding if
* params - > encoding is specified ( eg . " pkcs1 " ) .
*
* Returns the length of the data placed in the decrypted data buffer or an
* error .
*/
int decrypt_blob ( struct kernel_pkey_params * params ,
const void * enc , void * data )
{
params - > op = kernel_pkey_decrypt ;
return asymmetric_key_eds_op ( params , enc , data ) ;
}
EXPORT_SYMBOL_GPL ( decrypt_blob ) ;
/**
* create_signature - Sign some data using an asymmetric key
* @ params : Various parameters
* @ data : Data blob to be signed , length params - > data_len
* @ enc : Signature buffer , length params - > enc_len
*
* Sign the specified data blob using the private key specified by params - > key .
* The signature is wrapped in an encoding if params - > encoding is specified
* ( eg . " pkcs1 " ) . If the encoding needs to know the digest type , this can be
* passed through params - > hash_algo ( eg . " sha1 " ) .
*
* Returns the length of the data placed in the signature buffer or an error .
*/
int create_signature ( struct kernel_pkey_params * params ,
const void * data , void * enc )
{
params - > op = kernel_pkey_sign ;
return asymmetric_key_eds_op ( params , data , enc ) ;
}
EXPORT_SYMBOL_GPL ( create_signature ) ;
2012-09-22 02:25:04 +04:00
/**
* verify_signature - Initiate the use of an asymmetric key to verify a signature
* @ key : The asymmetric key to verify against
* @ sig : The signature to check
*
* Returns 0 if successful or else an error .
*/
int verify_signature ( const struct key * key ,
const struct public_key_signature * sig )
{
const struct asymmetric_key_subtype * subtype ;
int ret ;
pr_devel ( " ==>%s() \n " , __func__ ) ;
if ( key - > type ! = & key_type_asymmetric )
return - EINVAL ;
subtype = asymmetric_key_subtype ( key ) ;
if ( ! subtype | |
2015-10-21 16:04:48 +03:00
! key - > payload . data [ 0 ] )
2012-09-22 02:25:04 +04:00
return - EINVAL ;
if ( ! subtype - > verify_signature )
return - ENOTSUPP ;
ret = subtype - > verify_signature ( key , sig ) ;
pr_devel ( " <==%s() = %d \n " , __func__ , ret ) ;
return ret ;
}
EXPORT_SYMBOL_GPL ( verify_signature ) ;