~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/security/keys/trusted-keys/trusted_tpm1.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Copyright (C) 2010 IBM Corporation
  4  * Copyright (c) 2019-2021, Linaro Limited
  5  *
  6  * See Documentation/security/keys/trusted-encrypted.rst
  7  */
  8 
  9 #include <crypto/hash_info.h>
 10 #include <linux/init.h>
 11 #include <linux/slab.h>
 12 #include <linux/parser.h>
 13 #include <linux/string.h>
 14 #include <linux/err.h>
 15 #include <keys/trusted-type.h>
 16 #include <linux/key-type.h>
 17 #include <linux/crypto.h>
 18 #include <crypto/hash.h>
 19 #include <crypto/sha1.h>
 20 #include <linux/tpm.h>
 21 #include <linux/tpm_command.h>
 22 
 23 #include <keys/trusted_tpm.h>
 24 
 25 static const char hmac_alg[] = "hmac(sha1)";
 26 static const char hash_alg[] = "sha1";
 27 static struct tpm_chip *chip;
 28 static struct tpm_digest *digests;
 29 
 30 struct sdesc {
 31         struct shash_desc shash;
 32         char ctx[];
 33 };
 34 
 35 static struct crypto_shash *hashalg;
 36 static struct crypto_shash *hmacalg;
 37 
 38 static struct sdesc *init_sdesc(struct crypto_shash *alg)
 39 {
 40         struct sdesc *sdesc;
 41         int size;
 42 
 43         size = sizeof(struct shash_desc) + crypto_shash_descsize(alg);
 44         sdesc = kmalloc(size, GFP_KERNEL);
 45         if (!sdesc)
 46                 return ERR_PTR(-ENOMEM);
 47         sdesc->shash.tfm = alg;
 48         return sdesc;
 49 }
 50 
 51 static int TSS_sha1(const unsigned char *data, unsigned int datalen,
 52                     unsigned char *digest)
 53 {
 54         struct sdesc *sdesc;
 55         int ret;
 56 
 57         sdesc = init_sdesc(hashalg);
 58         if (IS_ERR(sdesc)) {
 59                 pr_info("can't alloc %s\n", hash_alg);
 60                 return PTR_ERR(sdesc);
 61         }
 62 
 63         ret = crypto_shash_digest(&sdesc->shash, data, datalen, digest);
 64         kfree_sensitive(sdesc);
 65         return ret;
 66 }
 67 
 68 static int TSS_rawhmac(unsigned char *digest, const unsigned char *key,
 69                        unsigned int keylen, ...)
 70 {
 71         struct sdesc *sdesc;
 72         va_list argp;
 73         unsigned int dlen;
 74         unsigned char *data;
 75         int ret;
 76 
 77         sdesc = init_sdesc(hmacalg);
 78         if (IS_ERR(sdesc)) {
 79                 pr_info("can't alloc %s\n", hmac_alg);
 80                 return PTR_ERR(sdesc);
 81         }
 82 
 83         ret = crypto_shash_setkey(hmacalg, key, keylen);
 84         if (ret < 0)
 85                 goto out;
 86         ret = crypto_shash_init(&sdesc->shash);
 87         if (ret < 0)
 88                 goto out;
 89 
 90         va_start(argp, keylen);
 91         for (;;) {
 92                 dlen = va_arg(argp, unsigned int);
 93                 if (dlen == 0)
 94                         break;
 95                 data = va_arg(argp, unsigned char *);
 96                 if (data == NULL) {
 97                         ret = -EINVAL;
 98                         break;
 99                 }
100                 ret = crypto_shash_update(&sdesc->shash, data, dlen);
101                 if (ret < 0)
102                         break;
103         }
104         va_end(argp);
105         if (!ret)
106                 ret = crypto_shash_final(&sdesc->shash, digest);
107 out:
108         kfree_sensitive(sdesc);
109         return ret;
110 }
111 
112 /*
113  * calculate authorization info fields to send to TPM
114  */
115 int TSS_authhmac(unsigned char *digest, const unsigned char *key,
116                         unsigned int keylen, unsigned char *h1,
117                         unsigned char *h2, unsigned int h3, ...)
118 {
119         unsigned char paramdigest[SHA1_DIGEST_SIZE];
120         struct sdesc *sdesc;
121         unsigned int dlen;
122         unsigned char *data;
123         unsigned char c;
124         int ret;
125         va_list argp;
126 
127         if (!chip)
128                 return -ENODEV;
129 
130         sdesc = init_sdesc(hashalg);
131         if (IS_ERR(sdesc)) {
132                 pr_info("can't alloc %s\n", hash_alg);
133                 return PTR_ERR(sdesc);
134         }
135 
136         c = !!h3;
137         ret = crypto_shash_init(&sdesc->shash);
138         if (ret < 0)
139                 goto out;
140         va_start(argp, h3);
141         for (;;) {
142                 dlen = va_arg(argp, unsigned int);
143                 if (dlen == 0)
144                         break;
145                 data = va_arg(argp, unsigned char *);
146                 if (!data) {
147                         ret = -EINVAL;
148                         break;
149                 }
150                 ret = crypto_shash_update(&sdesc->shash, data, dlen);
151                 if (ret < 0)
152                         break;
153         }
154         va_end(argp);
155         if (!ret)
156                 ret = crypto_shash_final(&sdesc->shash, paramdigest);
157         if (!ret)
158                 ret = TSS_rawhmac(digest, key, keylen, SHA1_DIGEST_SIZE,
159                                   paramdigest, TPM_NONCE_SIZE, h1,
160                                   TPM_NONCE_SIZE, h2, 1, &c, 0, 0);
161 out:
162         kfree_sensitive(sdesc);
163         return ret;
164 }
165 EXPORT_SYMBOL_GPL(TSS_authhmac);
166 
167 /*
168  * verify the AUTH1_COMMAND (Seal) result from TPM
169  */
170 int TSS_checkhmac1(unsigned char *buffer,
171                           const uint32_t command,
172                           const unsigned char *ononce,
173                           const unsigned char *key,
174                           unsigned int keylen, ...)
175 {
176         uint32_t bufsize;
177         uint16_t tag;
178         uint32_t ordinal;
179         uint32_t result;
180         unsigned char *enonce;
181         unsigned char *continueflag;
182         unsigned char *authdata;
183         unsigned char testhmac[SHA1_DIGEST_SIZE];
184         unsigned char paramdigest[SHA1_DIGEST_SIZE];
185         struct sdesc *sdesc;
186         unsigned int dlen;
187         unsigned int dpos;
188         va_list argp;
189         int ret;
190 
191         if (!chip)
192                 return -ENODEV;
193 
194         bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
195         tag = LOAD16(buffer, 0);
196         ordinal = command;
197         result = LOAD32N(buffer, TPM_RETURN_OFFSET);
198         if (tag == TPM_TAG_RSP_COMMAND)
199                 return 0;
200         if (tag != TPM_TAG_RSP_AUTH1_COMMAND)
201                 return -EINVAL;
202         authdata = buffer + bufsize - SHA1_DIGEST_SIZE;
203         continueflag = authdata - 1;
204         enonce = continueflag - TPM_NONCE_SIZE;
205 
206         sdesc = init_sdesc(hashalg);
207         if (IS_ERR(sdesc)) {
208                 pr_info("can't alloc %s\n", hash_alg);
209                 return PTR_ERR(sdesc);
210         }
211         ret = crypto_shash_init(&sdesc->shash);
212         if (ret < 0)
213                 goto out;
214         ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
215                                   sizeof result);
216         if (ret < 0)
217                 goto out;
218         ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
219                                   sizeof ordinal);
220         if (ret < 0)
221                 goto out;
222         va_start(argp, keylen);
223         for (;;) {
224                 dlen = va_arg(argp, unsigned int);
225                 if (dlen == 0)
226                         break;
227                 dpos = va_arg(argp, unsigned int);
228                 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
229                 if (ret < 0)
230                         break;
231         }
232         va_end(argp);
233         if (!ret)
234                 ret = crypto_shash_final(&sdesc->shash, paramdigest);
235         if (ret < 0)
236                 goto out;
237 
238         ret = TSS_rawhmac(testhmac, key, keylen, SHA1_DIGEST_SIZE, paramdigest,
239                           TPM_NONCE_SIZE, enonce, TPM_NONCE_SIZE, ononce,
240                           1, continueflag, 0, 0);
241         if (ret < 0)
242                 goto out;
243 
244         if (memcmp(testhmac, authdata, SHA1_DIGEST_SIZE))
245                 ret = -EINVAL;
246 out:
247         kfree_sensitive(sdesc);
248         return ret;
249 }
250 EXPORT_SYMBOL_GPL(TSS_checkhmac1);
251 
252 /*
253  * verify the AUTH2_COMMAND (unseal) result from TPM
254  */
255 static int TSS_checkhmac2(unsigned char *buffer,
256                           const uint32_t command,
257                           const unsigned char *ononce,
258                           const unsigned char *key1,
259                           unsigned int keylen1,
260                           const unsigned char *key2,
261                           unsigned int keylen2, ...)
262 {
263         uint32_t bufsize;
264         uint16_t tag;
265         uint32_t ordinal;
266         uint32_t result;
267         unsigned char *enonce1;
268         unsigned char *continueflag1;
269         unsigned char *authdata1;
270         unsigned char *enonce2;
271         unsigned char *continueflag2;
272         unsigned char *authdata2;
273         unsigned char testhmac1[SHA1_DIGEST_SIZE];
274         unsigned char testhmac2[SHA1_DIGEST_SIZE];
275         unsigned char paramdigest[SHA1_DIGEST_SIZE];
276         struct sdesc *sdesc;
277         unsigned int dlen;
278         unsigned int dpos;
279         va_list argp;
280         int ret;
281 
282         bufsize = LOAD32(buffer, TPM_SIZE_OFFSET);
283         tag = LOAD16(buffer, 0);
284         ordinal = command;
285         result = LOAD32N(buffer, TPM_RETURN_OFFSET);
286 
287         if (tag == TPM_TAG_RSP_COMMAND)
288                 return 0;
289         if (tag != TPM_TAG_RSP_AUTH2_COMMAND)
290                 return -EINVAL;
291         authdata1 = buffer + bufsize - (SHA1_DIGEST_SIZE + 1
292                         + SHA1_DIGEST_SIZE + SHA1_DIGEST_SIZE);
293         authdata2 = buffer + bufsize - (SHA1_DIGEST_SIZE);
294         continueflag1 = authdata1 - 1;
295         continueflag2 = authdata2 - 1;
296         enonce1 = continueflag1 - TPM_NONCE_SIZE;
297         enonce2 = continueflag2 - TPM_NONCE_SIZE;
298 
299         sdesc = init_sdesc(hashalg);
300         if (IS_ERR(sdesc)) {
301                 pr_info("can't alloc %s\n", hash_alg);
302                 return PTR_ERR(sdesc);
303         }
304         ret = crypto_shash_init(&sdesc->shash);
305         if (ret < 0)
306                 goto out;
307         ret = crypto_shash_update(&sdesc->shash, (const u8 *)&result,
308                                   sizeof result);
309         if (ret < 0)
310                 goto out;
311         ret = crypto_shash_update(&sdesc->shash, (const u8 *)&ordinal,
312                                   sizeof ordinal);
313         if (ret < 0)
314                 goto out;
315 
316         va_start(argp, keylen2);
317         for (;;) {
318                 dlen = va_arg(argp, unsigned int);
319                 if (dlen == 0)
320                         break;
321                 dpos = va_arg(argp, unsigned int);
322                 ret = crypto_shash_update(&sdesc->shash, buffer + dpos, dlen);
323                 if (ret < 0)
324                         break;
325         }
326         va_end(argp);
327         if (!ret)
328                 ret = crypto_shash_final(&sdesc->shash, paramdigest);
329         if (ret < 0)
330                 goto out;
331 
332         ret = TSS_rawhmac(testhmac1, key1, keylen1, SHA1_DIGEST_SIZE,
333                           paramdigest, TPM_NONCE_SIZE, enonce1,
334                           TPM_NONCE_SIZE, ononce, 1, continueflag1, 0, 0);
335         if (ret < 0)
336                 goto out;
337         if (memcmp(testhmac1, authdata1, SHA1_DIGEST_SIZE)) {
338                 ret = -EINVAL;
339                 goto out;
340         }
341         ret = TSS_rawhmac(testhmac2, key2, keylen2, SHA1_DIGEST_SIZE,
342                           paramdigest, TPM_NONCE_SIZE, enonce2,
343                           TPM_NONCE_SIZE, ononce, 1, continueflag2, 0, 0);
344         if (ret < 0)
345                 goto out;
346         if (memcmp(testhmac2, authdata2, SHA1_DIGEST_SIZE))
347                 ret = -EINVAL;
348 out:
349         kfree_sensitive(sdesc);
350         return ret;
351 }
352 
353 /*
354  * For key specific tpm requests, we will generate and send our
355  * own TPM command packets using the drivers send function.
356  */
357 int trusted_tpm_send(unsigned char *cmd, size_t buflen)
358 {
359         struct tpm_buf buf;
360         int rc;
361 
362         if (!chip)
363                 return -ENODEV;
364 
365         rc = tpm_try_get_ops(chip);
366         if (rc)
367                 return rc;
368 
369         buf.flags = 0;
370         buf.length = buflen;
371         buf.data = cmd;
372         dump_tpm_buf(cmd);
373         rc = tpm_transmit_cmd(chip, &buf, 4, "sending data");
374         dump_tpm_buf(cmd);
375 
376         if (rc > 0)
377                 /* TPM error */
378                 rc = -EPERM;
379 
380         tpm_put_ops(chip);
381         return rc;
382 }
383 EXPORT_SYMBOL_GPL(trusted_tpm_send);
384 
385 /*
386  * Lock a trusted key, by extending a selected PCR.
387  *
388  * Prevents a trusted key that is sealed to PCRs from being accessed.
389  * This uses the tpm driver's extend function.
390  */
391 static int pcrlock(const int pcrnum)
392 {
393         if (!capable(CAP_SYS_ADMIN))
394                 return -EPERM;
395 
396         return tpm_pcr_extend(chip, pcrnum, digests) ? -EINVAL : 0;
397 }
398 
399 /*
400  * Create an object specific authorisation protocol (OSAP) session
401  */
402 static int osap(struct tpm_buf *tb, struct osapsess *s,
403                 const unsigned char *key, uint16_t type, uint32_t handle)
404 {
405         unsigned char enonce[TPM_NONCE_SIZE];
406         unsigned char ononce[TPM_NONCE_SIZE];
407         int ret;
408 
409         ret = tpm_get_random(chip, ononce, TPM_NONCE_SIZE);
410         if (ret < 0)
411                 return ret;
412 
413         if (ret != TPM_NONCE_SIZE)
414                 return -EIO;
415 
416         tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OSAP);
417         tpm_buf_append_u16(tb, type);
418         tpm_buf_append_u32(tb, handle);
419         tpm_buf_append(tb, ononce, TPM_NONCE_SIZE);
420 
421         ret = trusted_tpm_send(tb->data, tb->length);
422         if (ret < 0)
423                 return ret;
424 
425         s->handle = LOAD32(tb->data, TPM_DATA_OFFSET);
426         memcpy(s->enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)]),
427                TPM_NONCE_SIZE);
428         memcpy(enonce, &(tb->data[TPM_DATA_OFFSET + sizeof(uint32_t) +
429                                   TPM_NONCE_SIZE]), TPM_NONCE_SIZE);
430         return TSS_rawhmac(s->secret, key, SHA1_DIGEST_SIZE, TPM_NONCE_SIZE,
431                            enonce, TPM_NONCE_SIZE, ononce, 0, 0);
432 }
433 
434 /*
435  * Create an object independent authorisation protocol (oiap) session
436  */
437 int oiap(struct tpm_buf *tb, uint32_t *handle, unsigned char *nonce)
438 {
439         int ret;
440 
441         if (!chip)
442                 return -ENODEV;
443 
444         tpm_buf_reset(tb, TPM_TAG_RQU_COMMAND, TPM_ORD_OIAP);
445         ret = trusted_tpm_send(tb->data, tb->length);
446         if (ret < 0)
447                 return ret;
448 
449         *handle = LOAD32(tb->data, TPM_DATA_OFFSET);
450         memcpy(nonce, &tb->data[TPM_DATA_OFFSET + sizeof(uint32_t)],
451                TPM_NONCE_SIZE);
452         return 0;
453 }
454 EXPORT_SYMBOL_GPL(oiap);
455 
456 struct tpm_digests {
457         unsigned char encauth[SHA1_DIGEST_SIZE];
458         unsigned char pubauth[SHA1_DIGEST_SIZE];
459         unsigned char xorwork[SHA1_DIGEST_SIZE * 2];
460         unsigned char xorhash[SHA1_DIGEST_SIZE];
461         unsigned char nonceodd[TPM_NONCE_SIZE];
462 };
463 
464 /*
465  * Have the TPM seal(encrypt) the trusted key, possibly based on
466  * Platform Configuration Registers (PCRs). AUTH1 for sealing key.
467  */
468 static int tpm_seal(struct tpm_buf *tb, uint16_t keytype,
469                     uint32_t keyhandle, const unsigned char *keyauth,
470                     const unsigned char *data, uint32_t datalen,
471                     unsigned char *blob, uint32_t *bloblen,
472                     const unsigned char *blobauth,
473                     const unsigned char *pcrinfo, uint32_t pcrinfosize)
474 {
475         struct osapsess sess;
476         struct tpm_digests *td;
477         unsigned char cont;
478         uint32_t ordinal;
479         uint32_t pcrsize;
480         uint32_t datsize;
481         int sealinfosize;
482         int encdatasize;
483         int storedsize;
484         int ret;
485         int i;
486 
487         /* alloc some work space for all the hashes */
488         td = kmalloc(sizeof *td, GFP_KERNEL);
489         if (!td)
490                 return -ENOMEM;
491 
492         /* get session for sealing key */
493         ret = osap(tb, &sess, keyauth, keytype, keyhandle);
494         if (ret < 0)
495                 goto out;
496         dump_sess(&sess);
497 
498         /* calculate encrypted authorization value */
499         memcpy(td->xorwork, sess.secret, SHA1_DIGEST_SIZE);
500         memcpy(td->xorwork + SHA1_DIGEST_SIZE, sess.enonce, SHA1_DIGEST_SIZE);
501         ret = TSS_sha1(td->xorwork, SHA1_DIGEST_SIZE * 2, td->xorhash);
502         if (ret < 0)
503                 goto out;
504 
505         ret = tpm_get_random(chip, td->nonceodd, TPM_NONCE_SIZE);
506         if (ret < 0)
507                 goto out;
508 
509         if (ret != TPM_NONCE_SIZE) {
510                 ret = -EIO;
511                 goto out;
512         }
513 
514         ordinal = htonl(TPM_ORD_SEAL);
515         datsize = htonl(datalen);
516         pcrsize = htonl(pcrinfosize);
517         cont = 0;
518 
519         /* encrypt data authorization key */
520         for (i = 0; i < SHA1_DIGEST_SIZE; ++i)
521                 td->encauth[i] = td->xorhash[i] ^ blobauth[i];
522 
523         /* calculate authorization HMAC value */
524         if (pcrinfosize == 0) {
525                 /* no pcr info specified */
526                 ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
527                                    sess.enonce, td->nonceodd, cont,
528                                    sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
529                                    td->encauth, sizeof(uint32_t), &pcrsize,
530                                    sizeof(uint32_t), &datsize, datalen, data, 0,
531                                    0);
532         } else {
533                 /* pcr info specified */
534                 ret = TSS_authhmac(td->pubauth, sess.secret, SHA1_DIGEST_SIZE,
535                                    sess.enonce, td->nonceodd, cont,
536                                    sizeof(uint32_t), &ordinal, SHA1_DIGEST_SIZE,
537                                    td->encauth, sizeof(uint32_t), &pcrsize,
538                                    pcrinfosize, pcrinfo, sizeof(uint32_t),
539                                    &datsize, datalen, data, 0, 0);
540         }
541         if (ret < 0)
542                 goto out;
543 
544         /* build and send the TPM request packet */
545         tpm_buf_reset(tb, TPM_TAG_RQU_AUTH1_COMMAND, TPM_ORD_SEAL);
546         tpm_buf_append_u32(tb, keyhandle);
547         tpm_buf_append(tb, td->encauth, SHA1_DIGEST_SIZE);
548         tpm_buf_append_u32(tb, pcrinfosize);
549         tpm_buf_append(tb, pcrinfo, pcrinfosize);
550         tpm_buf_append_u32(tb, datalen);
551         tpm_buf_append(tb, data, datalen);
552         tpm_buf_append_u32(tb, sess.handle);
553         tpm_buf_append(tb, td->nonceodd, TPM_NONCE_SIZE);
554         tpm_buf_append_u8(tb, cont);
555         tpm_buf_append(tb, td->pubauth, SHA1_DIGEST_SIZE);
556 
557         ret = trusted_tpm_send(tb->data, tb->length);
558         if (ret < 0)
559                 goto out;
560 
561         /* calculate the size of the returned Blob */
562         sealinfosize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t));
563         encdatasize = LOAD32(tb->data, TPM_DATA_OFFSET + sizeof(uint32_t) +
564                              sizeof(uint32_t) + sealinfosize);
565         storedsize = sizeof(uint32_t) + sizeof(uint32_t) + sealinfosize +
566             sizeof(uint32_t) + encdatasize;
567 
568         /* check the HMAC in the response */
569         ret = TSS_checkhmac1(tb->data, ordinal, td->nonceodd, sess.secret,
570                              SHA1_DIGEST_SIZE, storedsize, TPM_DATA_OFFSET, 0,
571                              0);
572 
573         /* copy the returned blob to caller */
574         if (!ret) {
575                 memcpy(blob, tb->data + TPM_DATA_OFFSET, storedsize);
576                 *bloblen = storedsize;
577         }
578 out:
579         kfree_sensitive(td);
580         return ret;
581 }
582 
583 /*
584  * use the AUTH2_COMMAND form of unseal, to authorize both key and blob
585  */
586 static int tpm_unseal(struct tpm_buf *tb,
587                       uint32_t keyhandle, const unsigned char *keyauth,
588                       const unsigned char *blob, int bloblen,
589                       const unsigned char *blobauth,
590                       unsigned char *data, unsigned int *datalen)
591 {
592         unsigned char nonceodd[TPM_NONCE_SIZE];
593         unsigned char enonce1[TPM_NONCE_SIZE];
594         unsigned char enonce2[TPM_NONCE_SIZE];
595         unsigned char authdata1[SHA1_DIGEST_SIZE];
596         unsigned char authdata2[SHA1_DIGEST_SIZE];
597         uint32_t authhandle1 = 0;
598         uint32_t authhandle2 = 0;
599         unsigned char cont = 0;
600         uint32_t ordinal;
601         int ret;
602 
603         /* sessions for unsealing key and data */
604         ret = oiap(tb, &authhandle1, enonce1);
605         if (ret < 0) {
606                 pr_info("oiap failed (%d)\n", ret);
607                 return ret;
608         }
609         ret = oiap(tb, &authhandle2, enonce2);
610         if (ret < 0) {
611                 pr_info("oiap failed (%d)\n", ret);
612                 return ret;
613         }
614 
615         ordinal = htonl(TPM_ORD_UNSEAL);
616         ret = tpm_get_random(chip, nonceodd, TPM_NONCE_SIZE);
617         if (ret < 0)
618                 return ret;
619 
620         if (ret != TPM_NONCE_SIZE) {
621                 pr_info("tpm_get_random failed (%d)\n", ret);
622                 return -EIO;
623         }
624         ret = TSS_authhmac(authdata1, keyauth, TPM_NONCE_SIZE,
625                            enonce1, nonceodd, cont, sizeof(uint32_t),
626                            &ordinal, bloblen, blob, 0, 0);
627         if (ret < 0)
628                 return ret;
629         ret = TSS_authhmac(authdata2, blobauth, TPM_NONCE_SIZE,
630                            enonce2, nonceodd, cont, sizeof(uint32_t),
631                            &ordinal, bloblen, blob, 0, 0);
632         if (ret < 0)
633                 return ret;
634 
635         /* build and send TPM request packet */
636         tpm_buf_reset(tb, TPM_TAG_RQU_AUTH2_COMMAND, TPM_ORD_UNSEAL);
637         tpm_buf_append_u32(tb, keyhandle);
638         tpm_buf_append(tb, blob, bloblen);
639         tpm_buf_append_u32(tb, authhandle1);
640         tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
641         tpm_buf_append_u8(tb, cont);
642         tpm_buf_append(tb, authdata1, SHA1_DIGEST_SIZE);
643         tpm_buf_append_u32(tb, authhandle2);
644         tpm_buf_append(tb, nonceodd, TPM_NONCE_SIZE);
645         tpm_buf_append_u8(tb, cont);
646         tpm_buf_append(tb, authdata2, SHA1_DIGEST_SIZE);
647 
648         ret = trusted_tpm_send(tb->data, tb->length);
649         if (ret < 0) {
650                 pr_info("authhmac failed (%d)\n", ret);
651                 return ret;
652         }
653 
654         *datalen = LOAD32(tb->data, TPM_DATA_OFFSET);
655         ret = TSS_checkhmac2(tb->data, ordinal, nonceodd,
656                              keyauth, SHA1_DIGEST_SIZE,
657                              blobauth, SHA1_DIGEST_SIZE,
658                              sizeof(uint32_t), TPM_DATA_OFFSET,
659                              *datalen, TPM_DATA_OFFSET + sizeof(uint32_t), 0,
660                              0);
661         if (ret < 0) {
662                 pr_info("TSS_checkhmac2 failed (%d)\n", ret);
663                 return ret;
664         }
665         memcpy(data, tb->data + TPM_DATA_OFFSET + sizeof(uint32_t), *datalen);
666         return 0;
667 }
668 
669 /*
670  * Have the TPM seal(encrypt) the symmetric key
671  */
672 static int key_seal(struct trusted_key_payload *p,
673                     struct trusted_key_options *o)
674 {
675         struct tpm_buf tb;
676         int ret;
677 
678         ret = tpm_buf_init(&tb, 0, 0);
679         if (ret)
680                 return ret;
681 
682         /* include migratable flag at end of sealed key */
683         p->key[p->key_len] = p->migratable;
684 
685         ret = tpm_seal(&tb, o->keytype, o->keyhandle, o->keyauth,
686                        p->key, p->key_len + 1, p->blob, &p->blob_len,
687                        o->blobauth, o->pcrinfo, o->pcrinfo_len);
688         if (ret < 0)
689                 pr_info("srkseal failed (%d)\n", ret);
690 
691         tpm_buf_destroy(&tb);
692         return ret;
693 }
694 
695 /*
696  * Have the TPM unseal(decrypt) the symmetric key
697  */
698 static int key_unseal(struct trusted_key_payload *p,
699                       struct trusted_key_options *o)
700 {
701         struct tpm_buf tb;
702         int ret;
703 
704         ret = tpm_buf_init(&tb, 0, 0);
705         if (ret)
706                 return ret;
707 
708         ret = tpm_unseal(&tb, o->keyhandle, o->keyauth, p->blob, p->blob_len,
709                          o->blobauth, p->key, &p->key_len);
710         if (ret < 0)
711                 pr_info("srkunseal failed (%d)\n", ret);
712         else
713                 /* pull migratable flag out of sealed key */
714                 p->migratable = p->key[--p->key_len];
715 
716         tpm_buf_destroy(&tb);
717         return ret;
718 }
719 
720 enum {
721         Opt_err,
722         Opt_keyhandle, Opt_keyauth, Opt_blobauth,
723         Opt_pcrinfo, Opt_pcrlock, Opt_migratable,
724         Opt_hash,
725         Opt_policydigest,
726         Opt_policyhandle,
727 };
728 
729 static const match_table_t key_tokens = {
730         {Opt_keyhandle, "keyhandle=%s"},
731         {Opt_keyauth, "keyauth=%s"},
732         {Opt_blobauth, "blobauth=%s"},
733         {Opt_pcrinfo, "pcrinfo=%s"},
734         {Opt_pcrlock, "pcrlock=%s"},
735         {Opt_migratable, "migratable=%s"},
736         {Opt_hash, "hash=%s"},
737         {Opt_policydigest, "policydigest=%s"},
738         {Opt_policyhandle, "policyhandle=%s"},
739         {Opt_err, NULL}
740 };
741 
742 /* can have zero or more token= options */
743 static int getoptions(char *c, struct trusted_key_payload *pay,
744                       struct trusted_key_options *opt)
745 {
746         substring_t args[MAX_OPT_ARGS];
747         char *p = c;
748         int token;
749         int res;
750         unsigned long handle;
751         unsigned long lock;
752         unsigned long token_mask = 0;
753         unsigned int digest_len;
754         int i;
755         int tpm2;
756 
757         tpm2 = tpm_is_tpm2(chip);
758         if (tpm2 < 0)
759                 return tpm2;
760 
761         opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1;
762 
763         if (!c)
764                 return 0;
765 
766         while ((p = strsep(&c, " \t"))) {
767                 if (*p == '\0' || *p == ' ' || *p == '\t')
768                         continue;
769                 token = match_token(p, key_tokens, args);
770                 if (test_and_set_bit(token, &token_mask))
771                         return -EINVAL;
772 
773                 switch (token) {
774                 case Opt_pcrinfo:
775                         opt->pcrinfo_len = strlen(args[0].from) / 2;
776                         if (opt->pcrinfo_len > MAX_PCRINFO_SIZE)
777                                 return -EINVAL;
778                         res = hex2bin(opt->pcrinfo, args[0].from,
779                                       opt->pcrinfo_len);
780                         if (res < 0)
781                                 return -EINVAL;
782                         break;
783                 case Opt_keyhandle:
784                         res = kstrtoul(args[0].from, 16, &handle);
785                         if (res < 0)
786                                 return -EINVAL;
787                         opt->keytype = SEAL_keytype;
788                         opt->keyhandle = handle;
789                         break;
790                 case Opt_keyauth:
791                         if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE)
792                                 return -EINVAL;
793                         res = hex2bin(opt->keyauth, args[0].from,
794                                       SHA1_DIGEST_SIZE);
795                         if (res < 0)
796                                 return -EINVAL;
797                         break;
798                 case Opt_blobauth:
799                         /*
800                          * TPM 1.2 authorizations are sha1 hashes passed in as
801                          * hex strings.  TPM 2.0 authorizations are simple
802                          * passwords (although it can take a hash as well)
803                          */
804                         opt->blobauth_len = strlen(args[0].from);
805 
806                         if (opt->blobauth_len == 2 * TPM_DIGEST_SIZE) {
807                                 res = hex2bin(opt->blobauth, args[0].from,
808                                               TPM_DIGEST_SIZE);
809                                 if (res < 0)
810                                         return -EINVAL;
811 
812                                 opt->blobauth_len = TPM_DIGEST_SIZE;
813                                 break;
814                         }
815 
816                         if (tpm2 && opt->blobauth_len <= sizeof(opt->blobauth)) {
817                                 memcpy(opt->blobauth, args[0].from,
818                                        opt->blobauth_len);
819                                 break;
820                         }
821 
822                         return -EINVAL;
823 
824                         break;
825 
826                 case Opt_migratable:
827                         if (*args[0].from == '')
828                                 pay->migratable = 0;
829                         else if (*args[0].from != '1')
830                                 return -EINVAL;
831                         break;
832                 case Opt_pcrlock:
833                         res = kstrtoul(args[0].from, 10, &lock);
834                         if (res < 0)
835                                 return -EINVAL;
836                         opt->pcrlock = lock;
837                         break;
838                 case Opt_hash:
839                         if (test_bit(Opt_policydigest, &token_mask))
840                                 return -EINVAL;
841                         for (i = 0; i < HASH_ALGO__LAST; i++) {
842                                 if (!strcmp(args[0].from, hash_algo_name[i])) {
843                                         opt->hash = i;
844                                         break;
845                                 }
846                         }
847                         if (i == HASH_ALGO__LAST)
848                                 return -EINVAL;
849                         if  (!tpm2 && i != HASH_ALGO_SHA1) {
850                                 pr_info("TPM 1.x only supports SHA-1.\n");
851                                 return -EINVAL;
852                         }
853                         break;
854                 case Opt_policydigest:
855                         digest_len = hash_digest_size[opt->hash];
856                         if (!tpm2 || strlen(args[0].from) != (2 * digest_len))
857                                 return -EINVAL;
858                         res = hex2bin(opt->policydigest, args[0].from,
859                                       digest_len);
860                         if (res < 0)
861                                 return -EINVAL;
862                         opt->policydigest_len = digest_len;
863                         break;
864                 case Opt_policyhandle:
865                         if (!tpm2)
866                                 return -EINVAL;
867                         res = kstrtoul(args[0].from, 16, &handle);
868                         if (res < 0)
869                                 return -EINVAL;
870                         opt->policyhandle = handle;
871                         break;
872                 default:
873                         return -EINVAL;
874                 }
875         }
876         return 0;
877 }
878 
879 static struct trusted_key_options *trusted_options_alloc(void)
880 {
881         struct trusted_key_options *options;
882         int tpm2;
883 
884         tpm2 = tpm_is_tpm2(chip);
885         if (tpm2 < 0)
886                 return NULL;
887 
888         options = kzalloc(sizeof *options, GFP_KERNEL);
889         if (options) {
890                 /* set any non-zero defaults */
891                 options->keytype = SRK_keytype;
892 
893                 if (!tpm2)
894                         options->keyhandle = SRKHANDLE;
895         }
896         return options;
897 }
898 
899 static int trusted_tpm_seal(struct trusted_key_payload *p, char *datablob)
900 {
901         struct trusted_key_options *options = NULL;
902         int ret = 0;
903         int tpm2;
904 
905         tpm2 = tpm_is_tpm2(chip);
906         if (tpm2 < 0)
907                 return tpm2;
908 
909         options = trusted_options_alloc();
910         if (!options)
911                 return -ENOMEM;
912 
913         ret = getoptions(datablob, p, options);
914         if (ret < 0)
915                 goto out;
916         dump_options(options);
917 
918         if (!options->keyhandle && !tpm2) {
919                 ret = -EINVAL;
920                 goto out;
921         }
922 
923         if (tpm2)
924                 ret = tpm2_seal_trusted(chip, p, options);
925         else
926                 ret = key_seal(p, options);
927         if (ret < 0) {
928                 pr_info("key_seal failed (%d)\n", ret);
929                 goto out;
930         }
931 
932         if (options->pcrlock) {
933                 ret = pcrlock(options->pcrlock);
934                 if (ret < 0) {
935                         pr_info("pcrlock failed (%d)\n", ret);
936                         goto out;
937                 }
938         }
939 out:
940         kfree_sensitive(options);
941         return ret;
942 }
943 
944 static int trusted_tpm_unseal(struct trusted_key_payload *p, char *datablob)
945 {
946         struct trusted_key_options *options = NULL;
947         int ret = 0;
948         int tpm2;
949 
950         tpm2 = tpm_is_tpm2(chip);
951         if (tpm2 < 0)
952                 return tpm2;
953 
954         options = trusted_options_alloc();
955         if (!options)
956                 return -ENOMEM;
957 
958         ret = getoptions(datablob, p, options);
959         if (ret < 0)
960                 goto out;
961         dump_options(options);
962 
963         if (!options->keyhandle && !tpm2) {
964                 ret = -EINVAL;
965                 goto out;
966         }
967 
968         if (tpm2)
969                 ret = tpm2_unseal_trusted(chip, p, options);
970         else
971                 ret = key_unseal(p, options);
972         if (ret < 0)
973                 pr_info("key_unseal failed (%d)\n", ret);
974 
975         if (options->pcrlock) {
976                 ret = pcrlock(options->pcrlock);
977                 if (ret < 0) {
978                         pr_info("pcrlock failed (%d)\n", ret);
979                         goto out;
980                 }
981         }
982 out:
983         kfree_sensitive(options);
984         return ret;
985 }
986 
987 static int trusted_tpm_get_random(unsigned char *key, size_t key_len)
988 {
989         return tpm_get_random(chip, key, key_len);
990 }
991 
992 static void trusted_shash_release(void)
993 {
994         if (hashalg)
995                 crypto_free_shash(hashalg);
996         if (hmacalg)
997                 crypto_free_shash(hmacalg);
998 }
999 
1000 static int __init trusted_shash_alloc(void)
1001 {
1002         int ret;
1003 
1004         hmacalg = crypto_alloc_shash(hmac_alg, 0, 0);
1005         if (IS_ERR(hmacalg)) {
1006                 pr_info("could not allocate crypto %s\n",
1007                         hmac_alg);
1008                 return PTR_ERR(hmacalg);
1009         }
1010 
1011         hashalg = crypto_alloc_shash(hash_alg, 0, 0);
1012         if (IS_ERR(hashalg)) {
1013                 pr_info("could not allocate crypto %s\n",
1014                         hash_alg);
1015                 ret = PTR_ERR(hashalg);
1016                 goto hashalg_fail;
1017         }
1018 
1019         return 0;
1020 
1021 hashalg_fail:
1022         crypto_free_shash(hmacalg);
1023         return ret;
1024 }
1025 
1026 static int __init init_digests(void)
1027 {
1028         int i;
1029 
1030         digests = kcalloc(chip->nr_allocated_banks, sizeof(*digests),
1031                           GFP_KERNEL);
1032         if (!digests)
1033                 return -ENOMEM;
1034 
1035         for (i = 0; i < chip->nr_allocated_banks; i++)
1036                 digests[i].alg_id = chip->allocated_banks[i].alg_id;
1037 
1038         return 0;
1039 }
1040 
1041 static int __init trusted_tpm_init(void)
1042 {
1043         int ret;
1044 
1045         chip = tpm_default_chip();
1046         if (!chip)
1047                 return -ENODEV;
1048 
1049         ret = init_digests();
1050         if (ret < 0)
1051                 goto err_put;
1052         ret = trusted_shash_alloc();
1053         if (ret < 0)
1054                 goto err_free;
1055         ret = register_key_type(&key_type_trusted);
1056         if (ret < 0)
1057                 goto err_release;
1058         return 0;
1059 err_release:
1060         trusted_shash_release();
1061 err_free:
1062         kfree(digests);
1063 err_put:
1064         put_device(&chip->dev);
1065         return ret;
1066 }
1067 
1068 static void trusted_tpm_exit(void)
1069 {
1070         if (chip) {
1071                 put_device(&chip->dev);
1072                 kfree(digests);
1073                 trusted_shash_release();
1074                 unregister_key_type(&key_type_trusted);
1075         }
1076 }
1077 
1078 struct trusted_key_ops trusted_key_tpm_ops = {
1079         .migratable = 1, /* migratable by default */
1080         .init = trusted_tpm_init,
1081         .seal = trusted_tpm_seal,
1082         .unseal = trusted_tpm_unseal,
1083         .get_random = trusted_tpm_get_random,
1084         .exit = trusted_tpm_exit,
1085 };
1086 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php