1 /* SPDX-License-Identifier: GPL-2.0+ */
3 * Copyright IBM Corp. 2001, 2006
4 * Author(s): Robert Burroughs
5 * Eric Rossman (edrossma@us.ibm.com)
7 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
8 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
11 #ifndef _ZCRYPT_CCA_KEY_H_
12 #define _ZCRYPT_CCA_KEY_H_
14 struct T6_keyBlock_hdr
{
21 * mapping for the cca private ME key token.
22 * Three parts of interest here: the header, the private section and
25 * mapping for the cca key token header
27 struct cca_token_hdr
{
28 unsigned char token_identifier
;
29 unsigned char version
;
30 unsigned short token_length
;
31 unsigned char reserved
[4];
34 #define CCA_TKN_HDR_ID_EXT 0x1E
36 #define CCA_PVT_USAGE_ALL 0x80
39 * mapping for the cca public section
40 * In a private key, the modulus doesn't appear in the public
41 * section. So, an arbitrary public exponent of 0x010001 will be
42 * used, for a section length of 0x0F always.
44 struct cca_public_sec
{
45 unsigned char section_identifier
;
46 unsigned char version
;
47 unsigned short section_length
;
48 unsigned char reserved
[2];
49 unsigned short exponent_len
;
50 unsigned short modulus_bit_len
;
51 unsigned short modulus_byte_len
; /* In a private key, this is 0 */
55 * mapping for the cca private CRT key 'token'
56 * The first three parts (the only parts considered in this release)
57 * are: the header, the private section and the public section.
58 * The header and public section are the same as for the
59 * struct cca_private_ext_ME
61 * Following the structure are the quantities p, q, dp, dq, u, pad,
62 * and modulus, in that order, where pad_len is the modulo 8
63 * complement of the residue modulo 8 of the sum of
64 * (p_len + q_len + dp_len + dq_len + u_len).
66 struct cca_pvt_ext_CRT_sec
{
67 unsigned char section_identifier
;
68 unsigned char version
;
69 unsigned short section_length
;
70 unsigned char private_key_hash
[20];
71 unsigned char reserved1
[4];
72 unsigned char key_format
;
73 unsigned char reserved2
;
74 unsigned char key_name_hash
[20];
75 unsigned char key_use_flags
[4];
78 unsigned short dp_len
;
79 unsigned short dq_len
;
81 unsigned short mod_len
;
82 unsigned char reserved3
[4];
83 unsigned short pad_len
;
84 unsigned char reserved4
[52];
85 unsigned char confounder
[8];
88 #define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
89 #define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
92 * Set up private key fields of a type6 MEX message. The _pad variant
93 * strips leading zeroes from the b_key.
94 * Note that all numerics in the key token are big-endian,
95 * while the entries in the key block header are little-endian.
97 * @mex: pointer to user input data
98 * @p: pointer to memory area for the key
100 * Returns the size of the key area or negative errno value.
102 static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo
*mex
, void *p
)
104 static struct cca_token_hdr static_pub_hdr
= {
105 .token_identifier
= 0x1E,
107 static struct cca_public_sec static_pub_sec
= {
108 .section_identifier
= 0x04,
111 struct T6_keyBlock_hdr t6_hdr
;
112 struct cca_token_hdr pubHdr
;
113 struct cca_public_sec pubSec
;
120 * The inputdatalength was a selection criteria in the dispatching
121 * function zcrypt_rsa_modexpo(). However, do a plausibility check
122 * here to make sure the following copy_from_user() can't be utilized
123 * to compromise the system.
125 if (WARN_ON_ONCE(mex
->inputdatalength
> 512))
128 memset(key
, 0, sizeof(*key
));
130 key
->pubHdr
= static_pub_hdr
;
131 key
->pubSec
= static_pub_sec
;
133 /* key parameter block */
134 temp
= key
->exponent
;
135 if (copy_from_user(temp
, mex
->b_key
, mex
->inputdatalength
))
137 /* Strip leading zeroes from b_key. */
138 for (i
= 0; i
< mex
->inputdatalength
; i
++)
141 if (i
>= mex
->inputdatalength
)
143 memmove(temp
, temp
+ i
, mex
->inputdatalength
- i
);
144 temp
+= mex
->inputdatalength
- i
;
146 if (copy_from_user(temp
, mex
->n_modulus
, mex
->inputdatalength
))
149 key
->pubSec
.modulus_bit_len
= 8 * mex
->inputdatalength
;
150 key
->pubSec
.modulus_byte_len
= mex
->inputdatalength
;
151 key
->pubSec
.exponent_len
= mex
->inputdatalength
- i
;
152 key
->pubSec
.section_length
= sizeof(key
->pubSec
) +
153 2*mex
->inputdatalength
- i
;
154 key
->pubHdr
.token_length
=
155 key
->pubSec
.section_length
+ sizeof(key
->pubHdr
);
156 key
->t6_hdr
.ulen
= key
->pubHdr
.token_length
+ 4;
157 key
->t6_hdr
.blen
= key
->pubHdr
.token_length
+ 6;
158 return sizeof(*key
) + 2*mex
->inputdatalength
- i
;
162 * Set up private key fields of a type6 CRT message.
163 * Note that all numerics in the key token are big-endian,
164 * while the entries in the key block header are little-endian.
166 * @mex: pointer to user input data
167 * @p: pointer to memory area for the key
169 * Returns the size of the key area or -EFAULT
171 static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt
*crt
, void *p
)
173 static struct cca_public_sec static_cca_pub_sec
= {
174 .section_identifier
= 4,
175 .section_length
= 0x000f,
176 .exponent_len
= 0x0003,
178 static char pk_exponent
[3] = { 0x01, 0x00, 0x01 };
180 struct T6_keyBlock_hdr t6_hdr
;
181 struct cca_token_hdr token
;
182 struct cca_pvt_ext_CRT_sec pvt
;
185 struct cca_public_sec
*pub
;
186 int short_len
, long_len
, pad_len
, key_len
, size
;
189 * The inputdatalength was a selection criteria in the dispatching
190 * function zcrypt_rsa_crt(). However, do a plausibility check
191 * here to make sure the following copy_from_user() can't be utilized
192 * to compromise the system.
194 if (WARN_ON_ONCE(crt
->inputdatalength
> 512))
197 memset(key
, 0, sizeof(*key
));
199 short_len
= (crt
->inputdatalength
+ 1) / 2;
200 long_len
= short_len
+ 8;
201 pad_len
= -(3*long_len
+ 2*short_len
) & 7;
202 key_len
= 3*long_len
+ 2*short_len
+ pad_len
+ crt
->inputdatalength
;
203 size
= sizeof(*key
) + key_len
+ sizeof(*pub
) + 3;
205 /* parameter block.key block */
206 key
->t6_hdr
.blen
= size
;
207 key
->t6_hdr
.ulen
= size
- 2;
209 /* key token header */
210 key
->token
.token_identifier
= CCA_TKN_HDR_ID_EXT
;
211 key
->token
.token_length
= size
- 6;
213 /* private section */
214 key
->pvt
.section_identifier
= CCA_PVT_EXT_CRT_SEC_ID_PVT
;
215 key
->pvt
.section_length
= sizeof(key
->pvt
) + key_len
;
216 key
->pvt
.key_format
= CCA_PVT_EXT_CRT_SEC_FMT_CL
;
217 key
->pvt
.key_use_flags
[0] = CCA_PVT_USAGE_ALL
;
218 key
->pvt
.p_len
= key
->pvt
.dp_len
= key
->pvt
.u_len
= long_len
;
219 key
->pvt
.q_len
= key
->pvt
.dq_len
= short_len
;
220 key
->pvt
.mod_len
= crt
->inputdatalength
;
221 key
->pvt
.pad_len
= pad_len
;
224 if (copy_from_user(key
->key_parts
, crt
->np_prime
, long_len
) ||
225 copy_from_user(key
->key_parts
+ long_len
,
226 crt
->nq_prime
, short_len
) ||
227 copy_from_user(key
->key_parts
+ long_len
+ short_len
,
228 crt
->bp_key
, long_len
) ||
229 copy_from_user(key
->key_parts
+ 2*long_len
+ short_len
,
230 crt
->bq_key
, short_len
) ||
231 copy_from_user(key
->key_parts
+ 2*long_len
+ 2*short_len
,
232 crt
->u_mult_inv
, long_len
))
234 memset(key
->key_parts
+ 3*long_len
+ 2*short_len
+ pad_len
,
235 0xff, crt
->inputdatalength
);
236 pub
= (struct cca_public_sec
*)(key
->key_parts
+ key_len
);
237 *pub
= static_cca_pub_sec
;
238 pub
->modulus_bit_len
= 8 * crt
->inputdatalength
;
240 * In a private key, the modulus doesn't appear in the public
241 * section. So, an arbitrary public exponent of 0x010001 will be
244 memcpy((char *) (pub
+ 1), pk_exponent
, 3);
248 #endif /* _ZCRYPT_CCA_KEY_H_ */