2018-08-17 12:36:01 +02:00
/* SPDX-License-Identifier: GPL-2.0+ */
2006-09-20 15:58:32 +02:00
/*
2012-07-20 11:15:04 +02:00
* Copyright IBM Corp . 2001 , 2006
2006-09-20 15:58:32 +02:00
* Author ( s ) : Robert Burroughs
* Eric Rossman ( edrossma @ us . ibm . com )
*
* Hotplug & misc device support : Jochen Roehrig ( roehrig @ de . ibm . com )
* Major cleanup & driver split : Martin Schwidefsky < schwidefsky @ de . ibm . com >
*/
# ifndef _ZCRYPT_CCA_KEY_H_
# define _ZCRYPT_CCA_KEY_H_
2022-04-04 17:12:37 +02:00
struct t6_keyblock_hdr {
2006-09-20 15:58:32 +02:00
unsigned short blen ;
unsigned short ulen ;
unsigned short flags ;
} ;
/**
* mapping for the cca private ME key token .
* Three parts of interest here : the header , the private section and
* the public section .
*
* mapping for the cca key token header
*/
struct cca_token_hdr {
unsigned char token_identifier ;
unsigned char version ;
unsigned short token_length ;
unsigned char reserved [ 4 ] ;
2018-08-17 12:36:01 +02:00
} __packed ;
2006-09-20 15:58:32 +02:00
# define CCA_TKN_HDR_ID_EXT 0x1E
# define CCA_PVT_USAGE_ALL 0x80
/**
* mapping for the cca public section
* In a private key , the modulus doesn ' t appear in the public
* section . So , an arbitrary public exponent of 0x010001 will be
* used , for a section length of 0x0F always .
*/
struct cca_public_sec {
unsigned char section_identifier ;
unsigned char version ;
unsigned short section_length ;
unsigned char reserved [ 2 ] ;
unsigned short exponent_len ;
unsigned short modulus_bit_len ;
unsigned short modulus_byte_len ; /* In a private key, this is 0 */
2018-08-17 12:36:01 +02:00
} __packed ;
2006-09-20 15:58:32 +02:00
/**
* mapping for the cca private CRT key ' token '
* The first three parts ( the only parts considered in this release )
* are : the header , the private section and the public section .
* The header and public section are the same as for the
* struct cca_private_ext_ME
*
* Following the structure are the quantities p , q , dp , dq , u , pad ,
* and modulus , in that order , where pad_len is the modulo 8
* complement of the residue modulo 8 of the sum of
* ( p_len + q_len + dp_len + dq_len + u_len ) .
*/
2022-04-04 17:12:37 +02:00
struct cca_pvt_ext_crt_sec {
2006-09-20 15:58:32 +02:00
unsigned char section_identifier ;
unsigned char version ;
unsigned short section_length ;
unsigned char private_key_hash [ 20 ] ;
unsigned char reserved1 [ 4 ] ;
unsigned char key_format ;
unsigned char reserved2 ;
unsigned char key_name_hash [ 20 ] ;
unsigned char key_use_flags [ 4 ] ;
unsigned short p_len ;
unsigned short q_len ;
unsigned short dp_len ;
unsigned short dq_len ;
unsigned short u_len ;
unsigned short mod_len ;
unsigned char reserved3 [ 4 ] ;
unsigned short pad_len ;
unsigned char reserved4 [ 52 ] ;
unsigned char confounder [ 8 ] ;
2018-08-17 12:36:01 +02:00
} __packed ;
2006-09-20 15:58:32 +02:00
# define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
# define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
/**
2023-03-22 15:22:11 +01:00
* Set up private key fields of a type6 MEX message .
2006-09-20 15:58:32 +02:00
*
* @ mex : pointer to user input data
* @ p : pointer to memory area for the key
*
2018-06-27 09:50:43 +02:00
* Returns the size of the key area or negative errno value .
2006-09-20 15:58:32 +02:00
*/
2017-05-09 12:19:16 +02:00
static inline int zcrypt_type6_mex_key_en ( struct ica_rsa_modexpo * mex , void * p )
2006-09-20 15:58:32 +02:00
{
static struct cca_token_hdr static_pub_hdr = {
. token_identifier = 0x1E ,
} ;
static struct cca_public_sec static_pub_sec = {
. section_identifier = 0x04 ,
} ;
struct {
2022-04-04 17:12:37 +02:00
struct t6_keyblock_hdr t6_hdr ;
struct cca_token_hdr pubhdr ;
struct cca_public_sec pubsec ;
2023-03-22 15:22:11 +01:00
char exponent [ ] ;
2018-08-17 12:36:01 +02:00
} __packed * key = p ;
2023-03-22 15:22:11 +01:00
unsigned char * ptr ;
2006-09-20 15:58:32 +02:00
2018-06-27 09:50:43 +02:00
/*
* The inputdatalength was a selection criteria in the dispatching
* function zcrypt_rsa_modexpo ( ) . However , do a plausibility check
* here to make sure the following copy_from_user ( ) can ' t be utilized
* to compromise the system .
*/
if ( WARN_ON_ONCE ( mex - > inputdatalength > 512 ) )
return - EINVAL ;
2006-09-20 15:58:32 +02:00
memset ( key , 0 , sizeof ( * key ) ) ;
2022-04-04 17:12:37 +02:00
key - > pubhdr = static_pub_hdr ;
key - > pubsec = static_pub_sec ;
2006-09-20 15:58:32 +02:00
/* key parameter block */
2023-03-22 15:22:11 +01:00
ptr = key - > exponent ;
if ( copy_from_user ( ptr , mex - > b_key , mex - > inputdatalength ) )
2006-09-20 15:58:32 +02:00
return - EFAULT ;
2023-03-22 15:22:11 +01:00
ptr + = mex - > inputdatalength ;
2006-09-20 15:58:32 +02:00
/* modulus */
2023-03-22 15:22:11 +01:00
if ( copy_from_user ( ptr , mex - > n_modulus , mex - > inputdatalength ) )
2006-09-20 15:58:32 +02:00
return - EFAULT ;
2022-04-04 17:12:37 +02:00
key - > pubsec . modulus_bit_len = 8 * mex - > inputdatalength ;
key - > pubsec . modulus_byte_len = mex - > inputdatalength ;
2023-03-22 15:22:11 +01:00
key - > pubsec . exponent_len = mex - > inputdatalength ;
2022-04-04 17:12:37 +02:00
key - > pubsec . section_length = sizeof ( key - > pubsec ) +
2023-03-22 15:22:11 +01:00
2 * mex - > inputdatalength ;
2022-04-04 17:12:37 +02:00
key - > pubhdr . token_length =
key - > pubsec . section_length + sizeof ( key - > pubhdr ) ;
key - > t6_hdr . ulen = key - > pubhdr . token_length + 4 ;
key - > t6_hdr . blen = key - > pubhdr . token_length + 6 ;
2023-03-22 15:22:11 +01:00
return sizeof ( * key ) + 2 * mex - > inputdatalength ;
2006-09-20 15:58:32 +02:00
}
/**
* Set up private key fields of a type6 CRT message .
*
* @ mex : pointer to user input data
* @ p : pointer to memory area for the key
*
* Returns the size of the key area or - EFAULT
*/
2017-05-09 12:19:16 +02:00
static inline int zcrypt_type6_crt_key ( struct ica_rsa_modexpo_crt * crt , void * p )
2006-09-20 15:58:32 +02:00
{
static struct cca_public_sec static_cca_pub_sec = {
. section_identifier = 4 ,
. section_length = 0x000f ,
. exponent_len = 0x0003 ,
} ;
static char pk_exponent [ 3 ] = { 0x01 , 0x00 , 0x01 } ;
struct {
2022-04-04 17:12:37 +02:00
struct t6_keyblock_hdr t6_hdr ;
2006-09-20 15:58:32 +02:00
struct cca_token_hdr token ;
2022-04-04 17:12:37 +02:00
struct cca_pvt_ext_crt_sec pvt ;
2023-04-14 17:33:19 +02:00
char key_parts [ ] ;
2018-08-17 12:36:01 +02:00
} __packed * key = p ;
2006-09-20 15:58:32 +02:00
struct cca_public_sec * pub ;
int short_len , long_len , pad_len , key_len , size ;
2018-06-27 09:50:43 +02:00
/*
* The inputdatalength was a selection criteria in the dispatching
* function zcrypt_rsa_crt ( ) . However , do a plausibility check
* here to make sure the following copy_from_user ( ) can ' t be utilized
* to compromise the system .
*/
if ( WARN_ON_ONCE ( crt - > inputdatalength > 512 ) )
return - EINVAL ;
2006-09-20 15:58:32 +02:00
memset ( key , 0 , sizeof ( * key ) ) ;
2015-09-04 09:57:24 +02:00
short_len = ( crt - > inputdatalength + 1 ) / 2 ;
2006-09-20 15:58:32 +02:00
long_len = short_len + 8 ;
2022-04-04 17:12:37 +02:00
pad_len = - ( 3 * long_len + 2 * short_len ) & 7 ;
key_len = 3 * long_len + 2 * short_len + pad_len + crt - > inputdatalength ;
2006-09-20 15:58:32 +02:00
size = sizeof ( * key ) + key_len + sizeof ( * pub ) + 3 ;
/* parameter block.key block */
2017-05-09 12:19:16 +02:00
key - > t6_hdr . blen = size ;
key - > t6_hdr . ulen = size - 2 ;
2006-09-20 15:58:32 +02:00
/* key token header */
key - > token . token_identifier = CCA_TKN_HDR_ID_EXT ;
key - > token . token_length = size - 6 ;
/* private section */
key - > pvt . section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT ;
key - > pvt . section_length = sizeof ( key - > pvt ) + key_len ;
key - > pvt . key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL ;
key - > pvt . key_use_flags [ 0 ] = CCA_PVT_USAGE_ALL ;
key - > pvt . p_len = key - > pvt . dp_len = key - > pvt . u_len = long_len ;
key - > pvt . q_len = key - > pvt . dq_len = short_len ;
key - > pvt . mod_len = crt - > inputdatalength ;
key - > pvt . pad_len = pad_len ;
/* key parts */
if ( copy_from_user ( key - > key_parts , crt - > np_prime , long_len ) | |
copy_from_user ( key - > key_parts + long_len ,
2022-04-04 17:12:37 +02:00
crt - > nq_prime , short_len ) | |
2006-09-20 15:58:32 +02:00
copy_from_user ( key - > key_parts + long_len + short_len ,
2022-04-04 17:12:37 +02:00
crt - > bp_key , long_len ) | |
copy_from_user ( key - > key_parts + 2 * long_len + short_len ,
crt - > bq_key , short_len ) | |
copy_from_user ( key - > key_parts + 2 * long_len + 2 * short_len ,
crt - > u_mult_inv , long_len ) )
2006-09-20 15:58:32 +02:00
return - EFAULT ;
2022-04-04 17:12:37 +02:00
memset ( key - > key_parts + 3 * long_len + 2 * short_len + pad_len ,
2006-09-20 15:58:32 +02:00
0xff , crt - > inputdatalength ) ;
pub = ( struct cca_public_sec * ) ( key - > key_parts + key_len ) ;
* pub = static_cca_pub_sec ;
pub - > modulus_bit_len = 8 * crt - > inputdatalength ;
2008-04-17 07:46:28 +02:00
/*
2006-09-20 15:58:32 +02:00
* In a private key , the modulus doesn ' t appear in the public
* section . So , an arbitrary public exponent of 0x010001 will be
* used .
*/
2022-04-04 17:12:37 +02:00
memcpy ( ( char * ) ( pub + 1 ) , pk_exponent , 3 ) ;
2023-03-22 15:22:11 +01:00
2006-09-20 15:58:32 +02:00
return size ;
}
# endif /* _ZCRYPT_CCA_KEY_H_ */