Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0+ */
0002 /*
0003  *  Copyright IBM Corp. 2001, 2006
0004  *  Author(s): Robert Burroughs
0005  *         Eric Rossman (edrossma@us.ibm.com)
0006  *
0007  *  Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
0008  *  Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
0009  */
0010 
0011 #ifndef _ZCRYPT_CCA_KEY_H_
0012 #define _ZCRYPT_CCA_KEY_H_
0013 
0014 struct t6_keyblock_hdr {
0015     unsigned short blen;
0016     unsigned short ulen;
0017     unsigned short flags;
0018 };
0019 
0020 /**
0021  * mapping for the cca private ME key token.
0022  * Three parts of interest here: the header, the private section and
0023  * the public section.
0024  *
0025  * mapping for the cca key token header
0026  */
0027 struct cca_token_hdr {
0028     unsigned char  token_identifier;
0029     unsigned char  version;
0030     unsigned short token_length;
0031     unsigned char  reserved[4];
0032 } __packed;
0033 
0034 #define CCA_TKN_HDR_ID_EXT 0x1E
0035 
0036 #define CCA_PVT_USAGE_ALL 0x80
0037 
0038 /**
0039  * mapping for the cca public section
0040  * In a private key, the modulus doesn't appear in the public
0041  * section. So, an arbitrary public exponent of 0x010001 will be
0042  * used, for a section length of 0x0F always.
0043  */
0044 struct cca_public_sec {
0045     unsigned char  section_identifier;
0046     unsigned char  version;
0047     unsigned short section_length;
0048     unsigned char  reserved[2];
0049     unsigned short exponent_len;
0050     unsigned short modulus_bit_len;
0051     unsigned short modulus_byte_len;    /* In a private key, this is 0 */
0052 } __packed;
0053 
0054 /**
0055  * mapping for the cca private CRT key 'token'
0056  * The first three parts (the only parts considered in this release)
0057  * are: the header, the private section and the public section.
0058  * The header and public section are the same as for the
0059  * struct cca_private_ext_ME
0060  *
0061  * Following the structure are the quantities p, q, dp, dq, u, pad,
0062  * and modulus, in that order, where pad_len is the modulo 8
0063  * complement of the residue modulo 8 of the sum of
0064  * (p_len + q_len + dp_len + dq_len + u_len).
0065  */
0066 struct cca_pvt_ext_crt_sec {
0067     unsigned char  section_identifier;
0068     unsigned char  version;
0069     unsigned short section_length;
0070     unsigned char  private_key_hash[20];
0071     unsigned char  reserved1[4];
0072     unsigned char  key_format;
0073     unsigned char  reserved2;
0074     unsigned char  key_name_hash[20];
0075     unsigned char  key_use_flags[4];
0076     unsigned short p_len;
0077     unsigned short q_len;
0078     unsigned short dp_len;
0079     unsigned short dq_len;
0080     unsigned short u_len;
0081     unsigned short mod_len;
0082     unsigned char  reserved3[4];
0083     unsigned short pad_len;
0084     unsigned char  reserved4[52];
0085     unsigned char  confounder[8];
0086 } __packed;
0087 
0088 #define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
0089 #define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
0090 
0091 /**
0092  * Set up private key fields of a type6 MEX message. The _pad variant
0093  * strips leading zeroes from the b_key.
0094  * Note that all numerics in the key token are big-endian,
0095  * while the entries in the key block header are little-endian.
0096  *
0097  * @mex: pointer to user input data
0098  * @p: pointer to memory area for the key
0099  *
0100  * Returns the size of the key area or negative errno value.
0101  */
0102 static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo *mex, void *p)
0103 {
0104     static struct cca_token_hdr static_pub_hdr = {
0105         .token_identifier   =  0x1E,
0106     };
0107     static struct cca_public_sec static_pub_sec = {
0108         .section_identifier =  0x04,
0109     };
0110     struct {
0111         struct t6_keyblock_hdr t6_hdr;
0112         struct cca_token_hdr pubhdr;
0113         struct cca_public_sec pubsec;
0114         char exponent[0];
0115     } __packed *key = p;
0116     unsigned char *temp;
0117     int i;
0118 
0119     /*
0120      * The inputdatalength was a selection criteria in the dispatching
0121      * function zcrypt_rsa_modexpo(). However, do a plausibility check
0122      * here to make sure the following copy_from_user() can't be utilized
0123      * to compromise the system.
0124      */
0125     if (WARN_ON_ONCE(mex->inputdatalength > 512))
0126         return -EINVAL;
0127 
0128     memset(key, 0, sizeof(*key));
0129 
0130     key->pubhdr = static_pub_hdr;
0131     key->pubsec = static_pub_sec;
0132 
0133     /* key parameter block */
0134     temp = key->exponent;
0135     if (copy_from_user(temp, mex->b_key, mex->inputdatalength))
0136         return -EFAULT;
0137     /* Strip leading zeroes from b_key. */
0138     for (i = 0; i < mex->inputdatalength; i++)
0139         if (temp[i])
0140             break;
0141     if (i >= mex->inputdatalength)
0142         return -EINVAL;
0143     memmove(temp, temp + i, mex->inputdatalength - i);
0144     temp += mex->inputdatalength - i;
0145     /* modulus */
0146     if (copy_from_user(temp, mex->n_modulus, mex->inputdatalength))
0147         return -EFAULT;
0148 
0149     key->pubsec.modulus_bit_len = 8 * mex->inputdatalength;
0150     key->pubsec.modulus_byte_len = mex->inputdatalength;
0151     key->pubsec.exponent_len = mex->inputdatalength - i;
0152     key->pubsec.section_length = sizeof(key->pubsec) +
0153                     2 * mex->inputdatalength - i;
0154     key->pubhdr.token_length =
0155         key->pubsec.section_length + sizeof(key->pubhdr);
0156     key->t6_hdr.ulen = key->pubhdr.token_length + 4;
0157     key->t6_hdr.blen = key->pubhdr.token_length + 6;
0158     return sizeof(*key) + 2 * mex->inputdatalength - i;
0159 }
0160 
0161 /**
0162  * Set up private key fields of a type6 CRT message.
0163  * Note that all numerics in the key token are big-endian,
0164  * while the entries in the key block header are little-endian.
0165  *
0166  * @mex: pointer to user input data
0167  * @p: pointer to memory area for the key
0168  *
0169  * Returns the size of the key area or -EFAULT
0170  */
0171 static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt *crt, void *p)
0172 {
0173     static struct cca_public_sec static_cca_pub_sec = {
0174         .section_identifier = 4,
0175         .section_length = 0x000f,
0176         .exponent_len = 0x0003,
0177     };
0178     static char pk_exponent[3] = { 0x01, 0x00, 0x01 };
0179     struct {
0180         struct t6_keyblock_hdr t6_hdr;
0181         struct cca_token_hdr token;
0182         struct cca_pvt_ext_crt_sec pvt;
0183         char key_parts[0];
0184     } __packed *key = p;
0185     struct cca_public_sec *pub;
0186     int short_len, long_len, pad_len, key_len, size;
0187 
0188     /*
0189      * The inputdatalength was a selection criteria in the dispatching
0190      * function zcrypt_rsa_crt(). However, do a plausibility check
0191      * here to make sure the following copy_from_user() can't be utilized
0192      * to compromise the system.
0193      */
0194     if (WARN_ON_ONCE(crt->inputdatalength > 512))
0195         return -EINVAL;
0196 
0197     memset(key, 0, sizeof(*key));
0198 
0199     short_len = (crt->inputdatalength + 1) / 2;
0200     long_len = short_len + 8;
0201     pad_len = -(3 * long_len + 2 * short_len) & 7;
0202     key_len = 3 * long_len + 2 * short_len + pad_len + crt->inputdatalength;
0203     size = sizeof(*key) + key_len + sizeof(*pub) + 3;
0204 
0205     /* parameter block.key block */
0206     key->t6_hdr.blen = size;
0207     key->t6_hdr.ulen = size - 2;
0208 
0209     /* key token header */
0210     key->token.token_identifier = CCA_TKN_HDR_ID_EXT;
0211     key->token.token_length = size - 6;
0212 
0213     /* private section */
0214     key->pvt.section_identifier = CCA_PVT_EXT_CRT_SEC_ID_PVT;
0215     key->pvt.section_length = sizeof(key->pvt) + key_len;
0216     key->pvt.key_format = CCA_PVT_EXT_CRT_SEC_FMT_CL;
0217     key->pvt.key_use_flags[0] = CCA_PVT_USAGE_ALL;
0218     key->pvt.p_len = key->pvt.dp_len = key->pvt.u_len = long_len;
0219     key->pvt.q_len = key->pvt.dq_len = short_len;
0220     key->pvt.mod_len = crt->inputdatalength;
0221     key->pvt.pad_len = pad_len;
0222 
0223     /* key parts */
0224     if (copy_from_user(key->key_parts, crt->np_prime, long_len) ||
0225         copy_from_user(key->key_parts + long_len,
0226                crt->nq_prime, short_len) ||
0227         copy_from_user(key->key_parts + long_len + short_len,
0228                crt->bp_key, long_len) ||
0229         copy_from_user(key->key_parts + 2 * long_len + short_len,
0230                crt->bq_key, short_len) ||
0231         copy_from_user(key->key_parts + 2 * long_len + 2 * short_len,
0232                crt->u_mult_inv, long_len))
0233         return -EFAULT;
0234     memset(key->key_parts + 3 * long_len + 2 * short_len + pad_len,
0235            0xff, crt->inputdatalength);
0236     pub = (struct cca_public_sec *)(key->key_parts + key_len);
0237     *pub = static_cca_pub_sec;
0238     pub->modulus_bit_len = 8 * crt->inputdatalength;
0239     /*
0240      * In a private key, the modulus doesn't appear in the public
0241      * section. So, an arbitrary public exponent of 0x010001 will be
0242      * used.
0243      */
0244     memcpy((char *)(pub + 1), pk_exponent, 3);
0245     return size;
0246 }
0247 
0248 #endif /* _ZCRYPT_CCA_KEY_H_ */