1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2004 IBM Corporation
4 * Copyright (C) 2014 Intel Corporation
7 #include <linux/string.h>
10 #include <linux/tpm_command.h>
12 #include <keys/trusted-type.h>
13 #include <keys/trusted_tpm.h>
15 static struct tpm2_hash tpm2_hash_map
[] = {
16 {HASH_ALGO_SHA1
, TPM_ALG_SHA1
},
17 {HASH_ALGO_SHA256
, TPM_ALG_SHA256
},
18 {HASH_ALGO_SHA384
, TPM_ALG_SHA384
},
19 {HASH_ALGO_SHA512
, TPM_ALG_SHA512
},
20 {HASH_ALGO_SM3_256
, TPM_ALG_SM3_256
},
24 * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer.
26 * @buf: an allocated tpm_buf instance
27 * @session_handle: session handle
28 * @nonce: the session nonce, may be NULL if not used
29 * @nonce_len: the session nonce length, may be 0 if not used
30 * @attributes: the session attributes
31 * @hmac: the session HMAC or password, may be NULL if not used
32 * @hmac_len: the session HMAC or password length, maybe 0 if not used
34 static void tpm2_buf_append_auth(struct tpm_buf
*buf
, u32 session_handle
,
35 const u8
*nonce
, u16 nonce_len
,
37 const u8
*hmac
, u16 hmac_len
)
39 tpm_buf_append_u32(buf
, 9 + nonce_len
+ hmac_len
);
40 tpm_buf_append_u32(buf
, session_handle
);
41 tpm_buf_append_u16(buf
, nonce_len
);
43 if (nonce
&& nonce_len
)
44 tpm_buf_append(buf
, nonce
, nonce_len
);
46 tpm_buf_append_u8(buf
, attributes
);
47 tpm_buf_append_u16(buf
, hmac_len
);
50 tpm_buf_append(buf
, hmac
, hmac_len
);
54 * tpm2_seal_trusted() - seal the payload of a trusted key
56 * @chip: TPM chip to use
57 * @payload: the key data in clear and encrypted form
58 * @options: authentication values and other options
60 * Return: < 0 on error and 0 on success.
62 int tpm2_seal_trusted(struct tpm_chip
*chip
,
63 struct trusted_key_payload
*payload
,
64 struct trusted_key_options
*options
)
66 unsigned int blob_len
;
72 for (i
= 0; i
< ARRAY_SIZE(tpm2_hash_map
); i
++) {
73 if (options
->hash
== tpm2_hash_map
[i
].crypto_id
) {
74 hash
= tpm2_hash_map
[i
].tpm_id
;
79 if (i
== ARRAY_SIZE(tpm2_hash_map
))
82 rc
= tpm_buf_init(&buf
, TPM2_ST_SESSIONS
, TPM2_CC_CREATE
);
86 tpm_buf_append_u32(&buf
, options
->keyhandle
);
87 tpm2_buf_append_auth(&buf
, TPM2_RS_PW
,
89 0 /* session_attributes */,
90 options
->keyauth
/* hmac */,
94 tpm_buf_append_u16(&buf
, 4 + TPM_DIGEST_SIZE
+ payload
->key_len
+ 1);
96 tpm_buf_append_u16(&buf
, TPM_DIGEST_SIZE
);
97 tpm_buf_append(&buf
, options
->blobauth
, TPM_DIGEST_SIZE
);
98 tpm_buf_append_u16(&buf
, payload
->key_len
+ 1);
99 tpm_buf_append(&buf
, payload
->key
, payload
->key_len
);
100 tpm_buf_append_u8(&buf
, payload
->migratable
);
103 tpm_buf_append_u16(&buf
, 14 + options
->policydigest_len
);
104 tpm_buf_append_u16(&buf
, TPM_ALG_KEYEDHASH
);
105 tpm_buf_append_u16(&buf
, hash
);
108 if (options
->policydigest_len
) {
109 tpm_buf_append_u32(&buf
, 0);
110 tpm_buf_append_u16(&buf
, options
->policydigest_len
);
111 tpm_buf_append(&buf
, options
->policydigest
,
112 options
->policydigest_len
);
114 tpm_buf_append_u32(&buf
, TPM2_OA_USER_WITH_AUTH
);
115 tpm_buf_append_u16(&buf
, 0);
118 /* public parameters */
119 tpm_buf_append_u16(&buf
, TPM_ALG_NULL
);
120 tpm_buf_append_u16(&buf
, 0);
123 tpm_buf_append_u16(&buf
, 0);
126 tpm_buf_append_u32(&buf
, 0);
128 if (buf
.flags
& TPM_BUF_OVERFLOW
) {
133 rc
= tpm_send(chip
, buf
.data
, tpm_buf_length(&buf
));
137 blob_len
= be32_to_cpup((__be32
*) &buf
.data
[TPM_HEADER_SIZE
]);
138 if (blob_len
> MAX_BLOB_SIZE
) {
142 if (tpm_buf_length(&buf
) < TPM_HEADER_SIZE
+ 4 + blob_len
) {
147 memcpy(payload
->blob
, &buf
.data
[TPM_HEADER_SIZE
+ 4], blob_len
);
148 payload
->blob_len
= blob_len
;
151 tpm_buf_destroy(&buf
);
154 if (tpm2_rc_value(rc
) == TPM2_RC_HASH
)
164 * tpm2_load_cmd() - execute a TPM2_Load command
166 * @chip: TPM chip to use
167 * @payload: the key data in clear and encrypted form
168 * @options: authentication values and other options
169 * @blob_handle: returned blob handle
171 * Return: 0 on success.
172 * -E2BIG on wrong payload size.
173 * -EPERM on tpm error status.
174 * < 0 error from tpm_send.
176 static int tpm2_load_cmd(struct tpm_chip
*chip
,
177 struct trusted_key_payload
*payload
,
178 struct trusted_key_options
*options
,
182 unsigned int private_len
;
183 unsigned int public_len
;
184 unsigned int blob_len
;
187 private_len
= be16_to_cpup((__be16
*) &payload
->blob
[0]);
188 if (private_len
> (payload
->blob_len
- 2))
191 public_len
= be16_to_cpup((__be16
*) &payload
->blob
[2 + private_len
]);
192 blob_len
= private_len
+ public_len
+ 4;
193 if (blob_len
> payload
->blob_len
)
196 rc
= tpm_buf_init(&buf
, TPM2_ST_SESSIONS
, TPM2_CC_LOAD
);
200 tpm_buf_append_u32(&buf
, options
->keyhandle
);
201 tpm2_buf_append_auth(&buf
, TPM2_RS_PW
,
203 0 /* session_attributes */,
204 options
->keyauth
/* hmac */,
207 tpm_buf_append(&buf
, payload
->blob
, blob_len
);
209 if (buf
.flags
& TPM_BUF_OVERFLOW
) {
214 rc
= tpm_send(chip
, buf
.data
, tpm_buf_length(&buf
));
216 *blob_handle
= be32_to_cpup(
217 (__be32
*) &buf
.data
[TPM_HEADER_SIZE
]);
220 tpm_buf_destroy(&buf
);
229 * tpm2_unseal_cmd() - execute a TPM2_Unload command
231 * @chip: TPM chip to use
232 * @payload: the key data in clear and encrypted form
233 * @options: authentication values and other options
234 * @blob_handle: blob handle
236 * Return: 0 on success
237 * -EPERM on tpm error status
238 * < 0 error from tpm_send
240 static int tpm2_unseal_cmd(struct tpm_chip
*chip
,
241 struct trusted_key_payload
*payload
,
242 struct trusted_key_options
*options
,
250 rc
= tpm_buf_init(&buf
, TPM2_ST_SESSIONS
, TPM2_CC_UNSEAL
);
254 tpm_buf_append_u32(&buf
, blob_handle
);
255 tpm2_buf_append_auth(&buf
,
256 options
->policyhandle
?
257 options
->policyhandle
: TPM2_RS_PW
,
259 TPM2_SA_CONTINUE_SESSION
,
260 options
->blobauth
/* hmac */,
263 rc
= tpm_send(chip
, buf
.data
, tpm_buf_length(&buf
));
268 data_len
= be16_to_cpup(
269 (__be16
*) &buf
.data
[TPM_HEADER_SIZE
+ 4]);
270 if (data_len
< MIN_KEY_SIZE
|| data_len
> MAX_KEY_SIZE
+ 1) {
275 if (tpm_buf_length(&buf
) < TPM_HEADER_SIZE
+ 6 + data_len
) {
279 data
= &buf
.data
[TPM_HEADER_SIZE
+ 6];
281 memcpy(payload
->key
, data
, data_len
- 1);
282 payload
->key_len
= data_len
- 1;
283 payload
->migratable
= data
[data_len
- 1];
287 tpm_buf_destroy(&buf
);
292 * tpm2_unseal_trusted() - unseal the payload of a trusted key
294 * @chip: TPM chip to use
295 * @payload: the key data in clear and encrypted form
296 * @options: authentication values and other options
298 * Return: Same as with tpm_send.
300 int tpm2_unseal_trusted(struct tpm_chip
*chip
,
301 struct trusted_key_payload
*payload
,
302 struct trusted_key_options
*options
)
307 rc
= tpm2_load_cmd(chip
, payload
, options
, &blob_handle
);
311 rc
= tpm2_unseal_cmd(chip
, payload
, options
, blob_handle
);
312 tpm2_flush_context(chip
, blob_handle
);