2019-05-27 09:55:01 +03:00
// SPDX-License-Identifier: GPL-2.0-or-later
2015-12-05 19:09:34 +03:00
/*
* RSA padding templates .
*
* Copyright ( c ) 2015 Intel Corporation
*/
# include <crypto/algapi.h>
# include <crypto/akcipher.h>
# include <crypto/internal/akcipher.h>
2019-01-10 23:17:53 +03:00
# include <crypto/internal/rsa.h>
2015-12-05 19:09:34 +03:00
# include <linux/err.h>
# include <linux/init.h>
# include <linux/kernel.h>
# include <linux/module.h>
# include <linux/random.h>
2020-08-19 14:58:20 +03:00
# include <linux/scatterlist.h>
2015-12-05 19:09:34 +03:00
2016-03-04 00:49:26 +03:00
/*
* Hash algorithm OIDs plus ASN .1 DER wrappings [ RFC4880 sec 5.2 .2 ] .
*/
static const u8 rsa_digest_info_md5 [ ] = {
0x30 , 0x20 , 0x30 , 0x0c , 0x06 , 0x08 ,
0x2a , 0x86 , 0x48 , 0x86 , 0xf7 , 0x0d , 0x02 , 0x05 , /* OID */
0x05 , 0x00 , 0x04 , 0x10
} ;
static const u8 rsa_digest_info_sha1 [ ] = {
0x30 , 0x21 , 0x30 , 0x09 , 0x06 , 0x05 ,
0x2b , 0x0e , 0x03 , 0x02 , 0x1a ,
0x05 , 0x00 , 0x04 , 0x14
} ;
static const u8 rsa_digest_info_rmd160 [ ] = {
0x30 , 0x21 , 0x30 , 0x09 , 0x06 , 0x05 ,
0x2b , 0x24 , 0x03 , 0x02 , 0x01 ,
0x05 , 0x00 , 0x04 , 0x14
} ;
static const u8 rsa_digest_info_sha224 [ ] = {
0x30 , 0x2d , 0x30 , 0x0d , 0x06 , 0x09 ,
0x60 , 0x86 , 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x04 ,
0x05 , 0x00 , 0x04 , 0x1c
} ;
static const u8 rsa_digest_info_sha256 [ ] = {
0x30 , 0x31 , 0x30 , 0x0d , 0x06 , 0x09 ,
0x60 , 0x86 , 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x01 ,
0x05 , 0x00 , 0x04 , 0x20
} ;
static const u8 rsa_digest_info_sha384 [ ] = {
0x30 , 0x41 , 0x30 , 0x0d , 0x06 , 0x09 ,
0x60 , 0x86 , 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x02 ,
0x05 , 0x00 , 0x04 , 0x30
} ;
static const u8 rsa_digest_info_sha512 [ ] = {
0x30 , 0x51 , 0x30 , 0x0d , 0x06 , 0x09 ,
0x60 , 0x86 , 0x48 , 0x01 , 0x65 , 0x03 , 0x04 , 0x02 , 0x03 ,
0x05 , 0x00 , 0x04 , 0x40
} ;
static const struct rsa_asn1_template {
const char * name ;
const u8 * data ;
size_t size ;
} rsa_asn1_templates [ ] = {
# define _(X) { #X, rsa_digest_info_##X, sizeof(rsa_digest_info_##X) }
_ ( md5 ) ,
_ ( sha1 ) ,
_ ( rmd160 ) ,
_ ( sha256 ) ,
_ ( sha384 ) ,
_ ( sha512 ) ,
_ ( sha224 ) ,
{ NULL }
# undef _
} ;
static const struct rsa_asn1_template * rsa_lookup_asn1 ( const char * name )
{
const struct rsa_asn1_template * p ;
for ( p = rsa_asn1_templates ; p - > name ; p + + )
if ( strcmp ( name , p - > name ) = = 0 )
return p ;
return NULL ;
}
2015-12-05 19:09:34 +03:00
struct pkcs1pad_ctx {
struct crypto_akcipher * child ;
unsigned int key_size ;
} ;
2016-03-04 00:49:26 +03:00
struct pkcs1pad_inst_ctx {
struct crypto_akcipher_spawn spawn ;
2016-06-29 14:32:23 +03:00
const struct rsa_asn1_template * digest_info ;
2016-03-04 00:49:26 +03:00
} ;
2015-12-05 19:09:34 +03:00
struct pkcs1pad_request {
2016-06-29 14:32:24 +03:00
struct scatterlist in_sg [ 2 ] , out_sg [ 1 ] ;
2015-12-05 19:09:34 +03:00
uint8_t * in_buf , * out_buf ;
2016-07-15 06:39:18 +03:00
struct akcipher_request child_req ;
2015-12-05 19:09:34 +03:00
} ;
static int pkcs1pad_set_pub_key ( struct crypto_akcipher * tfm , const void * key ,
unsigned int keylen )
{
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
2016-06-29 14:32:27 +03:00
int err ;
ctx - > key_size = 0 ;
2015-12-05 19:09:34 +03:00
err = crypto_akcipher_set_pub_key ( ctx - > child , key , keylen ) ;
2016-06-29 14:32:27 +03:00
if ( err )
return err ;
2015-12-05 19:09:34 +03:00
2016-06-29 14:32:27 +03:00
/* Find out new modulus size from rsa implementation */
err = crypto_akcipher_maxsize ( ctx - > child ) ;
if ( err > PAGE_SIZE )
return - ENOTSUPP ;
2015-12-05 19:09:34 +03:00
2016-06-29 14:32:27 +03:00
ctx - > key_size = err ;
return 0 ;
2015-12-05 19:09:34 +03:00
}
static int pkcs1pad_set_priv_key ( struct crypto_akcipher * tfm , const void * key ,
unsigned int keylen )
{
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
2016-06-29 14:32:27 +03:00
int err ;
ctx - > key_size = 0 ;
2015-12-05 19:09:34 +03:00
err = crypto_akcipher_set_priv_key ( ctx - > child , key , keylen ) ;
2016-06-29 14:32:27 +03:00
if ( err )
return err ;
2015-12-05 19:09:34 +03:00
2016-06-29 14:32:27 +03:00
/* Find out new modulus size from rsa implementation */
err = crypto_akcipher_maxsize ( ctx - > child ) ;
if ( err > PAGE_SIZE )
return - ENOTSUPP ;
2015-12-05 19:09:34 +03:00
2016-06-29 14:32:27 +03:00
ctx - > key_size = err ;
return 0 ;
2015-12-05 19:09:34 +03:00
}
2017-05-25 10:18:16 +03:00
static unsigned int pkcs1pad_get_max_size ( struct crypto_akcipher * tfm )
2015-12-05 19:09:34 +03:00
{
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
/*
* The maximum destination buffer size for the encrypt / sign operations
* will be the same as for RSA , even though it ' s smaller for
* decrypt / verify .
*/
2017-05-25 10:18:16 +03:00
return ctx - > key_size ;
2015-12-05 19:09:34 +03:00
}
static void pkcs1pad_sg_set_buf ( struct scatterlist * sg , void * buf , size_t len ,
struct scatterlist * next )
{
2016-06-29 14:32:24 +03:00
int nsegs = next ? 2 : 1 ;
sg_init_table ( sg , nsegs ) ;
sg_set_buf ( sg , buf , len ) ;
2015-12-05 19:09:34 +03:00
if ( next )
sg_chain ( sg , nsegs , next ) ;
}
static int pkcs1pad_encrypt_sign_complete ( struct akcipher_request * req , int err )
{
struct crypto_akcipher * tfm = crypto_akcipher_reqtfm ( req ) ;
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct pkcs1pad_request * req_ctx = akcipher_request_ctx ( req ) ;
2016-06-29 14:32:28 +03:00
unsigned int pad_len ;
unsigned int len ;
u8 * out_buf ;
if ( err )
goto out ;
len = req_ctx - > child_req . dst_len ;
pad_len = ctx - > key_size - len ;
/* Four billion to one */
if ( likely ( ! pad_len ) )
goto out ;
2023-01-23 13:08:56 +03:00
out_buf = kzalloc ( ctx - > key_size , GFP_ATOMIC ) ;
2016-06-29 14:32:28 +03:00
err = - ENOMEM ;
if ( ! out_buf )
goto out ;
sg_copy_to_buffer ( req - > dst , sg_nents_for_len ( req - > dst , len ) ,
out_buf + pad_len , len ) ;
sg_copy_from_buffer ( req - > dst ,
sg_nents_for_len ( req - > dst , ctx - > key_size ) ,
out_buf , ctx - > key_size ) ;
2020-08-07 09:18:13 +03:00
kfree_sensitive ( out_buf ) ;
2016-06-29 14:32:28 +03:00
out :
2015-12-05 19:09:34 +03:00
req - > dst_len = ctx - > key_size ;
kfree ( req_ctx - > in_buf ) ;
return err ;
}
2023-02-08 08:58:44 +03:00
static void pkcs1pad_encrypt_sign_complete_cb ( void * data , int err )
2015-12-05 19:09:34 +03:00
{
2023-02-08 08:58:44 +03:00
struct akcipher_request * req = data ;
2015-12-05 19:09:34 +03:00
if ( err = = - EINPROGRESS )
2023-01-31 11:02:04 +03:00
goto out ;
err = pkcs1pad_encrypt_sign_complete ( req , err ) ;
2015-12-05 19:09:34 +03:00
2023-01-31 11:02:04 +03:00
out :
akcipher_request_complete ( req , err ) ;
2015-12-05 19:09:34 +03:00
}
static int pkcs1pad_encrypt ( struct akcipher_request * req )
{
struct crypto_akcipher * tfm = crypto_akcipher_reqtfm ( req ) ;
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct pkcs1pad_request * req_ctx = akcipher_request_ctx ( req ) ;
int err ;
unsigned int i , ps_end ;
if ( ! ctx - > key_size )
return - EINVAL ;
if ( req - > src_len > ctx - > key_size - 11 )
return - EOVERFLOW ;
if ( req - > dst_len < ctx - > key_size ) {
req - > dst_len = ctx - > key_size ;
return - EOVERFLOW ;
}
req_ctx - > in_buf = kmalloc ( ctx - > key_size - 1 - req - > src_len ,
2016-06-29 14:32:26 +03:00
GFP_KERNEL ) ;
2015-12-05 19:09:34 +03:00
if ( ! req_ctx - > in_buf )
return - ENOMEM ;
ps_end = ctx - > key_size - req - > src_len - 2 ;
req_ctx - > in_buf [ 0 ] = 0x02 ;
for ( i = 1 ; i < ps_end ; i + + )
2022-10-10 05:44:02 +03:00
req_ctx - > in_buf [ i ] = get_random_u32_inclusive ( 1 , 255 ) ;
2015-12-05 19:09:34 +03:00
req_ctx - > in_buf [ ps_end ] = 0x00 ;
pkcs1pad_sg_set_buf ( req_ctx - > in_sg , req_ctx - > in_buf ,
ctx - > key_size - 1 - req - > src_len , req - > src ) ;
akcipher_request_set_tfm ( & req_ctx - > child_req , ctx - > child ) ;
akcipher_request_set_callback ( & req_ctx - > child_req , req - > base . flags ,
pkcs1pad_encrypt_sign_complete_cb , req ) ;
2016-06-29 14:32:28 +03:00
/* Reuse output buffer */
akcipher_request_set_crypt ( & req_ctx - > child_req , req_ctx - > in_sg ,
req - > dst , ctx - > key_size - 1 , req - > dst_len ) ;
2015-12-05 19:09:34 +03:00
err = crypto_akcipher_encrypt ( & req_ctx - > child_req ) ;
2017-10-18 10:00:36 +03:00
if ( err ! = - EINPROGRESS & & err ! = - EBUSY )
2015-12-05 19:09:34 +03:00
return pkcs1pad_encrypt_sign_complete ( req , err ) ;
return err ;
}
static int pkcs1pad_decrypt_complete ( struct akcipher_request * req , int err )
{
struct crypto_akcipher * tfm = crypto_akcipher_reqtfm ( req ) ;
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct pkcs1pad_request * req_ctx = akcipher_request_ctx ( req ) ;
2016-09-22 12:04:57 +03:00
unsigned int dst_len ;
2015-12-05 19:09:34 +03:00
unsigned int pos ;
2016-09-22 12:04:57 +03:00
u8 * out_buf ;
2015-12-05 19:09:34 +03:00
if ( err )
goto done ;
2016-09-22 12:04:57 +03:00
err = - EINVAL ;
dst_len = req_ctx - > child_req . dst_len ;
if ( dst_len < ctx - > key_size - 1 )
2015-12-05 19:09:34 +03:00
goto done ;
2016-09-22 12:04:57 +03:00
out_buf = req_ctx - > out_buf ;
if ( dst_len = = ctx - > key_size ) {
if ( out_buf [ 0 ] ! = 0x00 )
/* Decrypted value had no leading 0 byte */
goto done ;
dst_len - - ;
out_buf + + ;
2015-12-05 19:09:34 +03:00
}
2016-09-22 12:04:57 +03:00
if ( out_buf [ 0 ] ! = 0x02 )
2015-12-05 19:09:34 +03:00
goto done ;
2016-09-22 12:04:57 +03:00
for ( pos = 1 ; pos < dst_len ; pos + + )
if ( out_buf [ pos ] = = 0x00 )
2015-12-05 19:09:34 +03:00
break ;
2016-09-22 12:04:57 +03:00
if ( pos < 9 | | pos = = dst_len )
2015-12-05 19:09:34 +03:00
goto done ;
pos + + ;
2016-09-22 12:04:57 +03:00
err = 0 ;
if ( req - > dst_len < dst_len - pos )
2015-12-05 19:09:34 +03:00
err = - EOVERFLOW ;
2016-09-22 12:04:57 +03:00
req - > dst_len = dst_len - pos ;
2015-12-05 19:09:34 +03:00
if ( ! err )
sg_copy_from_buffer ( req - > dst ,
sg_nents_for_len ( req - > dst , req - > dst_len ) ,
2016-09-22 12:04:57 +03:00
out_buf + pos , req - > dst_len ) ;
2015-12-05 19:09:34 +03:00
done :
2020-08-07 09:18:13 +03:00
kfree_sensitive ( req_ctx - > out_buf ) ;
2015-12-05 19:09:34 +03:00
return err ;
}
2023-02-08 08:58:44 +03:00
static void pkcs1pad_decrypt_complete_cb ( void * data , int err )
2015-12-05 19:09:34 +03:00
{
2023-02-08 08:58:44 +03:00
struct akcipher_request * req = data ;
2015-12-05 19:09:34 +03:00
if ( err = = - EINPROGRESS )
2023-01-31 11:02:04 +03:00
goto out ;
err = pkcs1pad_decrypt_complete ( req , err ) ;
2015-12-05 19:09:34 +03:00
2023-01-31 11:02:04 +03:00
out :
akcipher_request_complete ( req , err ) ;
2015-12-05 19:09:34 +03:00
}
static int pkcs1pad_decrypt ( struct akcipher_request * req )
{
struct crypto_akcipher * tfm = crypto_akcipher_reqtfm ( req ) ;
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct pkcs1pad_request * req_ctx = akcipher_request_ctx ( req ) ;
int err ;
if ( ! ctx - > key_size | | req - > src_len ! = ctx - > key_size )
return - EINVAL ;
2016-06-29 14:32:26 +03:00
req_ctx - > out_buf = kmalloc ( ctx - > key_size , GFP_KERNEL ) ;
2015-12-05 19:09:34 +03:00
if ( ! req_ctx - > out_buf )
return - ENOMEM ;
pkcs1pad_sg_set_buf ( req_ctx - > out_sg , req_ctx - > out_buf ,
2016-04-07 00:42:32 +03:00
ctx - > key_size , NULL ) ;
2015-12-05 19:09:34 +03:00
akcipher_request_set_tfm ( & req_ctx - > child_req , ctx - > child ) ;
akcipher_request_set_callback ( & req_ctx - > child_req , req - > base . flags ,
pkcs1pad_decrypt_complete_cb , req ) ;
2016-06-29 14:32:28 +03:00
/* Reuse input buffer, output to a new buffer */
akcipher_request_set_crypt ( & req_ctx - > child_req , req - > src ,
req_ctx - > out_sg , req - > src_len ,
ctx - > key_size ) ;
2015-12-05 19:09:34 +03:00
err = crypto_akcipher_decrypt ( & req_ctx - > child_req ) ;
2017-10-18 10:00:36 +03:00
if ( err ! = - EINPROGRESS & & err ! = - EBUSY )
2015-12-05 19:09:34 +03:00
return pkcs1pad_decrypt_complete ( req , err ) ;
return err ;
}
static int pkcs1pad_sign ( struct akcipher_request * req )
{
struct crypto_akcipher * tfm = crypto_akcipher_reqtfm ( req ) ;
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct pkcs1pad_request * req_ctx = akcipher_request_ctx ( req ) ;
2016-06-29 14:32:23 +03:00
struct akcipher_instance * inst = akcipher_alg_instance ( tfm ) ;
struct pkcs1pad_inst_ctx * ictx = akcipher_instance_ctx ( inst ) ;
const struct rsa_asn1_template * digest_info = ictx - > digest_info ;
2015-12-05 19:09:34 +03:00
int err ;
2022-01-19 03:13:06 +03:00
unsigned int ps_end , digest_info_size = 0 ;
2015-12-05 19:09:34 +03:00
if ( ! ctx - > key_size )
return - EINVAL ;
2018-10-09 19:47:53 +03:00
if ( digest_info )
2022-01-19 03:13:06 +03:00
digest_info_size = digest_info - > size ;
2016-03-04 00:49:26 +03:00
2022-01-19 03:13:06 +03:00
if ( req - > src_len + digest_info_size > ctx - > key_size - 11 )
2015-12-05 19:09:34 +03:00
return - EOVERFLOW ;
if ( req - > dst_len < ctx - > key_size ) {
req - > dst_len = ctx - > key_size ;
return - EOVERFLOW ;
}
req_ctx - > in_buf = kmalloc ( ctx - > key_size - 1 - req - > src_len ,
2016-06-29 14:32:26 +03:00
GFP_KERNEL ) ;
2015-12-05 19:09:34 +03:00
if ( ! req_ctx - > in_buf )
return - ENOMEM ;
2022-01-19 03:13:06 +03:00
ps_end = ctx - > key_size - digest_info_size - req - > src_len - 2 ;
2015-12-05 19:09:34 +03:00
req_ctx - > in_buf [ 0 ] = 0x01 ;
memset ( req_ctx - > in_buf + 1 , 0xff , ps_end - 1 ) ;
req_ctx - > in_buf [ ps_end ] = 0x00 ;
2018-10-09 19:47:53 +03:00
if ( digest_info )
memcpy ( req_ctx - > in_buf + ps_end + 1 , digest_info - > data ,
digest_info - > size ) ;
2016-03-04 00:49:26 +03:00
2015-12-05 19:09:34 +03:00
pkcs1pad_sg_set_buf ( req_ctx - > in_sg , req_ctx - > in_buf ,
ctx - > key_size - 1 - req - > src_len , req - > src ) ;
akcipher_request_set_tfm ( & req_ctx - > child_req , ctx - > child ) ;
akcipher_request_set_callback ( & req_ctx - > child_req , req - > base . flags ,
pkcs1pad_encrypt_sign_complete_cb , req ) ;
2016-06-29 14:32:28 +03:00
/* Reuse output buffer */
akcipher_request_set_crypt ( & req_ctx - > child_req , req_ctx - > in_sg ,
req - > dst , ctx - > key_size - 1 , req - > dst_len ) ;
2019-04-11 18:51:14 +03:00
err = crypto_akcipher_decrypt ( & req_ctx - > child_req ) ;
2017-10-18 10:00:36 +03:00
if ( err ! = - EINPROGRESS & & err ! = - EBUSY )
2015-12-05 19:09:34 +03:00
return pkcs1pad_encrypt_sign_complete ( req , err ) ;
return err ;
}
static int pkcs1pad_verify_complete ( struct akcipher_request * req , int err )
{
struct crypto_akcipher * tfm = crypto_akcipher_reqtfm ( req ) ;
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct pkcs1pad_request * req_ctx = akcipher_request_ctx ( req ) ;
2016-06-29 14:32:23 +03:00
struct akcipher_instance * inst = akcipher_alg_instance ( tfm ) ;
struct pkcs1pad_inst_ctx * ictx = akcipher_instance_ctx ( inst ) ;
const struct rsa_asn1_template * digest_info = ictx - > digest_info ;
2022-01-19 03:13:06 +03:00
const unsigned int sig_size = req - > src_len ;
const unsigned int digest_size = req - > dst_len ;
2016-07-03 05:46:11 +03:00
unsigned int dst_len ;
2015-12-05 19:09:34 +03:00
unsigned int pos ;
2016-07-03 05:46:11 +03:00
u8 * out_buf ;
2015-12-05 19:09:34 +03:00
if ( err )
goto done ;
2016-07-03 05:46:11 +03:00
err = - EINVAL ;
dst_len = req_ctx - > child_req . dst_len ;
if ( dst_len < ctx - > key_size - 1 )
2015-12-05 19:09:34 +03:00
goto done ;
2016-07-03 05:46:11 +03:00
out_buf = req_ctx - > out_buf ;
if ( dst_len = = ctx - > key_size ) {
if ( out_buf [ 0 ] ! = 0x00 )
/* Decrypted value had no leading 0 byte */
goto done ;
dst_len - - ;
out_buf + + ;
2015-12-05 19:09:34 +03:00
}
2016-03-04 00:49:26 +03:00
err = - EBADMSG ;
2016-07-03 05:46:11 +03:00
if ( out_buf [ 0 ] ! = 0x01 )
2015-12-05 19:09:34 +03:00
goto done ;
2016-03-04 00:49:26 +03:00
2016-07-03 05:46:11 +03:00
for ( pos = 1 ; pos < dst_len ; pos + + )
if ( out_buf [ pos ] ! = 0xff )
2015-12-05 19:09:34 +03:00
break ;
2016-03-04 00:49:26 +03:00
2016-07-03 05:46:11 +03:00
if ( pos < 9 | | pos = = dst_len | | out_buf [ pos ] ! = 0x00 )
2015-12-05 19:09:34 +03:00
goto done ;
pos + + ;
2018-10-09 19:47:53 +03:00
if ( digest_info ) {
2022-01-19 03:13:05 +03:00
if ( digest_info - > size > dst_len - pos )
goto done ;
2018-10-09 19:47:53 +03:00
if ( crypto_memneq ( out_buf + pos , digest_info - > data ,
digest_info - > size ) )
goto done ;
2016-03-04 00:49:26 +03:00
2018-10-09 19:47:53 +03:00
pos + = digest_info - > size ;
}
2016-03-04 00:49:26 +03:00
err = 0 ;
2022-01-19 03:13:06 +03:00
if ( digest_size ! = dst_len - pos ) {
crypto: akcipher - new verify API for public key algorithms
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().
This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.
Make improved .verify() call which gets hash value as input and produce
complete signature check without any output besides status.
Now for the top level verification only crypto_akcipher_verify() needs
to be called and its return value inspected.
Make sure that `digest' is in kmalloc'd memory (in place of `output`) in
{public,tpm}_key_verify_signature() as insisted by Herbert Xu, and will
be changed in the following commit.
Cc: David Howells <dhowells@redhat.com>
Cc: keyrings@vger.kernel.org
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Reviewed-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-04-11 18:51:15 +03:00
err = - EKEYREJECTED ;
req - > dst_len = dst_len - pos ;
goto done ;
}
/* Extract appended digest. */
sg_pcopy_to_buffer ( req - > src ,
2022-01-19 03:13:06 +03:00
sg_nents_for_len ( req - > src , sig_size + digest_size ) ,
crypto: akcipher - new verify API for public key algorithms
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().
This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.
Make improved .verify() call which gets hash value as input and produce
complete signature check without any output besides status.
Now for the top level verification only crypto_akcipher_verify() needs
to be called and its return value inspected.
Make sure that `digest' is in kmalloc'd memory (in place of `output`) in
{public,tpm}_key_verify_signature() as insisted by Herbert Xu, and will
be changed in the following commit.
Cc: David Howells <dhowells@redhat.com>
Cc: keyrings@vger.kernel.org
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Reviewed-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-04-11 18:51:15 +03:00
req_ctx - > out_buf + ctx - > key_size ,
2022-01-19 03:13:06 +03:00
digest_size , sig_size ) ;
crypto: akcipher - new verify API for public key algorithms
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().
This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.
Make improved .verify() call which gets hash value as input and produce
complete signature check without any output besides status.
Now for the top level verification only crypto_akcipher_verify() needs
to be called and its return value inspected.
Make sure that `digest' is in kmalloc'd memory (in place of `output`) in
{public,tpm}_key_verify_signature() as insisted by Herbert Xu, and will
be changed in the following commit.
Cc: David Howells <dhowells@redhat.com>
Cc: keyrings@vger.kernel.org
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Reviewed-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-04-11 18:51:15 +03:00
/* Do the actual verification step. */
if ( memcmp ( req_ctx - > out_buf + ctx - > key_size , out_buf + pos ,
2022-01-19 03:13:06 +03:00
digest_size ) ! = 0 )
crypto: akcipher - new verify API for public key algorithms
Previous akcipher .verify() just `decrypts' (using RSA encrypt which is
using public key) signature to uncover message hash, which was then
compared in upper level public_key_verify_signature() with the expected
hash value, which itself was never passed into verify().
This approach was incompatible with EC-DSA family of algorithms,
because, to verify a signature EC-DSA algorithm also needs a hash value
as input; then it's used (together with a signature divided into halves
`r||s') to produce a witness value, which is then compared with `r' to
determine if the signature is correct. Thus, for EC-DSA, nor
requirements of .verify() itself, nor its output expectations in
public_key_verify_signature() wasn't sufficient.
Make improved .verify() call which gets hash value as input and produce
complete signature check without any output besides status.
Now for the top level verification only crypto_akcipher_verify() needs
to be called and its return value inspected.
Make sure that `digest' is in kmalloc'd memory (in place of `output`) in
{public,tpm}_key_verify_signature() as insisted by Herbert Xu, and will
be changed in the following commit.
Cc: David Howells <dhowells@redhat.com>
Cc: keyrings@vger.kernel.org
Signed-off-by: Vitaly Chikunov <vt@altlinux.org>
Reviewed-by: Denis Kenzior <denkenz@gmail.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
2019-04-11 18:51:15 +03:00
err = - EKEYREJECTED ;
2015-12-05 19:09:34 +03:00
done :
2020-08-07 09:18:13 +03:00
kfree_sensitive ( req_ctx - > out_buf ) ;
2015-12-05 19:09:34 +03:00
return err ;
}
2023-02-08 08:58:44 +03:00
static void pkcs1pad_verify_complete_cb ( void * data , int err )
2015-12-05 19:09:34 +03:00
{
2023-02-08 08:58:44 +03:00
struct akcipher_request * req = data ;
2015-12-05 19:09:34 +03:00
if ( err = = - EINPROGRESS )
2023-01-31 11:02:04 +03:00
goto out ;
2015-12-05 19:09:34 +03:00
2023-01-31 11:02:04 +03:00
err = pkcs1pad_verify_complete ( req , err ) ;
out :
akcipher_request_complete ( req , err ) ;
2015-12-05 19:09:34 +03:00
}
/*
* The verify operation is here for completeness similar to the verification
* defined in RFC2313 section 10.2 except that block type 0 is not accepted ,
* as in RFC2437 . RFC2437 section 9.2 doesn ' t define any operation to
* retrieve the DigestInfo from a signature , instead the user is expected
* to call the sign operation to generate the expected signature and compare
* signatures instead of the message - digests .
*/
static int pkcs1pad_verify ( struct akcipher_request * req )
{
struct crypto_akcipher * tfm = crypto_akcipher_reqtfm ( req ) ;
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct pkcs1pad_request * req_ctx = akcipher_request_ctx ( req ) ;
2022-01-19 03:13:06 +03:00
const unsigned int sig_size = req - > src_len ;
const unsigned int digest_size = req - > dst_len ;
2015-12-05 19:09:34 +03:00
int err ;
2022-01-19 03:13:06 +03:00
if ( WARN_ON ( req - > dst ) | | WARN_ON ( ! digest_size ) | |
! ctx - > key_size | | sig_size ! = ctx - > key_size )
2015-12-05 19:09:34 +03:00
return - EINVAL ;
2022-01-19 03:13:06 +03:00
req_ctx - > out_buf = kmalloc ( ctx - > key_size + digest_size , GFP_KERNEL ) ;
2015-12-05 19:09:34 +03:00
if ( ! req_ctx - > out_buf )
return - ENOMEM ;
pkcs1pad_sg_set_buf ( req_ctx - > out_sg , req_ctx - > out_buf ,
2016-04-07 00:42:32 +03:00
ctx - > key_size , NULL ) ;
2015-12-05 19:09:34 +03:00
akcipher_request_set_tfm ( & req_ctx - > child_req , ctx - > child ) ;
akcipher_request_set_callback ( & req_ctx - > child_req , req - > base . flags ,
pkcs1pad_verify_complete_cb , req ) ;
2016-06-29 14:32:28 +03:00
/* Reuse input buffer, output to a new buffer */
akcipher_request_set_crypt ( & req_ctx - > child_req , req - > src ,
2022-01-19 03:13:06 +03:00
req_ctx - > out_sg , sig_size , ctx - > key_size ) ;
2016-06-29 14:32:28 +03:00
2019-04-11 18:51:14 +03:00
err = crypto_akcipher_encrypt ( & req_ctx - > child_req ) ;
2017-10-18 10:00:36 +03:00
if ( err ! = - EINPROGRESS & & err ! = - EBUSY )
2015-12-05 19:09:34 +03:00
return pkcs1pad_verify_complete ( req , err ) ;
return err ;
}
static int pkcs1pad_init_tfm ( struct crypto_akcipher * tfm )
{
struct akcipher_instance * inst = akcipher_alg_instance ( tfm ) ;
2016-03-04 00:49:26 +03:00
struct pkcs1pad_inst_ctx * ictx = akcipher_instance_ctx ( inst ) ;
2015-12-05 19:09:34 +03:00
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
struct crypto_akcipher * child_tfm ;
2016-06-29 14:32:23 +03:00
child_tfm = crypto_spawn_akcipher ( & ictx - > spawn ) ;
2015-12-05 19:09:34 +03:00
if ( IS_ERR ( child_tfm ) )
return PTR_ERR ( child_tfm ) ;
ctx - > child = child_tfm ;
2022-11-22 08:53:38 +03:00
akcipher_set_reqsize ( tfm , sizeof ( struct pkcs1pad_request ) +
crypto_akcipher_reqsize ( child_tfm ) ) ;
2015-12-05 19:09:34 +03:00
return 0 ;
}
static void pkcs1pad_exit_tfm ( struct crypto_akcipher * tfm )
{
struct pkcs1pad_ctx * ctx = akcipher_tfm_ctx ( tfm ) ;
crypto_free_akcipher ( ctx - > child ) ;
}
static void pkcs1pad_free ( struct akcipher_instance * inst )
{
2016-03-04 00:49:26 +03:00
struct pkcs1pad_inst_ctx * ctx = akcipher_instance_ctx ( inst ) ;
struct crypto_akcipher_spawn * spawn = & ctx - > spawn ;
2015-12-05 19:09:34 +03:00
crypto_drop_akcipher ( spawn ) ;
kfree ( inst ) ;
}
static int pkcs1pad_create ( struct crypto_template * tmpl , struct rtattr * * tb )
{
2020-01-03 06:58:47 +03:00
u32 mask ;
2015-12-05 19:09:34 +03:00
struct akcipher_instance * inst ;
2016-03-04 00:49:26 +03:00
struct pkcs1pad_inst_ctx * ctx ;
2015-12-05 19:09:34 +03:00
struct akcipher_alg * rsa_alg ;
2016-03-04 00:49:26 +03:00
const char * hash_name ;
2015-12-05 19:09:34 +03:00
int err ;
2020-07-10 09:20:38 +03:00
err = crypto_check_attr_type ( tb , CRYPTO_ALG_TYPE_AKCIPHER , & mask ) ;
if ( err )
return err ;
2020-01-03 06:58:47 +03:00
2016-03-04 00:49:26 +03:00
inst = kzalloc ( sizeof ( * inst ) + sizeof ( * ctx ) , GFP_KERNEL ) ;
2015-12-05 19:09:34 +03:00
if ( ! inst )
return - ENOMEM ;
2016-03-04 00:49:26 +03:00
ctx = akcipher_instance_ctx ( inst ) ;
2020-02-26 07:59:23 +03:00
err = crypto_grab_akcipher ( & ctx - > spawn , akcipher_crypto_instance ( inst ) ,
crypto_attr_alg_name ( tb [ 1 ] ) , 0 , mask ) ;
2015-12-05 19:09:34 +03:00
if ( err )
2020-02-26 07:59:23 +03:00
goto err_free_inst ;
2015-12-05 19:09:34 +03:00
2020-02-26 07:59:23 +03:00
rsa_alg = crypto_spawn_akcipher_alg ( & ctx - > spawn ) ;
2015-12-05 19:09:34 +03:00
2022-01-19 03:13:02 +03:00
if ( strcmp ( rsa_alg - > base . cra_name , " rsa " ) ! = 0 ) {
err = - EINVAL ;
goto err_free_inst ;
}
2015-12-05 19:09:34 +03:00
err = - ENAMETOOLONG ;
2020-02-26 07:59:23 +03:00
hash_name = crypto_attr_alg_name ( tb [ 2 ] ) ;
if ( IS_ERR ( hash_name ) ) {
2018-10-09 19:47:53 +03:00
if ( snprintf ( inst - > alg . base . cra_name ,
CRYPTO_MAX_ALG_NAME , " pkcs1pad(%s) " ,
rsa_alg - > base . cra_name ) > = CRYPTO_MAX_ALG_NAME )
2020-02-26 07:59:23 +03:00
goto err_free_inst ;
2018-10-09 19:47:53 +03:00
if ( snprintf ( inst - > alg . base . cra_driver_name ,
CRYPTO_MAX_ALG_NAME , " pkcs1pad(%s) " ,
rsa_alg - > base . cra_driver_name ) > =
CRYPTO_MAX_ALG_NAME )
2020-02-26 07:59:23 +03:00
goto err_free_inst ;
2018-10-09 19:47:53 +03:00
} else {
2020-02-26 07:59:23 +03:00
ctx - > digest_info = rsa_lookup_asn1 ( hash_name ) ;
if ( ! ctx - > digest_info ) {
err = - EINVAL ;
goto err_free_inst ;
}
2018-10-09 19:47:53 +03:00
if ( snprintf ( inst - > alg . base . cra_name , CRYPTO_MAX_ALG_NAME ,
" pkcs1pad(%s,%s) " , rsa_alg - > base . cra_name ,
hash_name ) > = CRYPTO_MAX_ALG_NAME )
2020-02-26 07:59:23 +03:00
goto err_free_inst ;
2018-10-09 19:47:53 +03:00
if ( snprintf ( inst - > alg . base . cra_driver_name ,
CRYPTO_MAX_ALG_NAME , " pkcs1pad(%s,%s) " ,
rsa_alg - > base . cra_driver_name ,
hash_name ) > = CRYPTO_MAX_ALG_NAME )
2020-02-26 07:59:23 +03:00
goto err_free_inst ;
2018-10-09 19:47:53 +03:00
}
2015-12-05 19:09:34 +03:00
inst - > alg . base . cra_priority = rsa_alg - > base . cra_priority ;
inst - > alg . base . cra_ctxsize = sizeof ( struct pkcs1pad_ctx ) ;
inst - > alg . init = pkcs1pad_init_tfm ;
inst - > alg . exit = pkcs1pad_exit_tfm ;
inst - > alg . encrypt = pkcs1pad_encrypt ;
inst - > alg . decrypt = pkcs1pad_decrypt ;
inst - > alg . sign = pkcs1pad_sign ;
inst - > alg . verify = pkcs1pad_verify ;
inst - > alg . set_pub_key = pkcs1pad_set_pub_key ;
inst - > alg . set_priv_key = pkcs1pad_set_priv_key ;
inst - > alg . max_size = pkcs1pad_get_max_size ;
inst - > free = pkcs1pad_free ;
err = akcipher_register_instance ( tmpl , inst ) ;
2020-02-26 07:59:23 +03:00
if ( err ) {
err_free_inst :
pkcs1pad_free ( inst ) ;
}
2015-12-05 19:09:34 +03:00
return err ;
}
struct crypto_template rsa_pkcs1pad_tmpl = {
. name = " pkcs1pad " ,
. create = pkcs1pad_create ,
. module = THIS_MODULE ,
} ;