2 * linux/drivers/s390/crypto/zcrypt_cca_key.h
6 * Copyright (C) 2001, 2006 IBM Corporation
7 * Author(s): Robert Burroughs
8 * Eric Rossman (edrossma@us.ibm.com)
10 * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com)
11 * Major cleanup & driver split: Martin Schwidefsky <schwidefsky@de.ibm.com>
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #ifndef _ZCRYPT_CCA_KEY_H_
29 #define _ZCRYPT_CCA_KEY_H_
31 struct T6_keyBlock_hdr
{
38 * mapping for the cca private ME key token.
39 * Three parts of interest here: the header, the private section and
42 * mapping for the cca key token header
44 struct cca_token_hdr
{
45 unsigned char token_identifier
;
46 unsigned char version
;
47 unsigned short token_length
;
48 unsigned char reserved
[4];
49 } __attribute__((packed
));
51 #define CCA_TKN_HDR_ID_EXT 0x1E
54 * mapping for the cca private ME section
56 struct cca_private_ext_ME_sec
{
57 unsigned char section_identifier
;
58 unsigned char version
;
59 unsigned short section_length
;
60 unsigned char private_key_hash
[20];
61 unsigned char reserved1
[4];
62 unsigned char key_format
;
63 unsigned char reserved2
;
64 unsigned char key_name_hash
[20];
65 unsigned char key_use_flags
[4];
66 unsigned char reserved3
[6];
67 unsigned char reserved4
[24];
68 unsigned char confounder
[24];
69 unsigned char exponent
[128];
70 unsigned char modulus
[128];
71 } __attribute__((packed
));
73 #define CCA_PVT_USAGE_ALL 0x80
76 * mapping for the cca public section
77 * In a private key, the modulus doesn't appear in the public
78 * section. So, an arbitrary public exponent of 0x010001 will be
79 * used, for a section length of 0x0F always.
81 struct cca_public_sec
{
82 unsigned char section_identifier
;
83 unsigned char version
;
84 unsigned short section_length
;
85 unsigned char reserved
[2];
86 unsigned short exponent_len
;
87 unsigned short modulus_bit_len
;
88 unsigned short modulus_byte_len
; /* In a private key, this is 0 */
89 } __attribute__((packed
));
92 * mapping for the cca private CRT key 'token'
93 * The first three parts (the only parts considered in this release)
94 * are: the header, the private section and the public section.
95 * The header and public section are the same as for the
96 * struct cca_private_ext_ME
98 * Following the structure are the quantities p, q, dp, dq, u, pad,
99 * and modulus, in that order, where pad_len is the modulo 8
100 * complement of the residue modulo 8 of the sum of
101 * (p_len + q_len + dp_len + dq_len + u_len).
103 struct cca_pvt_ext_CRT_sec
{
104 unsigned char section_identifier
;
105 unsigned char version
;
106 unsigned short section_length
;
107 unsigned char private_key_hash
[20];
108 unsigned char reserved1
[4];
109 unsigned char key_format
;
110 unsigned char reserved2
;
111 unsigned char key_name_hash
[20];
112 unsigned char key_use_flags
[4];
113 unsigned short p_len
;
114 unsigned short q_len
;
115 unsigned short dp_len
;
116 unsigned short dq_len
;
117 unsigned short u_len
;
118 unsigned short mod_len
;
119 unsigned char reserved3
[4];
120 unsigned short pad_len
;
121 unsigned char reserved4
[52];
122 unsigned char confounder
[8];
123 } __attribute__((packed
));
125 #define CCA_PVT_EXT_CRT_SEC_ID_PVT 0x08
126 #define CCA_PVT_EXT_CRT_SEC_FMT_CL 0x40
129 * Set up private key fields of a type6 MEX message.
130 * Note that all numerics in the key token are big-endian,
131 * while the entries in the key block header are little-endian.
133 * @mex: pointer to user input data
134 * @p: pointer to memory area for the key
136 * Returns the size of the key area or -EFAULT
138 static inline int zcrypt_type6_mex_key_de(struct ica_rsa_modexpo
*mex
,
139 void *p
, int big_endian
)
141 static struct cca_token_hdr static_pvt_me_hdr
= {
142 .token_identifier
= 0x1E,
143 .token_length
= 0x0183,
145 static struct cca_private_ext_ME_sec static_pvt_me_sec
= {
146 .section_identifier
= 0x02,
147 .section_length
= 0x016C,
148 .key_use_flags
= {0x80,0x00,0x00,0x00},
150 static struct cca_public_sec static_pub_me_sec
= {
151 .section_identifier
= 0x04,
152 .section_length
= 0x000F,
153 .exponent_len
= 0x0003,
155 static char pk_exponent
[3] = { 0x01, 0x00, 0x01 };
157 struct T6_keyBlock_hdr t6_hdr
;
158 struct cca_token_hdr pvtMeHdr
;
159 struct cca_private_ext_ME_sec pvtMeSec
;
160 struct cca_public_sec pubMeSec
;
162 } __attribute__((packed
)) *key
= p
;
165 memset(key
, 0, sizeof(*key
));
168 key
->t6_hdr
.blen
= cpu_to_be16(0x189);
169 key
->t6_hdr
.ulen
= cpu_to_be16(0x189 - 2);
171 key
->t6_hdr
.blen
= cpu_to_le16(0x189);
172 key
->t6_hdr
.ulen
= cpu_to_le16(0x189 - 2);
174 key
->pvtMeHdr
= static_pvt_me_hdr
;
175 key
->pvtMeSec
= static_pvt_me_sec
;
176 key
->pubMeSec
= static_pub_me_sec
;
178 * In a private key, the modulus doesn't appear in the public
179 * section. So, an arbitrary public exponent of 0x010001 will be
182 memcpy(key
->exponent
, pk_exponent
, 3);
184 /* key parameter block */
185 temp
= key
->pvtMeSec
.exponent
+
186 sizeof(key
->pvtMeSec
.exponent
) - mex
->inputdatalength
;
187 if (copy_from_user(temp
, mex
->b_key
, mex
->inputdatalength
))
191 temp
= key
->pvtMeSec
.modulus
+
192 sizeof(key
->pvtMeSec
.modulus
) - mex
->inputdatalength
;
193 if (copy_from_user(temp
, mex
->n_modulus
, mex
->inputdatalength
))
195 key
->pubMeSec
.modulus_bit_len
= 8 * mex
->inputdatalength
;
200 * Set up private key fields of a type6 MEX message. The _pad variant
201 * strips leading zeroes from the b_key.
202 * Note that all numerics in the key token are big-endian,
203 * while the entries in the key block header are little-endian.
205 * @mex: pointer to user input data
206 * @p: pointer to memory area for the key
208 * Returns the size of the key area or -EFAULT
210 static inline int zcrypt_type6_mex_key_en(struct ica_rsa_modexpo
*mex
,
211 void *p
, int big_endian
)
213 static struct cca_token_hdr static_pub_hdr
= {
214 .token_identifier
= 0x1E,
216 static struct cca_public_sec static_pub_sec
= {
217 .section_identifier
= 0x04,
220 struct T6_keyBlock_hdr t6_hdr
;
221 struct cca_token_hdr pubHdr
;
222 struct cca_public_sec pubSec
;
224 } __attribute__((packed
)) *key
= p
;
228 memset(key
, 0, sizeof(*key
));
230 key
->pubHdr
= static_pub_hdr
;
231 key
->pubSec
= static_pub_sec
;
233 /* key parameter block */
234 temp
= key
->exponent
;
235 if (copy_from_user(temp
, mex
->b_key
, mex
->inputdatalength
))
237 /* Strip leading zeroes from b_key. */
238 for (i
= 0; i
< mex
->inputdatalength
; i
++)
241 if (i
>= mex
->inputdatalength
)
243 memmove(temp
, temp
+ i
, mex
->inputdatalength
- i
);
244 temp
+= mex
->inputdatalength
- i
;
246 if (copy_from_user(temp
, mex
->n_modulus
, mex
->inputdatalength
))
249 key
->pubSec
.modulus_bit_len
= 8 * mex
->inputdatalength
;
250 key
->pubSec
.modulus_byte_len
= mex
->inputdatalength
;
251 key
->pubSec
.exponent_len
= mex
->inputdatalength
- i
;
252 key
->pubSec
.section_length
= sizeof(key
->pubSec
) +
253 2*mex
->inputdatalength
- i
;
254 key
->pubHdr
.token_length
=
255 key
->pubSec
.section_length
+ sizeof(key
->pubHdr
);
257 key
->t6_hdr
.ulen
= cpu_to_be16(key
->pubHdr
.token_length
+ 4);
258 key
->t6_hdr
.blen
= cpu_to_be16(key
->pubHdr
.token_length
+ 6);
260 key
->t6_hdr
.ulen
= cpu_to_le16(key
->pubHdr
.token_length
+ 4);
261 key
->t6_hdr
.blen
= cpu_to_le16(key
->pubHdr
.token_length
+ 6);
263 return sizeof(*key
) + 2*mex
->inputdatalength
- i
;
267 * Set up private key fields of a type6 CRT message.
268 * Note that all numerics in the key token are big-endian,
269 * while the entries in the key block header are little-endian.
271 * @mex: pointer to user input data
272 * @p: pointer to memory area for the key
274 * Returns the size of the key area or -EFAULT
276 static inline int zcrypt_type6_crt_key(struct ica_rsa_modexpo_crt
*crt
,
277 void *p
, int big_endian
)
279 static struct cca_public_sec static_cca_pub_sec
= {
280 .section_identifier
= 4,
281 .section_length
= 0x000f,
282 .exponent_len
= 0x0003,
284 static char pk_exponent
[3] = { 0x01, 0x00, 0x01 };
286 struct T6_keyBlock_hdr t6_hdr
;
287 struct cca_token_hdr token
;
288 struct cca_pvt_ext_CRT_sec pvt
;
290 } __attribute__((packed
)) *key
= p
;
291 struct cca_public_sec
*pub
;
292 int short_len
, long_len
, pad_len
, key_len
, size
;
294 memset(key
, 0, sizeof(*key
));
296 short_len
= crt
->inputdatalength
/ 2;
297 long_len
= short_len
+ 8;
298 pad_len
= -(3*long_len
+ 2*short_len
) & 7;
299 key_len
= 3*long_len
+ 2*short_len
+ pad_len
+ crt
->inputdatalength
;
300 size
= sizeof(*key
) + key_len
+ sizeof(*pub
) + 3;
302 /* parameter block.key block */
304 key
->t6_hdr
.blen
= cpu_to_be16(size
);
305 key
->t6_hdr
.ulen
= cpu_to_be16(size
- 2);
307 key
->t6_hdr
.blen
= cpu_to_le16(size
);
308 key
->t6_hdr
.ulen
= cpu_to_le16(size
- 2);
311 /* key token header */
312 key
->token
.token_identifier
= CCA_TKN_HDR_ID_EXT
;
313 key
->token
.token_length
= size
- 6;
315 /* private section */
316 key
->pvt
.section_identifier
= CCA_PVT_EXT_CRT_SEC_ID_PVT
;
317 key
->pvt
.section_length
= sizeof(key
->pvt
) + key_len
;
318 key
->pvt
.key_format
= CCA_PVT_EXT_CRT_SEC_FMT_CL
;
319 key
->pvt
.key_use_flags
[0] = CCA_PVT_USAGE_ALL
;
320 key
->pvt
.p_len
= key
->pvt
.dp_len
= key
->pvt
.u_len
= long_len
;
321 key
->pvt
.q_len
= key
->pvt
.dq_len
= short_len
;
322 key
->pvt
.mod_len
= crt
->inputdatalength
;
323 key
->pvt
.pad_len
= pad_len
;
326 if (copy_from_user(key
->key_parts
, crt
->np_prime
, long_len
) ||
327 copy_from_user(key
->key_parts
+ long_len
,
328 crt
->nq_prime
, short_len
) ||
329 copy_from_user(key
->key_parts
+ long_len
+ short_len
,
330 crt
->bp_key
, long_len
) ||
331 copy_from_user(key
->key_parts
+ 2*long_len
+ short_len
,
332 crt
->bq_key
, short_len
) ||
333 copy_from_user(key
->key_parts
+ 2*long_len
+ 2*short_len
,
334 crt
->u_mult_inv
, long_len
))
336 memset(key
->key_parts
+ 3*long_len
+ 2*short_len
+ pad_len
,
337 0xff, crt
->inputdatalength
);
338 pub
= (struct cca_public_sec
*)(key
->key_parts
+ key_len
);
339 *pub
= static_cca_pub_sec
;
340 pub
->modulus_bit_len
= 8 * crt
->inputdatalength
;
342 * In a private key, the modulus doesn't appear in the public
343 * section. So, an arbitrary public exponent of 0x010001 will be
346 memcpy((char *) (pub
+ 1), pk_exponent
, 3);
350 #endif /* _ZCRYPT_CCA_KEY_H_ */