dt-bindings: More removals of type references on common properties
[linux-2.6-microblaze.git] / security / keys / trusted-keys / trusted_tpm2.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (C) 2004 IBM Corporation
4  * Copyright (C) 2014 Intel Corporation
5  */
6
7 #include <linux/asn1_encoder.h>
8 #include <linux/oid_registry.h>
9 #include <linux/string.h>
10 #include <linux/err.h>
11 #include <linux/tpm.h>
12 #include <linux/tpm_command.h>
13
14 #include <keys/trusted-type.h>
15 #include <keys/trusted_tpm.h>
16
17 #include <asm/unaligned.h>
18
19 #include "tpm2key.asn1.h"
20
21 static struct tpm2_hash tpm2_hash_map[] = {
22         {HASH_ALGO_SHA1, TPM_ALG_SHA1},
23         {HASH_ALGO_SHA256, TPM_ALG_SHA256},
24         {HASH_ALGO_SHA384, TPM_ALG_SHA384},
25         {HASH_ALGO_SHA512, TPM_ALG_SHA512},
26         {HASH_ALGO_SM3_256, TPM_ALG_SM3_256},
27 };
28
29 static u32 tpm2key_oid[] = { 2, 23, 133, 10, 1, 5 };
30
31 static int tpm2_key_encode(struct trusted_key_payload *payload,
32                            struct trusted_key_options *options,
33                            u8 *src, u32 len)
34 {
35         const int SCRATCH_SIZE = PAGE_SIZE;
36         u8 *scratch = kmalloc(SCRATCH_SIZE, GFP_KERNEL);
37         u8 *work = scratch, *work1;
38         u8 *end_work = scratch + SCRATCH_SIZE;
39         u8 *priv, *pub;
40         u16 priv_len, pub_len;
41
42         priv_len = get_unaligned_be16(src) + 2;
43         priv = src;
44
45         src += priv_len;
46
47         pub_len = get_unaligned_be16(src) + 2;
48         pub = src;
49
50         if (!scratch)
51                 return -ENOMEM;
52
53         work = asn1_encode_oid(work, end_work, tpm2key_oid,
54                                asn1_oid_len(tpm2key_oid));
55
56         if (options->blobauth_len == 0) {
57                 unsigned char bool[3], *w = bool;
58                 /* tag 0 is emptyAuth */
59                 w = asn1_encode_boolean(w, w + sizeof(bool), true);
60                 if (WARN(IS_ERR(w), "BUG: Boolean failed to encode"))
61                         return PTR_ERR(w);
62                 work = asn1_encode_tag(work, end_work, 0, bool, w - bool);
63         }
64
65         /*
66          * Assume both octet strings will encode to a 2 byte definite length
67          *
68          * Note: For a well behaved TPM, this warning should never
69          * trigger, so if it does there's something nefarious going on
70          */
71         if (WARN(work - scratch + pub_len + priv_len + 14 > SCRATCH_SIZE,
72                  "BUG: scratch buffer is too small"))
73                 return -EINVAL;
74
75         work = asn1_encode_integer(work, end_work, options->keyhandle);
76         work = asn1_encode_octet_string(work, end_work, pub, pub_len);
77         work = asn1_encode_octet_string(work, end_work, priv, priv_len);
78
79         work1 = payload->blob;
80         work1 = asn1_encode_sequence(work1, work1 + sizeof(payload->blob),
81                                      scratch, work - scratch);
82         if (WARN(IS_ERR(work1), "BUG: ASN.1 encoder failed"))
83                 return PTR_ERR(work1);
84
85         return work1 - payload->blob;
86 }
87
88 struct tpm2_key_context {
89         u32 parent;
90         const u8 *pub;
91         u32 pub_len;
92         const u8 *priv;
93         u32 priv_len;
94 };
95
96 static int tpm2_key_decode(struct trusted_key_payload *payload,
97                            struct trusted_key_options *options,
98                            u8 **buf)
99 {
100         int ret;
101         struct tpm2_key_context ctx;
102         u8 *blob;
103
104         memset(&ctx, 0, sizeof(ctx));
105
106         ret = asn1_ber_decoder(&tpm2key_decoder, &ctx, payload->blob,
107                                payload->blob_len);
108         if (ret < 0)
109                 return ret;
110
111         if (ctx.priv_len + ctx.pub_len > MAX_BLOB_SIZE)
112                 return -EINVAL;
113
114         blob = kmalloc(ctx.priv_len + ctx.pub_len + 4, GFP_KERNEL);
115         if (!blob)
116                 return -ENOMEM;
117
118         *buf = blob;
119         options->keyhandle = ctx.parent;
120
121         memcpy(blob, ctx.priv, ctx.priv_len);
122         blob += ctx.priv_len;
123
124         memcpy(blob, ctx.pub, ctx.pub_len);
125
126         return 0;
127 }
128
129 int tpm2_key_parent(void *context, size_t hdrlen,
130                   unsigned char tag,
131                   const void *value, size_t vlen)
132 {
133         struct tpm2_key_context *ctx = context;
134         const u8 *v = value;
135         int i;
136
137         ctx->parent = 0;
138         for (i = 0; i < vlen; i++) {
139                 ctx->parent <<= 8;
140                 ctx->parent |= v[i];
141         }
142
143         return 0;
144 }
145
146 int tpm2_key_type(void *context, size_t hdrlen,
147                 unsigned char tag,
148                 const void *value, size_t vlen)
149 {
150         enum OID oid = look_up_OID(value, vlen);
151
152         if (oid != OID_TPMSealedData) {
153                 char buffer[50];
154
155                 sprint_oid(value, vlen, buffer, sizeof(buffer));
156                 pr_debug("OID is \"%s\" which is not TPMSealedData\n",
157                          buffer);
158                 return -EINVAL;
159         }
160
161         return 0;
162 }
163
164 int tpm2_key_pub(void *context, size_t hdrlen,
165                unsigned char tag,
166                const void *value, size_t vlen)
167 {
168         struct tpm2_key_context *ctx = context;
169
170         ctx->pub = value;
171         ctx->pub_len = vlen;
172
173         return 0;
174 }
175
176 int tpm2_key_priv(void *context, size_t hdrlen,
177                 unsigned char tag,
178                 const void *value, size_t vlen)
179 {
180         struct tpm2_key_context *ctx = context;
181
182         ctx->priv = value;
183         ctx->priv_len = vlen;
184
185         return 0;
186 }
187
188 /**
189  * tpm_buf_append_auth() - append TPMS_AUTH_COMMAND to the buffer.
190  *
191  * @buf: an allocated tpm_buf instance
192  * @session_handle: session handle
193  * @nonce: the session nonce, may be NULL if not used
194  * @nonce_len: the session nonce length, may be 0 if not used
195  * @attributes: the session attributes
196  * @hmac: the session HMAC or password, may be NULL if not used
197  * @hmac_len: the session HMAC or password length, maybe 0 if not used
198  */
199 static void tpm2_buf_append_auth(struct tpm_buf *buf, u32 session_handle,
200                                  const u8 *nonce, u16 nonce_len,
201                                  u8 attributes,
202                                  const u8 *hmac, u16 hmac_len)
203 {
204         tpm_buf_append_u32(buf, 9 + nonce_len + hmac_len);
205         tpm_buf_append_u32(buf, session_handle);
206         tpm_buf_append_u16(buf, nonce_len);
207
208         if (nonce && nonce_len)
209                 tpm_buf_append(buf, nonce, nonce_len);
210
211         tpm_buf_append_u8(buf, attributes);
212         tpm_buf_append_u16(buf, hmac_len);
213
214         if (hmac && hmac_len)
215                 tpm_buf_append(buf, hmac, hmac_len);
216 }
217
218 /**
219  * tpm2_seal_trusted() - seal the payload of a trusted key
220  *
221  * @chip: TPM chip to use
222  * @payload: the key data in clear and encrypted form
223  * @options: authentication values and other options
224  *
225  * Return: < 0 on error and 0 on success.
226  */
227 int tpm2_seal_trusted(struct tpm_chip *chip,
228                       struct trusted_key_payload *payload,
229                       struct trusted_key_options *options)
230 {
231         int blob_len = 0;
232         struct tpm_buf buf;
233         u32 hash;
234         u32 flags;
235         int i;
236         int rc;
237
238         for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
239                 if (options->hash == tpm2_hash_map[i].crypto_id) {
240                         hash = tpm2_hash_map[i].tpm_id;
241                         break;
242                 }
243         }
244
245         if (i == ARRAY_SIZE(tpm2_hash_map))
246                 return -EINVAL;
247
248         if (!options->keyhandle)
249                 return -EINVAL;
250
251         rc = tpm_try_get_ops(chip);
252         if (rc)
253                 return rc;
254
255         rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_CREATE);
256         if (rc) {
257                 tpm_put_ops(chip);
258                 return rc;
259         }
260
261         tpm_buf_append_u32(&buf, options->keyhandle);
262         tpm2_buf_append_auth(&buf, TPM2_RS_PW,
263                              NULL /* nonce */, 0,
264                              0 /* session_attributes */,
265                              options->keyauth /* hmac */,
266                              TPM_DIGEST_SIZE);
267
268         /* sensitive */
269         tpm_buf_append_u16(&buf, 4 + options->blobauth_len + payload->key_len);
270
271         tpm_buf_append_u16(&buf, options->blobauth_len);
272         if (options->blobauth_len)
273                 tpm_buf_append(&buf, options->blobauth, options->blobauth_len);
274
275         tpm_buf_append_u16(&buf, payload->key_len);
276         tpm_buf_append(&buf, payload->key, payload->key_len);
277
278         /* public */
279         tpm_buf_append_u16(&buf, 14 + options->policydigest_len);
280         tpm_buf_append_u16(&buf, TPM_ALG_KEYEDHASH);
281         tpm_buf_append_u16(&buf, hash);
282
283         /* key properties */
284         flags = 0;
285         flags |= options->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH;
286         flags |= payload->migratable ? (TPM2_OA_FIXED_TPM |
287                                         TPM2_OA_FIXED_PARENT) : 0;
288         tpm_buf_append_u32(&buf, flags);
289
290         /* policy */
291         tpm_buf_append_u16(&buf, options->policydigest_len);
292         if (options->policydigest_len)
293                 tpm_buf_append(&buf, options->policydigest,
294                                options->policydigest_len);
295
296         /* public parameters */
297         tpm_buf_append_u16(&buf, TPM_ALG_NULL);
298         tpm_buf_append_u16(&buf, 0);
299
300         /* outside info */
301         tpm_buf_append_u16(&buf, 0);
302
303         /* creation PCR */
304         tpm_buf_append_u32(&buf, 0);
305
306         if (buf.flags & TPM_BUF_OVERFLOW) {
307                 rc = -E2BIG;
308                 goto out;
309         }
310
311         rc = tpm_transmit_cmd(chip, &buf, 4, "sealing data");
312         if (rc)
313                 goto out;
314
315         blob_len = be32_to_cpup((__be32 *) &buf.data[TPM_HEADER_SIZE]);
316         if (blob_len > MAX_BLOB_SIZE) {
317                 rc = -E2BIG;
318                 goto out;
319         }
320         if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 4 + blob_len) {
321                 rc = -EFAULT;
322                 goto out;
323         }
324
325         blob_len = tpm2_key_encode(payload, options,
326                                    &buf.data[TPM_HEADER_SIZE + 4],
327                                    blob_len);
328
329 out:
330         tpm_buf_destroy(&buf);
331
332         if (rc > 0) {
333                 if (tpm2_rc_value(rc) == TPM2_RC_HASH)
334                         rc = -EINVAL;
335                 else
336                         rc = -EPERM;
337         }
338         if (blob_len < 0)
339                 return blob_len;
340
341         payload->blob_len = blob_len;
342
343         tpm_put_ops(chip);
344         return rc;
345 }
346
347 /**
348  * tpm2_load_cmd() - execute a TPM2_Load command
349  *
350  * @chip: TPM chip to use
351  * @payload: the key data in clear and encrypted form
352  * @options: authentication values and other options
353  * @blob_handle: returned blob handle
354  *
355  * Return: 0 on success.
356  *        -E2BIG on wrong payload size.
357  *        -EPERM on tpm error status.
358  *        < 0 error from tpm_send.
359  */
360 static int tpm2_load_cmd(struct tpm_chip *chip,
361                          struct trusted_key_payload *payload,
362                          struct trusted_key_options *options,
363                          u32 *blob_handle)
364 {
365         struct tpm_buf buf;
366         unsigned int private_len;
367         unsigned int public_len;
368         unsigned int blob_len;
369         u8 *blob, *pub;
370         int rc;
371         u32 attrs;
372
373         rc = tpm2_key_decode(payload, options, &blob);
374         if (rc) {
375                 /* old form */
376                 blob = payload->blob;
377                 payload->old_format = 1;
378         }
379
380         /* new format carries keyhandle but old format doesn't */
381         if (!options->keyhandle)
382                 return -EINVAL;
383
384         /* must be big enough for at least the two be16 size counts */
385         if (payload->blob_len < 4)
386                 return -EINVAL;
387
388         private_len = get_unaligned_be16(blob);
389
390         /* must be big enough for following public_len */
391         if (private_len + 2 + 2 > (payload->blob_len))
392                 return -E2BIG;
393
394         public_len = get_unaligned_be16(blob + 2 + private_len);
395         if (private_len + 2 + public_len + 2 > payload->blob_len)
396                 return -E2BIG;
397
398         pub = blob + 2 + private_len + 2;
399         /* key attributes are always at offset 4 */
400         attrs = get_unaligned_be32(pub + 4);
401
402         if ((attrs & (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT)) ==
403             (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT))
404                 payload->migratable = 0;
405         else
406                 payload->migratable = 1;
407
408         blob_len = private_len + public_len + 4;
409         if (blob_len > payload->blob_len)
410                 return -E2BIG;
411
412         rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD);
413         if (rc)
414                 return rc;
415
416         tpm_buf_append_u32(&buf, options->keyhandle);
417         tpm2_buf_append_auth(&buf, TPM2_RS_PW,
418                              NULL /* nonce */, 0,
419                              0 /* session_attributes */,
420                              options->keyauth /* hmac */,
421                              TPM_DIGEST_SIZE);
422
423         tpm_buf_append(&buf, blob, blob_len);
424
425         if (buf.flags & TPM_BUF_OVERFLOW) {
426                 rc = -E2BIG;
427                 goto out;
428         }
429
430         rc = tpm_transmit_cmd(chip, &buf, 4, "loading blob");
431         if (!rc)
432                 *blob_handle = be32_to_cpup(
433                         (__be32 *) &buf.data[TPM_HEADER_SIZE]);
434
435 out:
436         if (blob != payload->blob)
437                 kfree(blob);
438         tpm_buf_destroy(&buf);
439
440         if (rc > 0)
441                 rc = -EPERM;
442
443         return rc;
444 }
445
446 /**
447  * tpm2_unseal_cmd() - execute a TPM2_Unload command
448  *
449  * @chip: TPM chip to use
450  * @payload: the key data in clear and encrypted form
451  * @options: authentication values and other options
452  * @blob_handle: blob handle
453  *
454  * Return: 0 on success
455  *         -EPERM on tpm error status
456  *         < 0 error from tpm_send
457  */
458 static int tpm2_unseal_cmd(struct tpm_chip *chip,
459                            struct trusted_key_payload *payload,
460                            struct trusted_key_options *options,
461                            u32 blob_handle)
462 {
463         struct tpm_buf buf;
464         u16 data_len;
465         u8 *data;
466         int rc;
467
468         rc = tpm_buf_init(&buf, TPM2_ST_SESSIONS, TPM2_CC_UNSEAL);
469         if (rc)
470                 return rc;
471
472         tpm_buf_append_u32(&buf, blob_handle);
473         tpm2_buf_append_auth(&buf,
474                              options->policyhandle ?
475                              options->policyhandle : TPM2_RS_PW,
476                              NULL /* nonce */, 0,
477                              TPM2_SA_CONTINUE_SESSION,
478                              options->blobauth /* hmac */,
479                              options->blobauth_len);
480
481         rc = tpm_transmit_cmd(chip, &buf, 6, "unsealing");
482         if (rc > 0)
483                 rc = -EPERM;
484
485         if (!rc) {
486                 data_len = be16_to_cpup(
487                         (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]);
488                 if (data_len < MIN_KEY_SIZE ||  data_len > MAX_KEY_SIZE) {
489                         rc = -EFAULT;
490                         goto out;
491                 }
492
493                 if (tpm_buf_length(&buf) < TPM_HEADER_SIZE + 6 + data_len) {
494                         rc = -EFAULT;
495                         goto out;
496                 }
497                 data = &buf.data[TPM_HEADER_SIZE + 6];
498
499                 if (payload->old_format) {
500                         /* migratable flag is at the end of the key */
501                         memcpy(payload->key, data, data_len - 1);
502                         payload->key_len = data_len - 1;
503                         payload->migratable = data[data_len - 1];
504                 } else {
505                         /*
506                          * migratable flag already collected from key
507                          * attributes
508                          */
509                         memcpy(payload->key, data, data_len);
510                         payload->key_len = data_len;
511                 }
512         }
513
514 out:
515         tpm_buf_destroy(&buf);
516         return rc;
517 }
518
519 /**
520  * tpm2_unseal_trusted() - unseal the payload of a trusted key
521  *
522  * @chip: TPM chip to use
523  * @payload: the key data in clear and encrypted form
524  * @options: authentication values and other options
525  *
526  * Return: Same as with tpm_send.
527  */
528 int tpm2_unseal_trusted(struct tpm_chip *chip,
529                         struct trusted_key_payload *payload,
530                         struct trusted_key_options *options)
531 {
532         u32 blob_handle;
533         int rc;
534
535         rc = tpm_try_get_ops(chip);
536         if (rc)
537                 return rc;
538
539         rc = tpm2_load_cmd(chip, payload, options, &blob_handle);
540         if (rc)
541                 goto out;
542
543         rc = tpm2_unseal_cmd(chip, payload, options, blob_handle);
544         tpm2_flush_context(chip, blob_handle);
545
546 out:
547         tpm_put_ops(chip);
548
549         return rc;
550 }