Imported Upstream version 2.3.1
[platform/upstream/gpg2.git] / tpm2d / tpm2.c
1 /* tpm2.c - Supporting TPM routines for the IBM TSS
2  * Copyright (C) 2021 James Bottomley <James.Bottomley@HansenPartnership.com>
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <https://www.gnu.org/licenses/>.
18  * SPDX-License-Identifier: GPL-3.0-or-later
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <assert.h>
28 #include <unistd.h>
29 #include <sys/stat.h>
30 #include <arpa/inet.h>
31
32 #include "tpm2.h"
33
34 #include "../common/i18n.h"
35 #include "../common/sexp-parse.h"
36
37 int
38 tpm2_start (TSS_CONTEXT **tssc)
39 {
40   return TSS_start(tssc);
41 }
42
43 void
44 tpm2_end (TSS_CONTEXT *tssc)
45 {
46   TSS_Delete (tssc);
47 }
48
49 static TPM_HANDLE
50 tpm2_get_parent (TSS_CONTEXT *tssc, TPM_HANDLE p)
51 {
52   TPM_RC rc;
53   TPM2B_SENSITIVE_CREATE inSensitive;
54   TPM2B_PUBLIC inPublic;
55   TPM_HANDLE objectHandle;
56
57   p = tpm2_handle_int(tssc, p);
58   if (tpm2_handle_mso(tssc, p, TPM_HT_PERSISTENT))
59     return p;                   /* should only be permanent */
60
61   /*  assume no hierarchy auth */
62   VAL_2B (inSensitive.sensitive.userAuth, size) = 0;
63   /* no sensitive date for storage keys */
64   VAL_2B (inSensitive.sensitive.data, size) = 0;
65
66   /* public parameters for a P-256 EC key  */
67   inPublic.publicArea.type = TPM_ALG_ECC;
68   inPublic.publicArea.nameAlg = TPM_ALG_SHA256;
69   VAL (inPublic.publicArea.objectAttributes) =
70     TPMA_OBJECT_NODA |
71     TPMA_OBJECT_SENSITIVEDATAORIGIN |
72     TPMA_OBJECT_USERWITHAUTH |
73     TPMA_OBJECT_DECRYPT |
74     TPMA_OBJECT_RESTRICTED |
75     TPMA_OBJECT_FIXEDPARENT |
76     TPMA_OBJECT_FIXEDTPM;
77
78   inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES;
79   inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128;
80   inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB;
81   inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL;
82   inPublic.publicArea.parameters.eccDetail.curveID = TPM_ECC_NIST_P256;
83   inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
84
85   VAL_2B (inPublic.publicArea.unique.ecc.x, size) = 0;
86   VAL_2B (inPublic.publicArea.unique.ecc.y, size) = 0;
87   VAL_2B (inPublic.publicArea.authPolicy, size) = 0;
88
89   rc = tpm2_CreatePrimary (tssc, p, &inSensitive, &inPublic, &objectHandle);
90   if (rc)
91     {
92       tpm2_error (rc, "TSS_CreatePrimary");
93       return 0;
94     }
95   return objectHandle;
96 }
97
98 void
99 tpm2_flush_handle (TSS_CONTEXT *tssc, TPM_HANDLE h)
100 {
101   /* only flush volatile handles */
102   if (tpm2_handle_mso(tssc, h, TPM_HT_PERSISTENT))
103     return;
104
105   tpm2_FlushContext(tssc, h);
106 }
107
108 static int
109 tpm2_get_hmac_handle (TSS_CONTEXT *tssc, TPM_HANDLE *handle,
110                       TPM_HANDLE salt_key)
111 {
112   TPM_RC rc;
113   TPMT_SYM_DEF symmetric;
114
115   symmetric.algorithm = TPM_ALG_AES;
116   symmetric.keyBits.aes = 128;
117   symmetric.mode.aes = TPM_ALG_CFB;
118
119   rc = tpm2_StartAuthSession(tssc, salt_key, TPM_RH_NULL, TPM_SE_HMAC,
120                              &symmetric, TPM_ALG_SHA256, handle, NULL);
121   if (rc)
122     {
123       tpm2_error (rc, "TPM2_StartAuthSession");
124       return GPG_ERR_CARD;
125     }
126
127   return 0;
128 }
129
130 static int
131 tpm2_pre_auth (ctrl_t ctrl, TSS_CONTEXT *tssc,
132                gpg_error_t (*pin_cb)(ctrl_t ctrl, const char *info,
133                                      char **retstr),
134                TPM_HANDLE *ah, char **auth)
135 {
136   TPM_RC rc;
137   int len;
138
139   rc = pin_cb (ctrl, _("TPM Key Passphrase"), auth);
140   if (rc)
141     return rc;
142
143   len = strlen(*auth);
144   /*
145    * TPMs can't accept a longer passphrase than the name algorithm.
146    * We hard code the name algorithm to SHA256 so the max passphrase
147    * length is 32
148    */
149   if (len > 32)
150     {
151       log_error ("Truncating Passphrase to TPM allowed 32\n");
152       (*auth)[32] = '\0';
153     }
154
155   rc = tpm2_get_hmac_handle (tssc, ah, TPM_RH_NULL);
156
157   return rc;
158 }
159
160 static int
161 tpm2_post_auth (TSS_CONTEXT *tssc, TPM_RC rc, TPM_HANDLE ah,
162                 char **auth, const char *cmd_str)
163 {
164   gcry_free (*auth);
165   *auth = NULL;
166   if (rc)
167     {
168       tpm2_error (rc, cmd_str);
169       tpm2_flush_handle (tssc, ah);
170       switch (rc & 0xFF)
171         {
172         case TPM_RC_BAD_AUTH:
173         case TPM_RC_AUTH_FAIL:
174           return GPG_ERR_BAD_PASSPHRASE;
175         default:
176           return GPG_ERR_CARD;
177         }
178     }
179   return 0;
180 }
181
182 static unsigned char *
183 make_tpm2_shadow_info (uint32_t parent, const char *pub, int pub_len,
184                        const char *priv, int priv_len, size_t *len)
185 {
186   gcry_sexp_t s_exp;
187   char *info;
188
189   gcry_sexp_build (&s_exp, NULL, "(%u%b%b)", parent, pub_len, pub,
190                    priv_len, priv);
191
192   *len = gcry_sexp_sprint (s_exp, GCRYSEXP_FMT_CANON, NULL, 0);
193   info = xtrymalloc (*len);
194   if (!info)
195           goto out;
196   gcry_sexp_sprint (s_exp, GCRYSEXP_FMT_CANON, info, *len);
197
198  out:
199   gcry_sexp_release (s_exp);
200   return (unsigned char *)info;
201 }
202
203 static gpg_error_t
204 parse_tpm2_shadow_info (const unsigned char *shadow_info,
205                         uint32_t *parent,
206                         const char **pub, int *pub_len,
207                         const char **priv, int *priv_len)
208 {
209   const unsigned char *s;
210   size_t n;
211   int i;
212
213   s = shadow_info;
214   if (*s != '(')
215     return gpg_error (GPG_ERR_INV_SEXP);
216   s++;
217   n = snext (&s);
218   if (!n)
219     return gpg_error (GPG_ERR_INV_SEXP);
220   *parent = 0;
221   for (i = 0; i < n; i++)
222     {
223       *parent *= 10;
224       *parent += atoi_1(s+i);
225     }
226
227   s += n;
228   n = snext (&s);
229   if (!n)
230     return gpg_error (GPG_ERR_INV_SEXP);
231
232   *pub_len = n;
233   *pub = s;
234
235   s += n;
236   n = snext (&s);
237   if (!n)
238     return gpg_error (GPG_ERR_INV_SEXP);
239
240   *priv_len = n;
241   *priv = s;
242
243   return 0;
244 }
245
246 int
247 tpm2_load_key (TSS_CONTEXT *tssc, const unsigned char *shadow_info,
248                TPM_HANDLE *key, TPMI_ALG_PUBLIC *type)
249 {
250   uint32_t parent;
251   TPM_HANDLE parentHandle;
252   PRIVATE_2B inPrivate;
253   TPM2B_PUBLIC inPublic;
254   const char *pub, *priv;
255   int ret, pub_len, priv_len;
256   TPM_RC rc;
257   BYTE *buf;
258   uint32_t size;
259
260   ret = parse_tpm2_shadow_info (shadow_info, &parent, &pub, &pub_len,
261                                 &priv, &priv_len);
262   if (ret)
263     return ret;
264
265   parentHandle = tpm2_get_parent (tssc, parent);
266
267   buf = (BYTE *)priv;
268   size = priv_len;
269   TPM2B_PRIVATE_Unmarshal ((TPM2B_PRIVATE *)&inPrivate, &buf, &size);
270
271   buf = (BYTE *)pub;
272   size = pub_len;
273   TPM2B_PUBLIC_Unmarshal (&inPublic, &buf, &size, FALSE);
274
275   *type = inPublic.publicArea.type;
276
277   rc = tpm2_Load (tssc, parentHandle, &inPrivate, &inPublic, key,
278                   TPM_RS_PW, NULL);
279
280   tpm2_flush_handle (tssc, parentHandle);
281
282   if (rc != TPM_RC_SUCCESS)
283     {
284       tpm2_error (rc, "TPM2_Load");
285       return GPG_ERR_CARD;
286     }
287
288   return 0;
289 }
290
291 int
292 tpm2_sign (ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key,
293            gpg_error_t (*pin_cb)(ctrl_t ctrl, const char *info,
294                                  char **retstr),
295            TPMI_ALG_PUBLIC type,
296            const unsigned char *digest, size_t digestlen,
297            unsigned char **r_sig, size_t *r_siglen)
298 {
299   int ret;
300   DIGEST_2B digest2b;
301   TPMT_SIG_SCHEME inScheme;
302   TPMT_SIGNATURE signature;
303   TPM_HANDLE ah;
304   char *auth;
305
306   /* The TPM insists on knowing the digest type, so
307    * calculate that from the size */
308   switch (digestlen)
309     {
310     case 20:
311       inScheme.details.rsassa.hashAlg = TPM_ALG_SHA1;
312       break;
313     case 32:
314       inScheme.details.rsassa.hashAlg = TPM_ALG_SHA256;
315       break;
316     case 48:
317       inScheme.details.rsassa.hashAlg = TPM_ALG_SHA384;
318       break;
319 #ifdef TPM_ALG_SHA512
320     case 64:
321       inScheme.details.rsassa.hashAlg = TPM_ALG_SHA512;
322       break;
323 #endif
324     default:
325       log_error ("Unknown signature digest length, cannot deduce hash type for TPM\n");
326       return GPG_ERR_NO_SIGNATURE_SCHEME;
327     }
328   digest2b.size = digestlen;
329   memcpy (digest2b.buffer, digest, digestlen);
330
331   if (type == TPM_ALG_RSA)
332     inScheme.scheme = TPM_ALG_RSASSA;
333   else if (type == TPM_ALG_ECC)
334     inScheme.scheme = TPM_ALG_ECDSA;
335   else
336     return GPG_ERR_PUBKEY_ALGO;
337
338   ret = tpm2_pre_auth (ctrl, tssc, pin_cb, &ah, &auth);
339   if (ret)
340     return ret;
341   ret = tpm2_Sign (tssc, key, &digest2b, &inScheme, &signature, ah, auth);
342   ret = tpm2_post_auth (tssc, ret, ah, &auth, "TPM2_Sign");
343   if (ret)
344     return ret;
345
346   if (type == TPM_ALG_RSA)
347     *r_siglen = VAL_2B (signature.signature.rsassa.sig, size);
348   else if (type == TPM_ALG_ECC)
349     *r_siglen = VAL_2B (signature.signature.ecdsa.signatureR, size)
350       + VAL_2B (signature.signature.ecdsa.signatureS, size);
351
352   *r_sig = xtrymalloc (*r_siglen);
353   if (!r_sig)
354     return GPG_ERR_ENOMEM;
355
356   if (type == TPM_ALG_RSA)
357     {
358       memcpy (*r_sig, VAL_2B (signature.signature.rsassa.sig, buffer),
359               *r_siglen);
360     }
361   else if (type == TPM_ALG_ECC)
362     {
363       memcpy (*r_sig, VAL_2B (signature.signature.ecdsa.signatureR, buffer),
364               VAL_2B (signature.signature.ecdsa.signatureR, size));
365       memcpy (*r_sig + VAL_2B (signature.signature.ecdsa.signatureR, size),
366               VAL_2B (signature.signature.ecdsa.signatureS, buffer),
367               VAL_2B (signature.signature.ecdsa.signatureS, size));
368     }
369
370   return 0;
371 }
372
373 static int
374 sexp_to_tpm2_sensitive_ecc (TPMT_SENSITIVE *s, gcry_sexp_t key)
375 {
376   gcry_mpi_t d;
377   gcry_sexp_t l;
378   int rc = -1;
379   size_t len;
380
381   s->sensitiveType = TPM_ALG_ECC;
382   VAL_2B (s->seedValue, size) = 0;
383
384   l = gcry_sexp_find_token (key, "d", 0);
385   if (!l)
386     return rc;
387   d = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
388   gcry_sexp_release (l);
389   len = sizeof (VAL_2B (s->sensitive.ecc, buffer));
390   rc = gcry_mpi_print (GCRYMPI_FMT_USG, VAL_2B (s->sensitive.ecc, buffer),
391                        len, &len, d);
392   VAL_2B (s->sensitive.ecc, size) = len;
393   gcry_mpi_release (d);
394
395   return rc;
396 }
397
398 /* try to match the libgcrypt curve names to known TPM parameters.
399  *
400  * As of 2018 the TCG defined curves are only NIST
401  * (192,224,256,384,521) Barreto-Naehring (256,638) and the Chinese
402  * SM2 (256), which means only the NIST ones overlap with libgcrypt */
403 static struct {
404   const char *name;
405   TPMI_ECC_CURVE c;
406 } tpm2_curves[] = {
407   { "NIST P-192", TPM_ECC_NIST_P192 },
408   { "prime192v1", TPM_ECC_NIST_P192 },
409   { "secp192r1", TPM_ECC_NIST_P192 },
410   { "nistp192", TPM_ECC_NIST_P192 },
411   { "NIST P-224", TPM_ECC_NIST_P224 },
412   { "secp224r1", TPM_ECC_NIST_P224 },
413   { "nistp224", TPM_ECC_NIST_P224 },
414   { "NIST P-256", TPM_ECC_NIST_P256 },
415   { "prime256v1", TPM_ECC_NIST_P256 },
416   { "secp256r1", TPM_ECC_NIST_P256 },
417   { "nistp256", TPM_ECC_NIST_P256 },
418   { "NIST P-384", TPM_ECC_NIST_P384 },
419   { "secp384r1", TPM_ECC_NIST_P384 },
420   { "nistp384", TPM_ECC_NIST_P384 },
421   { "NIST P-521", TPM_ECC_NIST_P521 },
422   { "secp521r1", TPM_ECC_NIST_P521 },
423   { "nistp521", TPM_ECC_NIST_P521 },
424 };
425
426 static int
427 tpm2_ecc_curve (const char *curve_name, TPMI_ECC_CURVE *c)
428 {
429   int i;
430
431   for (i = 0; i < DIM (tpm2_curves); i++)
432     if (strcmp (tpm2_curves[i].name, curve_name) == 0)
433       break;
434   if (i == DIM (tpm2_curves))
435     {
436       log_error ("curve %s does not match any available TPM curves\n", curve_name);
437       return GPG_ERR_UNKNOWN_CURVE;
438     }
439
440   *c = tpm2_curves[i].c;
441
442   return 0;
443 }
444
445 static int
446 sexp_to_tpm2_public_ecc (TPMT_PUBLIC *p, gcry_sexp_t key)
447 {
448   const char *q;
449   gcry_sexp_t l;
450   int rc = GPG_ERR_BAD_PUBKEY;
451   size_t len;
452   TPMI_ECC_CURVE curve;
453   char *curve_name;
454
455   l = gcry_sexp_find_token (key, "curve", 0);
456   if (!l)
457     return rc;
458   curve_name = gcry_sexp_nth_string (l, 1);
459   if (!curve_name)
460     goto out;
461   rc = tpm2_ecc_curve (curve_name, &curve);
462   gcry_free (curve_name);
463   if (rc)
464     goto out;
465   gcry_sexp_release (l);
466
467   l = gcry_sexp_find_token (key, "q", 0);
468   if (!l)
469     return rc;
470   q = gcry_sexp_nth_data (l, 1, &len);
471   /* This is a point representation, the first byte tells you what
472    * type.  The only format we understand is uncompressed (0x04)
473    * which has layout 0x04 | x | y */
474   if (q[0] != 0x04)
475     {
476       log_error ("Point format for q is not uncompressed\n");
477       goto out;
478     }
479   q++;
480   len--;
481   /* now should have to equal sized big endian point numbers */
482   if ((len & 0x01) == 1)
483     {
484       log_error ("Point format for q has incorrect length\n");
485       goto out;
486     }
487
488   len >>= 1;
489
490   p->type = TPM_ALG_ECC;
491   p->nameAlg = TPM_ALG_SHA256;
492   VAL (p->objectAttributes) = TPMA_OBJECT_NODA |
493     TPMA_OBJECT_SIGN |
494     TPMA_OBJECT_DECRYPT |
495     TPMA_OBJECT_USERWITHAUTH;
496   VAL_2B (p->authPolicy, size) = 0;
497   p->parameters.eccDetail.symmetric.algorithm = TPM_ALG_NULL;
498   p->parameters.eccDetail.scheme.scheme = TPM_ALG_NULL;
499   p->parameters.eccDetail.curveID = curve;
500   p->parameters.eccDetail.kdf.scheme = TPM_ALG_NULL;
501   memcpy (VAL_2B (p->unique.ecc.x, buffer), q, len);
502   VAL_2B (p->unique.ecc.x, size) = len;
503   memcpy (VAL_2B (p->unique.ecc.y, buffer), q + len, len);
504   VAL_2B (p->unique.ecc.y, size) = len;
505  out:
506   gcry_sexp_release (l);
507   return rc;
508 }
509
510 static int
511 sexp_to_tpm2_sensitive_rsa (TPMT_SENSITIVE *s, gcry_sexp_t key)
512 {
513   gcry_mpi_t p;
514   gcry_sexp_t l;
515   int rc = -1;
516   size_t len;
517
518   s->sensitiveType = TPM_ALG_RSA;
519   VAL_2B (s->seedValue, size) = 0;
520
521   l = gcry_sexp_find_token (key, "p", 0);
522   if (!l)
523     return rc;
524   p = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
525   gcry_sexp_release (l);
526   len = sizeof (VAL_2B (s->sensitive.rsa, buffer));
527   rc = gcry_mpi_print (GCRYMPI_FMT_USG, VAL_2B (s->sensitive.rsa, buffer),
528                        len, &len, p);
529   VAL_2B (s->sensitive.rsa, size) = len;
530   gcry_mpi_release (p);
531
532   return rc;
533 }
534
535 static int
536 sexp_to_tpm2_public_rsa (TPMT_PUBLIC *p, gcry_sexp_t key)
537 {
538   gcry_mpi_t n, e;
539   gcry_sexp_t l;
540   int rc = -1, i;
541   size_t len;
542   /* longer than an int */
543   unsigned char ebuf[5];
544   uint32_t exp = 0;
545
546   p->type = TPM_ALG_RSA;
547   p->nameAlg = TPM_ALG_SHA256;
548   VAL (p->objectAttributes) = TPMA_OBJECT_NODA |
549     TPMA_OBJECT_DECRYPT |
550     TPMA_OBJECT_SIGN |
551     TPMA_OBJECT_USERWITHAUTH;
552   VAL_2B (p->authPolicy, size) = 0;
553   p->parameters.rsaDetail.symmetric.algorithm = TPM_ALG_NULL;
554   p->parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL;
555
556   l = gcry_sexp_find_token (key, "n", 0);
557   if (!l)
558     return rc;
559   n = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
560   gcry_sexp_release (l);
561   len = sizeof (VAL_2B (p->unique.rsa, buffer));
562   p->parameters.rsaDetail.keyBits = gcry_mpi_get_nbits (n);
563   rc = gcry_mpi_print (GCRYMPI_FMT_USG, VAL_2B (p->unique.rsa, buffer),
564                        len, &len, n);
565   VAL_2B (p->unique.rsa, size) = len;
566   gcry_mpi_release (n);
567   if (rc)
568     return rc;
569   rc = -1;
570   l = gcry_sexp_find_token (key, "e", 0);
571   if (!l)
572     return rc;
573   e = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
574   gcry_sexp_release (l);
575   len = sizeof (ebuf);
576   rc = gcry_mpi_print (GCRYMPI_FMT_USG, ebuf, len, &len, e);
577   gcry_mpi_release (e);
578   if (rc)
579     return rc;
580   if (len > 4)
581     return -1;
582
583   /* MPI are simply big endian integers, so convert to uint32 */
584   for (i = 0; i < len; i++)
585     {
586       exp <<= 8;
587       exp += ebuf[i];
588     }
589   if (exp == 0x10001)
590     p->parameters.rsaDetail.exponent = 0;
591   else
592     p->parameters.rsaDetail.exponent = exp;
593   return 0;
594 }
595
596 static int
597 sexp_to_tpm2(TPMT_PUBLIC *p, TPMT_SENSITIVE *s, gcry_sexp_t s_skey)
598 {
599   gcry_sexp_t l1, l2;
600   int rc = -1;
601
602   /* find the value of (private-key */
603   l1 = gcry_sexp_nth (s_skey, 1);
604   if (!l1)
605     return rc;
606
607   l2 = gcry_sexp_find_token (l1, "rsa", 0);
608   if (l2)
609     {
610       rc = sexp_to_tpm2_public_rsa (p, l2);
611       if (!rc)
612         rc = sexp_to_tpm2_sensitive_rsa (s, l2);
613     }
614   else
615     {
616       l2 = gcry_sexp_find_token (l1, "ecc", 0);
617       if (!l2)
618         goto out;
619       rc = sexp_to_tpm2_public_ecc (p, l2);
620       if (!rc)
621         rc = sexp_to_tpm2_sensitive_ecc (s, l2);
622     }
623
624   gcry_sexp_release (l2);
625
626  out:
627   gcry_sexp_release (l1);
628   return rc;
629 }
630
631 /* copied from TPM implementation code */
632 static TPM_RC
633 tpm2_ObjectPublic_GetName (NAME_2B *name,
634                            TPMT_PUBLIC *tpmtPublic)
635 {
636   TPM_RC rc = 0;
637   uint16_t written = 0;
638   TPMT_HA digest;
639   uint32_t sizeInBytes;
640   uint8_t buffer[MAX_RESPONSE_SIZE];
641
642   /* marshal the TPMT_PUBLIC */
643   if (rc == 0)
644     {
645       INT32 size = MAX_RESPONSE_SIZE;
646       uint8_t *buffer1 = buffer;
647       rc = TSS_TPMT_PUBLIC_Marshal (tpmtPublic, &written, &buffer1, &size);
648     }
649   /* hash the public area */
650   if (rc == 0)
651     {
652       sizeInBytes = TSS_GetDigestSize (tpmtPublic->nameAlg);
653       digest.hashAlg = tpmtPublic->nameAlg;       /* Name digest algorithm */
654       /* generate the TPMT_HA */
655       rc = TSS_Hash_Generate (&digest, written, buffer, 0, NULL);
656     }
657   if (rc == 0)
658     {
659       TPMI_ALG_HASH nameAlgNbo;
660
661       /* copy the digest */
662       memcpy (name->name + sizeof (TPMI_ALG_HASH),
663               (uint8_t *)&digest.digest, sizeInBytes);
664       /* copy the hash algorithm */
665       nameAlgNbo = htons (tpmtPublic->nameAlg);
666       memcpy (name->name, (uint8_t *)&nameAlgNbo, sizeof (TPMI_ALG_HASH));
667       /* set the size */
668       name->size = sizeInBytes + sizeof (TPMI_ALG_HASH);
669     }
670   return rc;
671 }
672
673 /*
674  * Cut down version of Part 4 Supporting Routines 7.6.3.10
675  *
676  * Hard coded to symmetrically encrypt with aes128 as the inner
677  * wrapper and no outer wrapper but with a prototype that allows
678  * drop in replacement with a tss equivalent
679  */
680 TPM_RC tpm2_SensitiveToDuplicate (TPMT_SENSITIVE *s,
681                                   NAME_2B *name,
682                                   TPM_ALG_ID nalg,
683                                   TPMT_SYM_DEF_OBJECT *symdef,
684                                   DATA_2B *innerkey,
685                                   PRIVATE_2B *p)
686 {
687   BYTE *buf = p->buffer;
688
689   p->size = 0;
690   memset (p, 0, sizeof (*p));
691
692   /* hard code AES CFB */
693   if (symdef->algorithm == TPM_ALG_AES
694       && symdef->mode.aes == TPM_ALG_CFB)
695     {
696       TPMT_HA hash;
697       const int hlen = TSS_GetDigestSize (nalg);
698       TPM2B *digest = (TPM2B *)buf;
699       TPM2B *s2b;
700       int32_t size;
701       unsigned char null_iv[AES_128_BLOCK_SIZE_BYTES];
702       UINT16 bsize, written = 0;
703       gcry_cipher_hd_t hd;
704
705       /* WARNING: don't use the static null_iv trick here:
706        * the AES routines alter the passed in iv */
707       memset (null_iv, 0, sizeof (null_iv));
708
709       /* reserve space for hash before the encrypted sensitive */
710       bsize = sizeof (digest->size) + hlen;
711       buf += bsize;
712       p->size += bsize;
713       s2b = (TPM2B *)buf;
714
715       /* marshal the digest size */
716       buf = (BYTE *)&digest->size;
717       bsize = hlen;
718       size = 2;
719       TSS_UINT16_Marshal (&bsize, &written, &buf, &size);
720
721       /* marshal the unencrypted sensitive in place */
722       size = sizeof (*s);
723       bsize = 0;
724       buf = s2b->buffer;
725       TSS_TPMT_SENSITIVE_Marshal (s, &bsize, &buf, &size);
726       buf = (BYTE *)&s2b->size;
727       size = 2;
728       TSS_UINT16_Marshal (&bsize, &written, &buf, &size);
729
730       bsize = bsize + sizeof (s2b->size);
731       p->size += bsize;
732
733       /* compute hash of unencrypted marshalled sensitive and
734        * write to the digest buffer */
735       hash.hashAlg = nalg;
736       TSS_Hash_Generate (&hash, bsize, s2b,
737                          name->size, name->name,
738                          0, NULL);
739       memcpy (digest->buffer, &hash.digest, hlen);
740       gcry_cipher_open (&hd, GCRY_CIPHER_AES128,
741                         GCRY_CIPHER_MODE_CFB, GCRY_CIPHER_SECURE);
742       gcry_cipher_setiv (hd, null_iv, sizeof (null_iv));
743       gcry_cipher_setkey (hd, innerkey->buffer, innerkey->size);
744       /* encrypt the hash and sensitive in-place */
745       gcry_cipher_encrypt (hd, p->buffer, p->size, NULL, 0);
746       gcry_cipher_close (hd);
747
748     }
749   else if (symdef->algorithm == TPM_ALG_NULL)
750     {
751       /* Code is for debugging only, should never be used in production */
752       TPM2B *s2b = (TPM2B *)buf;
753       int32_t size = sizeof (*s);
754       UINT16 bsize = 0, written = 0;
755
756       log_error ("Secret key sent to TPM unencrypted\n");
757       buf = s2b->buffer;
758
759       /* marshal the unencrypted sensitive in place */
760       TSS_TPMT_SENSITIVE_Marshal (s, &bsize, &buf, &size);
761       buf = (BYTE *)&s2b->size;
762       size = 2;
763       TSS_UINT16_Marshal (&bsize, &written, &buf, &size);
764
765       p->size += bsize + sizeof (s2b->size);
766     }
767   else
768     {
769       log_error ("Unknown symmetric algorithm\n");
770       return TPM_RC_SYMMETRIC;
771     }
772
773   return TPM_RC_SUCCESS;
774 }
775
776 int
777 tpm2_import_key (ctrl_t ctrl, TSS_CONTEXT *tssc,
778                  gpg_error_t (*pin_cb)(ctrl_t ctrl, const char *info,
779                                        char **retstr),
780                  unsigned char **shadow_info, size_t *shadow_len,
781                  gcry_sexp_t s_skey, unsigned long parent)
782 {
783   TPM_HANDLE parentHandle;
784   DATA_2B encryptionKey;
785   TPM2B_PUBLIC objectPublic;
786   PRIVATE_2B duplicate;
787   ENCRYPTED_SECRET_2B inSymSeed;
788   TPMT_SYM_DEF_OBJECT symmetricAlg;
789   PRIVATE_2B outPrivate;
790   NAME_2B name;
791   const int aes_key_bits = 128;
792   const int aes_key_bytes = aes_key_bits/8;
793
794   TPMT_SENSITIVE s;
795   TPM_HANDLE ah;
796   TPM_RC rc;
797
798   uint32_t size;
799   uint16_t len;
800   BYTE *buffer;
801   int ret;
802   char *passphrase;
803
804   char pub[sizeof (TPM2B_PUBLIC)];
805   int pub_len;
806   char priv[sizeof (TPM2B_PRIVATE)];
807   int priv_len;
808
809   if (parent == 0)
810     parent = EXT_TPM_RH_OWNER;
811
812   ret = sexp_to_tpm2 (&objectPublic.publicArea, &s, s_skey);
813   if (ret)
814     {
815       log_error ("Failed to parse Key s-expression: key corrupt?\n");
816       return ret;
817     }
818
819   /* add an authorization password to the key which the TPM will check */
820
821   ret = pin_cb (ctrl,  _("Please enter the TPM Authorization passphrase for the key."), &passphrase);
822   if (ret)
823     return ret;
824   len = strlen(passphrase);
825   if (len > TSS_GetDigestSize(objectPublic.publicArea.nameAlg))
826     {
827       len = TSS_GetDigestSize(objectPublic.publicArea.nameAlg);
828       log_error ("Truncating Passphrase to TPM allowed %d\n", len);
829     }
830   VAL_2B (s.authValue, size) = len;
831   memcpy (VAL_2B (s.authValue, buffer), passphrase, len);
832
833   /* We're responsible for securing the data in transmission to the
834    * TPM here.  The TPM provides parameter encryption via a session,
835    * but only for the first parameter.  For TPM2_Import, the first
836    * parameter is a symmetric key used to encrypt the sensitive data,
837    * so we must populate this key with random value and encrypt the
838    * sensitive data with it */
839   parentHandle = tpm2_get_parent (tssc, parent);
840   tpm2_ObjectPublic_GetName (&name, &objectPublic.publicArea);
841   gcry_randomize (encryptionKey.buffer,
842                  aes_key_bytes, GCRY_STRONG_RANDOM);
843   encryptionKey.size = aes_key_bytes;
844
845   /* set random symSeed */
846   inSymSeed.size = 0;
847   symmetricAlg.algorithm = TPM_ALG_AES;
848   symmetricAlg.keyBits.aes = aes_key_bits;
849   symmetricAlg.mode.aes = TPM_ALG_CFB;
850
851   tpm2_SensitiveToDuplicate (&s, &name, objectPublic.publicArea.nameAlg,
852                              &symmetricAlg, &encryptionKey, &duplicate);
853
854   /* use salted parameter encryption to hide the key.  First we read
855    * the public parameters of the parent key and use them to agree an
856    * encryption for the first parameter */
857   rc = tpm2_get_hmac_handle (tssc, &ah, parentHandle);
858   if (rc)
859     {
860       tpm2_flush_handle (tssc, parentHandle);
861       return GPG_ERR_CARD;
862     }
863
864   rc = tpm2_Import (tssc, parentHandle, &encryptionKey, &objectPublic,
865                     &duplicate, &inSymSeed, &symmetricAlg, &outPrivate,
866                     ah, NULL);
867   tpm2_flush_handle (tssc, parentHandle);
868   if (rc)
869     {
870       tpm2_error (rc, "TPM2_Import");
871       /* failure means auth handle is not flushed */
872       tpm2_flush_handle (tssc, ah);
873
874       if ((rc & 0xbf) == TPM_RC_VALUE)
875         {
876           log_error ("TPM cannot import RSA key: wrong size");
877           return GPG_ERR_UNSUPPORTED_ALGORITHM;
878         }
879       else if ((rc & 0xbf) == TPM_RC_CURVE)
880         {
881           log_error ("TPM cannot import requested curve");
882           return GPG_ERR_UNKNOWN_CURVE;
883         }
884       return GPG_ERR_CARD;
885     }
886
887   size = sizeof (pub);
888   buffer = pub;
889   len = 0;
890   TSS_TPM2B_PUBLIC_Marshal (&objectPublic,
891                             &len, &buffer, &size);
892   pub_len = len;
893
894   size = sizeof (priv);
895   buffer = priv;
896   len = 0;
897   TSS_TPM2B_PRIVATE_Marshal ((TPM2B_PRIVATE *)&outPrivate,
898                              &len, &buffer, &size);
899   priv_len = len;
900
901   *shadow_info = make_tpm2_shadow_info (parent, pub, pub_len,
902                                         priv, priv_len, shadow_len);
903   return rc;
904 }
905
906 int
907 tpm2_ecc_decrypt (ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key,
908                   gpg_error_t (*pin_cb)(ctrl_t ctrl, const char *info,
909                                         char **retstr),
910                   const char *ciphertext, int ciphertext_len,
911                   char **decrypt, size_t *decrypt_len)
912 {
913   TPM2B_ECC_POINT inPoint;
914   TPM2B_ECC_POINT outPoint;
915   TPM_HANDLE ah;
916   char *auth;
917   size_t len;
918   int ret;
919
920   /* This isn't really a decryption per se.  The ciphertext actually
921    * contains an EC Point which we must multiply by the private key number.
922    *
923    * The reason is to generate a diffe helman agreement on a shared
924    * point.  This shared point is then used to generate the per
925    * session encryption key.
926    */
927   if (ciphertext[0] != 0x04)
928     {
929       log_error ("Decryption Shared Point format is not uncompressed\n");
930       return GPG_ERR_ENCODING_PROBLEM;
931     }
932   if ((ciphertext_len & 0x01) != 1)
933     {
934       log_error ("Decryption Shared Point has incorrect length\n");
935       return GPG_ERR_ENCODING_PROBLEM;
936     }
937   len = ciphertext_len >> 1;
938
939   memcpy (VAL_2B (inPoint.point.x, buffer), ciphertext + 1, len);
940   VAL_2B (inPoint.point.x, size) = len;
941   memcpy (VAL_2B (inPoint.point.y, buffer), ciphertext + 1 + len, len);
942   VAL_2B (inPoint.point.y, size) = len;
943
944   ret = tpm2_pre_auth (ctrl, tssc, pin_cb, &ah, &auth);
945   if (ret)
946     return ret;
947   ret = tpm2_ECDH_ZGen (tssc, key, &inPoint, &outPoint, ah, auth);
948   ret = tpm2_post_auth (tssc, ret, ah, &auth, "TPM2_ECDH_ZGen");
949   if (ret)
950     return ret;
951
952   *decrypt_len = VAL_2B (outPoint.point.x, size) +
953           VAL_2B (outPoint.point.y, size) + 1;
954   *decrypt = xtrymalloc (*decrypt_len);
955   (*decrypt)[0] = 0x04;
956   memcpy (*decrypt + 1, VAL_2B (outPoint.point.x, buffer),
957           VAL_2B (outPoint.point.x, size));
958   memcpy (*decrypt + 1 + VAL_2B (outPoint.point.x, size),
959           VAL_2B (outPoint.point.y, buffer),
960           VAL_2B (outPoint.point.y, size));
961
962   return 0;
963 }
964
965 int
966 tpm2_rsa_decrypt (ctrl_t ctrl, TSS_CONTEXT *tssc, TPM_HANDLE key,
967                   gpg_error_t (*pin_cb)(ctrl_t ctrl, const char *info,
968                                         char **retstr),
969                   const char *ciphertext, int ciphertext_len,
970                   char **decrypt, size_t *decrypt_len)
971 {
972   int ret;
973   PUBLIC_KEY_RSA_2B cipherText;
974   TPMT_RSA_DECRYPT inScheme;
975   PUBLIC_KEY_RSA_2B message;
976   TPM_HANDLE ah;
977   char *auth;
978
979   inScheme.scheme = TPM_ALG_RSAES;
980   /*
981    * apparent gcrypt error: occasionally rsa ciphertext will
982    * be one byte too long and have a leading zero
983    */
984   if ((ciphertext_len & 1) == 1 && ciphertext[0] == 0)
985     {
986       log_info ("Fixing Wrong Ciphertext size %d\n", ciphertext_len);
987       ciphertext_len--;
988       ciphertext++;
989     }
990   cipherText.size = ciphertext_len;
991   memcpy (cipherText.buffer, ciphertext, ciphertext_len);
992
993   ret = tpm2_pre_auth (ctrl, tssc, pin_cb, &ah, &auth);
994   if (ret)
995     return ret;
996   ret = tpm2_RSA_Decrypt (tssc, key, &cipherText, &inScheme, &message,
997                           ah, auth, TPMA_SESSION_ENCRYPT);
998   ret = tpm2_post_auth (tssc, ret, ah, &auth, "TPM2_RSA_Decrypt");
999   if (ret)
1000     return ret;
1001
1002   *decrypt_len = message.size;
1003   *decrypt = xtrymalloc (message.size);
1004   memcpy (*decrypt, message.buffer, message.size);
1005
1006   return 0;
1007 }