1 /* SPDX-License-Identifier: BSD-3-Clause */
3 * swtpm.c: Programming of a swtpm using communication via fd-passing
5 * Author: Stefan Berger, stefanb@linux.ibm.com
7 * Copyright (c) IBM Corporation, 2021
16 #include <sys/types.h>
17 #include <sys/socket.h>
24 #include <openssl/bn.h>
25 #include <openssl/evp.h>
26 #include <openssl/hmac.h>
27 #include <openssl/rsa.h>
28 #include <openssl/sha.h>
29 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
30 # include <openssl/core_names.h>
31 # include <openssl/param_build.h>
33 # include <openssl/rsa.h>
37 #include "swtpm_utils.h"
38 #include "tpm_ioctl.h"
39 #include "sys_dependencies.h"
41 #define AS2BE(VAL) (((VAL) >> 8) & 0xff), ((VAL) & 0xff)
42 #define AS4BE(VAL) AS2BE((VAL) >> 16), AS2BE(VAL)
43 #define AS8BE(VAL) AS4BE((VAL) >> 32), AS4BE(VAL)
45 struct tpm_req_header
{
49 } __attribute__((packed
));
51 struct tpm_resp_header
{
55 } __attribute__((packed
));
57 static int swtpm_start(struct swtpm
*self
)
59 g_autofree gchar
*tpmstate
= g_strdup_printf("backend-uri=%s", self
->state_path
);
60 g_autofree gchar
*pidfile_arg
= NULL
;
61 g_autofree gchar
*server_fd
= NULL
;
62 g_autofree gchar
*ctrl_fd
= NULL
;
63 g_autofree gchar
*keyopts
= NULL
;
64 g_autofree gchar
*logop
= NULL
;
65 g_autofree gchar
**argv
= NULL
;
72 char pidfile
[] = "/tmp/.swtpm_setup.pidfile.XXXXXX";
74 pidfile_fd
= mkstemp(pidfile
);
76 logerr(self
->logfile
, "Could not create pidfile: %s\n", strerror(errno
));
77 goto error_no_pidfile
;
79 // pass filename rather than fd (Cygwin)
80 pidfile_arg
= g_strdup_printf("file=%s", pidfile
);
82 argv
= concat_arrays(self
->swtpm_exec_l
,
84 "--flags", "not-need-init,startup-clear",
85 "--tpmstate", tpmstate
,
88 "--log", "file=/tmp/log,level=20",
94 argv
= concat_arrays(argv
, (gchar
*[]){"--tpm2", NULL
}, TRUE
);
96 if (self
->keyopts
!= NULL
) {
97 keyopts
= g_strdup(self
->keyopts
);
98 argv
= concat_arrays(argv
, (gchar
*[]){"--key", keyopts
, NULL
}, TRUE
);
101 if (gl_LOGFILE
!= NULL
) {
102 logop
= g_strdup_printf("file=%s", gl_LOGFILE
);
103 argv
= concat_arrays(argv
, (gchar
*[]){"--log", logop
, NULL
}, TRUE
);
106 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, self
->ctrl_fds
) != 0) {
107 logerr(self
->logfile
, "Could not create socketpair: %s\n", strerror(errno
));
110 ctrl_fd
= g_strdup_printf("type=unixio,clientfd=%d", self
->ctrl_fds
[1]);
112 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, self
->data_fds
) != 0) {
113 logerr(self
->logfile
, "Could not create socketpair: %s\n", strerror(errno
));
116 server_fd
= g_strdup_printf("type=tcp,fd=%d", self
->data_fds
[1]);
118 argv
= concat_arrays(argv
, (gchar
*[]){
119 "--server", server_fd
,
126 g_autofree gchar
*join
= g_strjoinv(" ", argv
);
127 logit(self
->logfile
, "Starting swtpm: %s\n", join
);
131 success
= g_spawn_async(NULL
, argv
, NULL
,
132 G_SPAWN_LEAVE_DESCRIPTORS_OPEN
| G_SPAWN_STDOUT_TO_DEV_NULL
| G_SPAWN_STDERR_TO_DEV_NULL
,
133 NULL
, NULL
, &self
->pid
, &error
);
135 logerr(self
->logfile
, "Could not start swtpm: %s\n", error
->message
);
140 /* wait until the pidfile is written to or swtpm terminates */
141 for (ctr
= 0; ctr
< 1000; ctr
++) {
142 if (kill(self
->pid
, 0) < 0) {
143 /* swtpm terminated */
145 logerr(self
->logfile
, "swtpm process terminated unexpectedly.\n");
146 self
->cops
->stop(self
);
149 if (fstat(pidfile_fd
, &statbuf
) == 0 && statbuf
.st_size
> 0) {
150 printf("TPM is listening on Unix socket.\n");
165 /* Stop a running swtpm instance and close all the file descriptors connecting to it */
166 static void swtpm_stop(struct swtpm
*self
)
169 gboolean ended
= FALSE
;
172 self
->cops
->ctrl_shutdown(self
);
173 for (c
= 0; c
< 500; c
++) {
174 if (kill(self
->pid
, 0) < 0) {
181 kill(self
->pid
, SIGKILL
);
182 waitpid(self
->pid
, NULL
, 0);
187 if (self
->ctrl_fds
[0] >= 0) {
188 close(self
->ctrl_fds
[0]);
189 close(self
->ctrl_fds
[1]);
190 self
->ctrl_fds
[0] = self
->ctrl_fds
[1] = -1;
193 if (self
->data_fds
[0] >= 0) {
194 close(self
->data_fds
[0]);
195 close(self
->data_fds
[1]);
196 self
->data_fds
[0] = self
->data_fds
[1] = -1;
200 /* Destroy a running swtpm instance */
201 static void swtpm_destroy(struct swtpm
*self
)
203 self
->cops
->stop(self
);
206 /* Send a command to swtpm and receive the response either via control or data channel */
207 static int transfer(struct swtpm
*self
, void *buffer
, size_t buffer_len
,
208 const char *cmdname
, gboolean use_ctrl
,
209 void *respbuffer
, size_t *respbuffer_len
)
214 unsigned char resp
[4096];
219 sockfd
= self
->ctrl_fds
[0];
222 sockfd
= self
->data_fds
[0];
226 n
= write(sockfd
, buffer
, buffer_len
);
228 logerr(self
->logfile
, "Could not send %s buffer to swtpm: %s\n",
229 cmdname
, strerror(errno
));
232 if ((size_t)n
!= buffer_len
) {
233 logerr(self
->logfile
, "Could not send all bytes to swtpm: %zu < %zu\n",
234 (size_t)n
, buffer_len
);
238 resplen
= read(sockfd
, resp
, sizeof(resp
));
240 logerr(self
->logfile
, "Could not receive response to %s from swtpm: %s\n",
241 cmdname
, strerror(errno
));
246 if ((size_t)resplen
< sizeof(struct tpm_resp_header
)) {
247 logerr(self
->logfile
,
248 "Response for %s has only %d bytes.\n", cmdname
, resplen
);
251 } else if ((size_t)resplen
< 4) {
252 logerr(self
->logfile
,
253 "Response for %s has only %d bytes.\n", cmdname
, resplen
);
257 memcpy(&returncode
, &resp
[offset
], sizeof(returncode
));
258 returncode
= be32toh(returncode
);
259 if (returncode
!= 0) {
260 logerr(self
->logfile
,
261 "%s failed: 0x%x\n", cmdname
, returncode
);
266 *respbuffer_len
= min((size_t)resplen
, *respbuffer_len
);
267 memcpy(respbuffer
, resp
, *respbuffer_len
);
273 /* Send a CMD_SHUTDOWN over the control channel */
274 static int swtpm_ctrl_shutdown(struct swtpm
*self
)
276 uint32_t cmd
= htobe32(CMD_SHUTDOWN
);
278 return transfer(self
, &cmd
, sizeof(cmd
), "CMD_SHUTDOWN", TRUE
, NULL
, 0);
281 /* Get the TPM specification parameters over the control channel */
282 static int swtpm_ctrl_get_tpm_specs_and_attrs(struct swtpm
*self
, gchar
**result
)
284 unsigned char req
[] = {AS4BE(CMD_GET_INFO
),
285 AS8BE(SWTPM_INFO_TPMSPECIFICATION
| SWTPM_INFO_TPMATTRIBUTES
),
287 unsigned char tpmresp
[1024];
288 size_t tpmresp_len
= sizeof(tpmresp
);
292 ret
= transfer(self
, req
, sizeof(req
), "CMD_GET_INFO", TRUE
, tpmresp
, &tpmresp_len
);
296 if (tpmresp_len
< 8 + sizeof(length
))
298 memcpy(&length
, &tpmresp
[8], sizeof(length
));
299 length
= htobe32(length
);
301 if (tpmresp_len
< 12 + length
)
303 *result
= g_strndup((gchar
*)&tpmresp
[12], length
);
308 logerr(self
->logfile
, "Response from CMD_GET_INFO is too short!\n");
313 static const struct swtpm_cops swtpm_cops
= {
314 .start
= swtpm_start
,
316 .destroy
= swtpm_destroy
,
317 .ctrl_shutdown
= swtpm_ctrl_shutdown
,
318 .ctrl_get_tpm_specs_and_attrs
= swtpm_ctrl_get_tpm_specs_and_attrs
,
325 #define TPM2_ST_NO_SESSIONS 0x8001
326 #define TPM2_ST_SESSIONS 0x8002
328 #define TPM2_CC_EVICTCONTROL 0x00000120
329 #define TPM2_CC_NV_DEFINESPACE 0x0000012a
330 #define TPM2_CC_PCR_ALLOCATE 0x0000012b
331 #define TPM2_CC_CREATEPRIMARY 0x00000131
332 #define TPM2_CC_NV_WRITE 0x00000137
333 #define TPM2_CC_NV_WRITELOCK 0x00000138
334 #define TPM2_CC_SHUTDOWN 0x00000145
335 #define TPM2_CC_GETCAPABILITY 0x0000017a
337 #define TPM2_SU_CLEAR 0x0000
339 #define TPM2_RH_OWNER 0x40000001
340 #define TPM2_RS_PW 0x40000009
341 #define TPM2_RH_ENDORSEMENT 0x4000000b
342 #define TPM2_RH_PLATFORM 0x4000000c
344 #define TPM2_ALG_RSA 0x0001
345 #define TPM2_ALG_SHA1 0x0004
346 #define TPM2_ALG_AES 0x0006
347 #define TPM2_ALG_SHA256 0x000b
348 #define TPM2_ALG_SHA384 0x000c
349 #define TPM2_ALG_SHA512 0x000d
350 #define TPM2_ALG_SHA3_256 0x0027
351 #define TPM2_ALG_SHA3_384 0x0028
352 #define TPM2_ALG_SHA3_512 0x0029
353 #define TPM2_ALG_NULL 0x0010
354 #define TPM2_ALG_SM3 0x0012
355 #define TPM2_ALG_ECC 0x0023
356 #define TPM2_ALG_CFB 0x0043
358 #define TPM2_CAP_PCRS 0x00000005
360 #define TPM2_ECC_NIST_P384 0x0004
362 #define TPMA_NV_PLATFORMCREATE 0x40000000
363 #define TPMA_NV_AUTHREAD 0x40000
364 #define TPMA_NV_NO_DA 0x2000000
365 #define TPMA_NV_PPWRITE 0x1
366 #define TPMA_NV_PPREAD 0x10000
367 #define TPMA_NV_OWNERREAD 0x20000
368 #define TPMA_NV_WRITEDEFINE 0x2000
370 // Use standard EK Cert NVRAM, EK and SRK handles per IWG spec.
371 // "TCG TPM v2.0 Provisioning Guide"; Version 1.0, Rev 1.0, March 15, 2017
373 #define TPM2_NV_INDEX_RSA2048_EKCERT 0x01c00002
374 #define TPM2_NV_INDEX_RSA2048_EKTEMPLATE 0x01c00004
375 #define TPM2_NV_INDEX_RSA3072_HI_EKCERT 0x01c0001c
376 #define TPM2_NV_INDEX_RSA3072_HI_EKTEMPLATE 0x01c0001d
377 // For ECC follow "TCG EK Credential Profile For TPM Family 2.0; Level 0"
378 // Specification Version 2.1; Revision 13; 10 December 2018
379 #define TPM2_NV_INDEX_PLATFORMCERT 0x01c08000
381 #define TPM2_NV_INDEX_ECC_SECP384R1_HI_EKCERT 0x01c00016
382 #define TPM2_NV_INDEX_ECC_SECP384R1_HI_EKTEMPLATE 0x01c00017
384 #define TPM2_EK_RSA_HANDLE 0x81010001
385 #define TPM2_EK_RSA3072_HANDLE 0x8101001c
386 #define TPM2_EK_ECC_SECP384R1_HANDLE 0x81010016
387 #define TPM2_SPK_HANDLE 0x81000001
389 #define TPM_REQ_HEADER_INITIALIZER(TAG, SIZE, ORD) \
391 .tag = htobe16(TAG), \
392 .size = htobe32(SIZE), \
393 .ordinal = htobe32(ORD), \
396 struct tpm2_authblock
{
398 uint16_t foo
; // FIXME
399 uint8_t continueSession
;
400 uint16_t bar
; // FIMXE
401 } __attribute__((packed
));
403 #define TPM2_AUTHBLOCK_INITIALIZER(AUTH, FOO, CS, BAR) \
405 .auth = htobe32(AUTH), \
406 .foo = htobe16(FOO), \
407 .continueSession = CS, \
408 .bar = htobe16(BAR), \
411 static const unsigned char NONCE_EMPTY
[2] = {AS2BE(0)};
412 static const unsigned char NONCE_RSA2048
[2+0x100] = {AS2BE(0x100), 0, };
413 static const unsigned char NONCE_RSA3072
[2+0x180] = {AS2BE(0x180), 0, };
414 static const unsigned char NONCE_ECC_384
[2+0x30] = {AS2BE(0x30), 0, };
416 static const struct bank_to_name
{
419 } banks_to_names
[] = {
420 {TPM2_ALG_SHA1
, "sha1"},
421 {TPM2_ALG_SHA256
, "sha256"},
422 {TPM2_ALG_SHA384
, "sha384"},
423 {TPM2_ALG_SHA512
, "sha512"},
424 {TPM2_ALG_SM3
, "sm3-256"},
425 {TPM2_ALG_SHA3_256
, "sha3-256"},
426 {TPM2_ALG_SHA3_384
, "sha3-384"},
427 {TPM2_ALG_SHA3_512
, "sha3-512"},
431 /* function prototypes */
432 static int swtpm_tpm2_createprimary_rsa(struct swtpm
*self
, uint32_t primaryhandle
, unsigned int keyflags
,
433 const unsigned char *symkeydata
, size_t symkeydata_len
,
434 const unsigned char *authpolicy
, size_t authpolicy_len
,
435 unsigned int rsa_keysize
, gboolean havenonce
, size_t off
,
436 uint32_t *curr_handle
,
437 unsigned char *ektemplate
, size_t *ektemplate_len
,
438 gchar
**ekparam
, const gchar
**key_description
);
440 static int swtpm_tpm2_write_nvram(struct swtpm
*self
, uint32_t nvindex
, uint32_t nvindexattrs
,
441 const unsigned char *data
, size_t data_len
, gboolean lock_nvram
,
442 const char *purpose
);
444 /* Given a hash algo identifier, return the name of the hash bank */
445 static const char *get_name_for_bank(uint16_t hashAlg
) {
448 for (i
= 0; banks_to_names
[i
].name
; i
++) {
449 if (banks_to_names
[i
].hashAlg
== hashAlg
)
450 return banks_to_names
[i
].name
;
455 /* Give the name of a hash bank, return its algo identifer */
456 static uint16_t get_hashalg_by_bankname(const char *name
) {
459 for (i
= 0; banks_to_names
[i
].name
; i
++) {
460 if (strcmp(banks_to_names
[i
].name
, name
) == 0)
461 return banks_to_names
[i
].hashAlg
;
466 /* Do an SU_CLEAR shutdown of the TPM 2 */
467 static int swtpm_tpm2_shutdown(struct swtpm
*self
)
469 struct tpm2_shutdown_req
{
470 struct tpm_req_header hdr
;
471 uint16_t shutdownType
;
472 } __attribute__((packed
)) req
= {
473 .hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_NO_SESSIONS
, sizeof(req
), TPM2_CC_SHUTDOWN
),
474 .shutdownType
= htobe16(TPM2_SU_CLEAR
)
477 return transfer(self
, &req
, sizeof(req
), "TPM2_Shutdown", FALSE
, NULL
, NULL
);
480 /* Get all available PCR banks */
481 static int swtpm_tpm2_get_all_pcr_banks(struct swtpm
*self
, gchar
***all_pcr_banks
)
483 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_NO_SESSIONS
, 0, TPM2_CC_GETCAPABILITY
);
484 g_autofree
unsigned char *req
= NULL
;
486 unsigned char tpmresp
[256];
487 size_t tpmresp_len
= sizeof(tpmresp
);
488 uint16_t count
, bank
;
495 req_len
= memconcat(&req
,
497 (unsigned char[]){AS4BE(TPM2_CAP_PCRS
), AS4BE(0), AS4BE(64)}, (size_t)12,
500 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
503 ((struct tpm_req_header
*)req
)->size
= htobe32(req_len
);
505 ret
= transfer(self
, req
, req_len
, "TPM2_GetCapability", FALSE
, tpmresp
, &tpmresp_len
);
509 *all_pcr_banks
= NULL
;
511 if (tpmresp_len
< 17 + sizeof(count
))
513 memcpy(&count
, &tpmresp
[17], sizeof(count
));
514 count
= be16toh(count
);
516 /* unreasonable number of PCR banks ? */
518 goto err_num_pcrbanks
;
520 *all_pcr_banks
= g_malloc0(sizeof(char *) * (count
+ 1));
524 for (i
= 0; i
< count
; i
++) {
527 if (tpmresp_len
< offset
+ sizeof(bank
))
529 memcpy(&bank
, &tpmresp
[offset
], sizeof(bank
));
530 bank
= be16toh(bank
);
532 if (tpmresp_len
< offset
+ 2 + sizeof(length
))
534 length
= tpmresp
[offset
+ 2];
536 name
= get_name_for_bank(bank
);
540 n
= g_strdup_printf("%02x", bank
);
542 (*all_pcr_banks
)[i
] = n
;
544 offset
+= 2 + 1 + length
;
549 logerr(self
->logfile
, "Unreasonable number of PCR banks (%u) returned.\n", count
);
553 logerr(self
->logfile
, "Response from TPM2_GetCapability is too short!\n");
556 g_strfreev(*all_pcr_banks
);
557 *all_pcr_banks
= NULL
;
562 /* Activate all user-chosen PCR banks and deactivate all others */
563 static int swtpm_tpm2_set_active_pcr_banks(struct swtpm
*self
, gchar
**pcr_banks
,
564 gchar
**all_pcr_banks
, gchar
***active
)
566 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_SESSIONS
, 0, TPM2_CC_PCR_ALLOCATE
);
567 struct tpm2_authblock authblock
= TPM2_AUTHBLOCK_INITIALIZER(TPM2_RS_PW
, 0, 0, 0);
568 unsigned char pcrselects
[6 * 10]; // supports up to 10 PCR banks
569 ssize_t pcrselects_len
= 0;
573 g_autofree
unsigned char *req
= NULL
;
574 ssize_t req_len
, len
;
576 uint64_t activated_mask
= 0;
578 for (idx
= 0; pcr_banks
[idx
] != NULL
; idx
++)
580 *active
= g_malloc0(sizeof(char *) * (idx
+ 1));
582 for (idx
= 0; pcr_banks
[idx
] != NULL
; idx
++) {
584 // Is user-chosen pcr_banks[idx] available?
585 for (j
= 0; all_pcr_banks
[j
] != NULL
; j
++) {
586 if (strcmp(pcr_banks
[idx
], all_pcr_banks
[j
]) == 0) {
587 hashAlg
= get_hashalg_by_bankname(pcr_banks
[idx
]);
591 if (hashAlg
!= 0 && (activated_mask
& ((uint64_t)1 << j
)) == 0) {
592 (*active
)[count
] = g_strdup(pcr_banks
[idx
]);
593 len
= concat(&pcrselects
[pcrselects_len
], sizeof(pcrselects
) - pcrselects_len
,
594 (unsigned char[]){AS2BE(hashAlg
), 3, 0xff, 0xff, 0xff} , (size_t)6,
597 logerr(self
->logfile
, "Internal error in %s: pcrselects is too small\n", __func__
);
600 pcrselects_len
+= len
;
602 activated_mask
|= ((uint64_t)1 << j
);
607 logerr(self
->logfile
,
608 "No PCR banks could be allocated. None of the selected algorithms are supported.\n");
612 // disable all the other ones not chosen by the user
613 for (idx
= 0; all_pcr_banks
[idx
] != NULL
; idx
++) {
614 gboolean found
= FALSE
;
616 for (j
= 0; pcr_banks
[j
] != NULL
; j
++) {
617 if (strcmp(pcr_banks
[j
], all_pcr_banks
[idx
]) == 0) {
625 /* not found, so not chosen by user */
626 hashAlg
= get_hashalg_by_bankname(all_pcr_banks
[idx
]);
628 len
= concat(&pcrselects
[pcrselects_len
], sizeof(pcrselects
) - pcrselects_len
,
629 (unsigned char[]){AS2BE(hashAlg
), 3, 0, 0, 0}, (size_t)6,
632 logerr(self
->logfile
, "Internal error in %s: pcrselects is too small\n", __func__
);
635 pcrselects_len
+= len
;
639 req_len
= memconcat(&req
,
642 AS4BE(TPM2_RH_PLATFORM
), AS4BE(sizeof(authblock
))
644 &authblock
, sizeof(authblock
),
645 (unsigned char[]){AS4BE(count
)}, (size_t)4,
646 pcrselects
, pcrselects_len
,
649 logerr(self
->logfile
, "Internal error in %s: req is too small\n", __func__
);
652 ((struct tpm_req_header
*)req
)->size
= htobe32(req_len
);
654 ret
= transfer(self
, req
, req_len
, "TPM2_PCR_Allocate", FALSE
, NULL
, 0);
667 /* Make object at the curr_handler permanent with the perm_handle */
668 static int swtpm_tpm2_evictcontrol(struct swtpm
*self
, uint32_t curr_handle
, uint32_t perm_handle
)
670 struct tpm2_evictcontrol_req
{
671 struct tpm_req_header hdr
;
673 uint32_t objectHandle
;
674 uint32_t authblockLen
;
675 struct tpm2_authblock authblock
;
676 uint32_t persistentHandle
;
677 } __attribute__((packed
)) req
= {
678 .hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_SESSIONS
, sizeof(req
), TPM2_CC_EVICTCONTROL
),
679 .auth
= htobe32(TPM2_RH_OWNER
),
680 .objectHandle
= htobe32(curr_handle
),
681 .authblockLen
= htobe32(sizeof(req
.authblock
)),
682 .authblock
= TPM2_AUTHBLOCK_INITIALIZER(TPM2_RS_PW
, 0, 0, 0),
683 .persistentHandle
= htobe32(perm_handle
),
686 return transfer(self
, &req
, sizeof(req
), "TPM2_EvictControl", FALSE
, NULL
, 0);
689 /* Create an RSA EK */
690 static int swtpm_tpm2_createprimary_ek_rsa(struct swtpm
*self
, unsigned int rsa_keysize
,
691 gboolean allowsigning
, gboolean decryption
,
692 uint32_t *curr_handle
,
693 unsigned char *ektemplate
, size_t *ektemplate_len
,
694 gchar
**ekparam
, const gchar
**key_description
)
696 unsigned char authpolicy
[48];
697 size_t authpolicy_len
;
698 unsigned char symkeydata
[6];
699 size_t symkeydata_len
;
700 unsigned int keyflags
;
701 unsigned int symkeylen
;
705 if (rsa_keysize
== 2048) {
707 memcpy(authpolicy
, ((unsigned char []){
708 0x83, 0x71, 0x97, 0x67, 0x44, 0x84, 0xb3, 0xf8, 0x1a, 0x90, 0xcc, 0x8d,
709 0x46, 0xa5, 0xd7, 0x24, 0xfd, 0x52, 0xd7, 0x6e, 0x06, 0x52, 0x0b, 0x64,
710 0xf2, 0xa1, 0xda, 0x1b, 0x33, 0x14, 0x69, 0xaa
716 } else if (rsa_keysize
== 3072) {
718 memcpy(authpolicy
, ((unsigned char []){
719 0xB2, 0x6E, 0x7D, 0x28, 0xD1, 0x1A, 0x50, 0xBC, 0x53, 0xD8, 0x82, 0xBC,
720 0xF5, 0xFD, 0x3A, 0x1A, 0x07, 0x41, 0x48, 0xBB, 0x35, 0xD3, 0xB4, 0xE4,
721 0xCB, 0x1C, 0x0A, 0xD9, 0xBD, 0xE4, 0x19, 0xCA, 0xCB, 0x47, 0xBA, 0x09,
722 0x69, 0x96, 0x46, 0x15, 0x0F, 0x9F, 0xC0, 0x00, 0xF3, 0xF8, 0x0E, 0x12
729 logerr(self
->logfile
, "Internal error in %s: unsupported RSA keysize %d.\n",
730 __func__
, rsa_keysize
);
734 if (allowsigning
&& decryption
) {
735 // keyflags: fixedTPM, fixedParent, sensitiveDatOrigin,
736 // adminWithPolicy, sign, decrypt
737 keyflags
|= 0x000600b2;
738 // symmetric: TPM_ALG_NULL
740 memcpy(symkeydata
, ((unsigned char[]) {AS2BE(TPM2_ALG_NULL
)}), symkeydata_len
);
742 } else if (allowsigning
) {
743 // keyflags: fixedTPM, fixedParent, sensitiveDatOrigin,
744 // adminWithPolicy, sign
745 keyflags
|= 0x000400b2;
746 // symmetric: TPM_ALG_NULL
748 memcpy(symkeydata
, ((unsigned char[]) {AS2BE(TPM2_ALG_NULL
)}), symkeydata_len
);
751 // keyflags: fixedTPM, fixedParent, sensitiveDatOrigin,
752 // adminWithPolicy, restricted, decrypt
753 keyflags
|= 0x000300b2;
754 // symmetric: TPM_ALG_AES, 128bit or 256bit, TPM_ALG_CFB
757 ((unsigned char[]) {AS2BE(TPM2_ALG_AES
), AS2BE(symkeylen
), AS2BE(TPM2_ALG_CFB
)}),
762 return swtpm_tpm2_createprimary_rsa(self
, TPM2_RH_ENDORSEMENT
, keyflags
,
763 symkeydata
, symkeydata_len
,
764 authpolicy
, authpolicy_len
, rsa_keysize
,
765 havenonce
, off
, curr_handle
,
766 ektemplate
, ektemplate_len
, ekparam
, key_description
);
769 /* Create an RSA key with the given parameters */
770 static int swtpm_tpm2_createprimary_rsa(struct swtpm
*self
, uint32_t primaryhandle
, unsigned int keyflags
,
771 const unsigned char *symkeydata
, size_t symkeydata_len
,
772 const unsigned char *authpolicy
, size_t authpolicy_len
,
773 unsigned int rsa_keysize
, gboolean havenonce
, size_t off
,
774 uint32_t *curr_handle
,
775 unsigned char *ektemplate
, size_t *ektemplate_len
,
776 gchar
**ekparam
, const gchar
**key_description
)
778 const unsigned char *nonce
;
781 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_SESSIONS
, 0, TPM2_CC_CREATEPRIMARY
);
782 struct tpm2_authblock authblock
= TPM2_AUTHBLOCK_INITIALIZER(TPM2_RS_PW
, 0, 0, 0);
783 g_autofree
unsigned char *public = NULL
;
785 g_autofree
unsigned char *createprimary
= NULL
;
786 ssize_t createprimary_len
;
788 unsigned char tpmresp
[2048];
789 size_t tpmresp_len
= sizeof(tpmresp
);
792 if (rsa_keysize
== 2048) {
793 nonce
= NONCE_RSA2048
;
794 nonce_len
= sizeof(NONCE_RSA2048
);
795 hashalg
= TPM2_ALG_SHA256
;
797 *key_description
= "rsa2048";
798 } else if (rsa_keysize
== 3072) {
801 nonce_len
= sizeof(NONCE_EMPTY
);
803 nonce
= NONCE_RSA3072
;
804 nonce_len
= sizeof(NONCE_RSA3072
);
806 hashalg
= TPM2_ALG_SHA384
;
808 *key_description
= "rsa3072";
810 logerr(self
->logfile
, "Internal error in %s: unsupported RSA keysize %d.\n",
811 __func__
, rsa_keysize
);
818 AS2BE(TPM2_ALG_RSA
), AS2BE(hashalg
),
819 AS4BE(keyflags
), AS2BE(authpolicy_len
)
821 authpolicy
, authpolicy_len
,
822 symkeydata
, symkeydata_len
,
824 AS2BE(TPM2_ALG_NULL
), AS2BE(rsa_keysize
), AS4BE(0)
828 if (public_len
< 0) {
829 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
833 if (*ektemplate_len
< (size_t)public_len
) {
834 logerr(self
->logfile
, "Internal error in %s: Need %zu bytes for ektemplate (rsa) but got only %zu\n",
835 __func__
, public_len
, *ektemplate_len
);
838 memcpy(ektemplate
, public, public_len
);
839 *ektemplate_len
= public_len
;
843 memconcat(&createprimary
,
845 (unsigned char[]) {AS4BE(primaryhandle
), AS4BE(sizeof(authblock
))}, (size_t)8,
846 &authblock
, sizeof(authblock
),
847 (unsigned char[]) {AS2BE(4), AS4BE(0), AS2BE(public_len
)}, (size_t)8,
849 (unsigned char[]) {AS4BE(0), AS2BE(0)}, (size_t)6,
851 if (createprimary_len
< 0) {
852 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
855 ((struct tpm_req_header
*)createprimary
)->size
= htobe32(createprimary_len
);
857 ret
= transfer(self
, createprimary
, createprimary_len
, "TPM2_CreatePrimary(RSA)", FALSE
,
858 tpmresp
, &tpmresp_len
);
863 if (tpmresp_len
< 10 + sizeof(*curr_handle
))
865 memcpy(curr_handle
, &tpmresp
[10], sizeof(*curr_handle
));
866 *curr_handle
= be32toh(*curr_handle
);
869 if (tpmresp_len
< off
+ sizeof(modlen
))
871 memcpy(&modlen
, &tpmresp
[off
], sizeof(modlen
));
872 modlen
= be16toh(modlen
);
873 if (modlen
!= rsa_keysize
>> 3) {
874 logerr(self
->logfile
, "Internal error in %s: Getting modulus from wrong offset %zu\n",
879 if (tpmresp_len
< off
+ 2 + modlen
)
881 *ekparam
= print_as_hex(&tpmresp
[off
+ 2], modlen
);
887 logerr(self
->logfile
, "Response from TPM2_CreatePrimary(RSA) is too short!\n");
891 /* Create an ECC key with the given parameters */
892 static int swtpm_tpm2_createprimary_ecc(struct swtpm
*self
, uint32_t primaryhandle
, unsigned int keyflags
,
893 const unsigned char *symkeydata
, size_t symkeydata_len
,
894 const unsigned char *authpolicy
, size_t authpolicy_len
,
895 unsigned short curveid
, unsigned short hashalg
,
896 const unsigned char *nonce
, size_t nonce_len
,
897 size_t off
, uint32_t *curr_handle
,
898 unsigned char *ektemplate
, size_t *ektemplate_len
,
899 gchar
**ekparam
, const gchar
**key_description
)
901 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_SESSIONS
, 0, TPM2_CC_CREATEPRIMARY
);
902 struct tpm2_authblock authblock
= TPM2_AUTHBLOCK_INITIALIZER(TPM2_RS_PW
, 0, 0, 0);
903 g_autofree
unsigned char *public = NULL
;
905 g_autofree
unsigned char *createprimary
= NULL
;
906 ssize_t createprimary_len
;
908 unsigned char tpmresp
[2048];
909 size_t tpmresp_len
= sizeof(tpmresp
);
911 uint16_t exp_ksize
, ksize1
, ksize2
;
917 AS2BE(TPM2_ALG_ECC
), AS2BE(hashalg
), AS4BE(keyflags
), AS2BE(authpolicy_len
)
919 authpolicy
, authpolicy_len
,
920 symkeydata
, symkeydata_len
,
921 (unsigned char[]) {AS2BE(TPM2_ALG_NULL
), AS2BE(curveid
), AS2BE(TPM2_ALG_NULL
)}, (size_t)6,
925 if (public_len
< 0) {
926 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
930 if (*ektemplate_len
< (size_t)public_len
) {
931 logerr(self
->logfile
, "Internal error: Need %zu bytes for ektemplate (ecc) but got only %zu\n",
932 public_len
, ektemplate_len
);
935 memcpy(ektemplate
, public, public_len
);
936 *ektemplate_len
= public_len
;
940 memconcat(&createprimary
,
942 (unsigned char[]) {AS4BE(primaryhandle
), AS4BE(sizeof(authblock
))}, (size_t)8,
943 &authblock
, sizeof(authblock
),
944 (unsigned char[]) {AS2BE(4), AS4BE(0), AS2BE(public_len
)}, (size_t)8,
946 (unsigned char[]) {AS4BE(0), AS2BE(0)}, (size_t)6,
948 if (createprimary_len
< 0) {
949 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
952 ((struct tpm_req_header
*)createprimary
)->size
= htobe32(createprimary_len
);
954 ret
= transfer(self
, createprimary
, createprimary_len
, "TPM2_CreatePrimary(ECC)", FALSE
,
955 tpmresp
, &tpmresp_len
);
959 if (tpmresp_len
< 10 + sizeof(*curr_handle
))
961 memcpy(curr_handle
, &tpmresp
[10], sizeof(*curr_handle
));
962 *curr_handle
= be32toh(*curr_handle
);
965 if (curveid
== TPM2_ECC_NIST_P384
) {
969 *key_description
= cid
;
971 logerr(self
->logfile
, "Unknown curveid 0x%x\n", curveid
);
975 if (tpmresp_len
< off
+ sizeof(ksize1
))
977 memcpy(&ksize1
, &tpmresp
[off
], sizeof(ksize1
));
978 ksize1
= be16toh(ksize1
);
979 off2
= off
+ 2 + ksize1
;
981 if (tpmresp_len
< off2
+ sizeof(ksize2
))
983 memcpy(&ksize2
, &tpmresp
[off2
], sizeof(ksize2
));
984 ksize2
= be16toh(ksize2
);
986 if (ksize1
!= exp_ksize
|| ksize2
!= exp_ksize
) {
987 logerr(self
->logfile
, "ECC: Getting key parameters from wrong offset\n");
992 unsigned char *xparam
= &tpmresp
[off
+ 2];
993 unsigned char *yparam
= &tpmresp
[off2
+ 2];
994 if (tpmresp_len
< off
+ 2 + ksize1
|| tpmresp_len
< off2
+ 2 + ksize2
)
996 g_autofree gchar
*xparam_str
= print_as_hex(xparam
, ksize1
);
997 g_autofree gchar
*yparam_str
= print_as_hex(yparam
, ksize2
);
999 *ekparam
= g_strdup_printf("x=%s,y=%s,id=%s", xparam_str
, yparam_str
, cid
);
1005 logerr(self
->logfile
, "Response from TPM2_CreatePrimary(ECC) is too short!\n");
1009 static int swtpm_tpm2_createprimary_spk_ecc_nist_p384(struct swtpm
*self
,
1010 uint32_t *curr_handle
)
1012 unsigned int keyflags
= 0x00030472;
1013 const unsigned char authpolicy
[0];
1014 size_t authpolicy_len
= sizeof(authpolicy
);
1015 const unsigned char symkeydata
[] = {AS2BE(TPM2_ALG_AES
), AS2BE(256), AS2BE(TPM2_ALG_CFB
)};
1016 size_t symkeydata_len
= sizeof(symkeydata
);
1019 return swtpm_tpm2_createprimary_ecc(self
, TPM2_RH_OWNER
, keyflags
, symkeydata
, symkeydata_len
,
1020 authpolicy
, authpolicy_len
, TPM2_ECC_NIST_P384
, TPM2_ALG_SHA384
,
1021 NONCE_ECC_384
, sizeof(NONCE_ECC_384
), off
, curr_handle
,
1022 NULL
, 0, NULL
, NULL
);
1025 static int swtpm_tpm2_createprimary_spk_rsa(struct swtpm
*self
, unsigned int rsa_keysize
,
1026 uint32_t *curr_handle
)
1028 unsigned int keyflags
= 0x00030472;
1029 const unsigned char authpolicy
[0];
1030 size_t authpolicy_len
= sizeof(authpolicy
);
1031 unsigned short symkeylen
= 0;
1032 unsigned char symkeydata
[6];
1033 size_t symkeydata_len
;
1036 if (rsa_keysize
== 2048)
1038 else if (rsa_keysize
== 3072)
1043 ((unsigned char[]) {AS2BE(TPM2_ALG_AES
), AS2BE(symkeylen
), AS2BE(TPM2_ALG_CFB
)}),
1046 return swtpm_tpm2_createprimary_rsa(self
, TPM2_RH_OWNER
, keyflags
,
1047 symkeydata
, symkeydata_len
,
1048 authpolicy
, authpolicy_len
, rsa_keysize
, TRUE
,
1049 off
, curr_handle
, NULL
, 0, NULL
, NULL
);
1052 /* Create either an ECC or RSA storage primary key */
1053 static int swtpm_tpm2_create_spk(struct swtpm
*self
, gboolean isecc
, unsigned int rsa_keysize
)
1056 uint32_t curr_handle
;
1059 ret
= swtpm_tpm2_createprimary_spk_ecc_nist_p384(self
, &curr_handle
);
1061 ret
= swtpm_tpm2_createprimary_spk_rsa(self
, rsa_keysize
, &curr_handle
);
1066 ret
= swtpm_tpm2_evictcontrol(self
, curr_handle
, TPM2_SPK_HANDLE
);
1068 logit(self
->logfile
,
1069 "Successfully created storage primary key with handle 0x%x.\n", TPM2_SPK_HANDLE
);
1074 /* Create an ECC EK key that may be allowed to sign and/or decrypt */
1075 static int swtpm_tpm2_createprimary_ek_ecc_nist_p384(struct swtpm
*self
, gboolean allowsigning
,
1076 gboolean decryption
, uint32_t *curr_handle
,
1077 unsigned char *ektemplate
, size_t *ektemplate_len
,
1078 gchar
**ekparam
, const char **key_description
)
1080 unsigned char authpolicy
[48]= {
1081 0xB2, 0x6E, 0x7D, 0x28, 0xD1, 0x1A, 0x50, 0xBC, 0x53, 0xD8, 0x82, 0xBC,
1082 0xF5, 0xFD, 0x3A, 0x1A, 0x07, 0x41, 0x48, 0xBB, 0x35, 0xD3, 0xB4, 0xE4,
1083 0xCB, 0x1C, 0x0A, 0xD9, 0xBD, 0xE4, 0x19, 0xCA, 0xCB, 0x47, 0xBA, 0x09,
1084 0x69, 0x96, 0x46, 0x15, 0x0F, 0x9F, 0xC0, 0x00, 0xF3, 0xF8, 0x0E, 0x12
1086 size_t authpolicy_len
= 48;
1087 unsigned char symkeydata
[6];
1088 size_t symkeydata_len
;
1089 unsigned int keyflags
;
1093 if (allowsigning
&& decryption
) {
1094 // keyflags: fixedTPM, fixedParent, sensitiveDatOrigin,
1095 // userWithAuth, adminWithPolicy, sign, decrypt
1096 keyflags
= 0x000600f2;
1097 // symmetric: TPM_ALG_NULL
1099 memcpy(symkeydata
, ((unsigned char[]){AS2BE(TPM2_ALG_NULL
)}), symkeydata_len
);
1101 } else if (allowsigning
) {
1102 // keyflags: fixedTPM, fixedParent, sensitiveDatOrigin,
1103 // userWithAuth, adminWithPolicy, sign
1104 keyflags
= 0x000400f2;
1105 // symmetric: TPM_ALG_NULL
1107 memcpy(symkeydata
, ((unsigned char[]){AS2BE(TPM2_ALG_NULL
)}), symkeydata_len
);
1110 // keyflags: fixedTPM, fixedParent, sensitiveDatOrigin,
1111 // userWithAuth, adminWithPolicy, restricted, decrypt
1112 keyflags
= 0x000300f2;
1113 // symmetric: TPM_ALG_AES, 256bit, TPM_ALG_CFB
1116 ((unsigned char[]){ AS2BE(TPM2_ALG_AES
), AS2BE(256), AS2BE(TPM2_ALG_CFB
)}),
1121 ret
= swtpm_tpm2_createprimary_ecc(self
, TPM2_RH_ENDORSEMENT
, keyflags
, symkeydata
, symkeydata_len
,
1122 authpolicy
, authpolicy_len
, TPM2_ECC_NIST_P384
, TPM2_ALG_SHA384
,
1123 NONCE_EMPTY
, sizeof(NONCE_EMPTY
), off
, curr_handle
,
1124 ektemplate
, ektemplate_len
, ekparam
, key_description
);
1126 logerr(self
->logfile
, "%s failed\n", __func__
);
1131 /* Create an ECC or RSA EK */
1132 static int swtpm_tpm2_create_ek(struct swtpm
*self
, gboolean isecc
, unsigned int rsa_keysize
,
1133 gboolean allowsigning
, gboolean decryption
, gboolean lock_nvram
,
1134 gchar
**ekparam
, const gchar
**key_description
)
1136 uint32_t tpm2_ek_handle
, nvindex
, curr_handle
;
1137 const char *keytype
;
1139 unsigned char ektemplate
[512];
1140 size_t ektemplate_len
= sizeof(ektemplate
);
1143 tpm2_ek_handle
= TPM2_EK_ECC_SECP384R1_HANDLE
;
1145 nvindex
= TPM2_NV_INDEX_ECC_SECP384R1_HI_EKTEMPLATE
;
1147 if (rsa_keysize
== 2048) {
1148 tpm2_ek_handle
= TPM2_EK_RSA_HANDLE
;
1149 keytype
= "RSA 2048";
1150 nvindex
= TPM2_NV_INDEX_RSA2048_EKTEMPLATE
;
1151 } else if (rsa_keysize
== 3072) {
1152 tpm2_ek_handle
= TPM2_EK_RSA3072_HANDLE
;
1153 keytype
= "RSA 3072";
1154 nvindex
= TPM2_NV_INDEX_RSA3072_HI_EKTEMPLATE
;
1156 logerr(self
->logfile
, "Internal error: Unsupported RSA keysize %u.\n", rsa_keysize
);
1161 ret
= swtpm_tpm2_createprimary_ek_ecc_nist_p384(self
, allowsigning
, decryption
, &curr_handle
,
1162 ektemplate
, &ektemplate_len
, ekparam
,
1165 ret
= swtpm_tpm2_createprimary_ek_rsa(self
, rsa_keysize
, allowsigning
, decryption
, &curr_handle
,
1166 ektemplate
, &ektemplate_len
, ekparam
, key_description
);
1169 ret
= swtpm_tpm2_evictcontrol(self
, curr_handle
, tpm2_ek_handle
);
1171 logerr(self
->logfile
, "create_ek failed: 0x%x\n", ret
);
1175 logit(self
->logfile
,
1176 "Successfully created %s EK with handle 0x%x.\n", keytype
, tpm2_ek_handle
);
1179 uint32_t nvindexattrs
= TPMA_NV_PLATFORMCREATE
| \
1180 TPMA_NV_AUTHREAD
| \
1181 TPMA_NV_OWNERREAD
| \
1185 TPMA_NV_WRITEDEFINE
;
1186 ret
= swtpm_tpm2_write_nvram(self
, nvindex
, nvindexattrs
, ektemplate
, ektemplate_len
,
1187 lock_nvram
, "EK template");
1189 logit(self
->logfile
,
1190 "Successfully created NVRAM area 0x%x for %s EK template.\n",
1197 static int swtpm_tpm2_nvdefinespace(struct swtpm
*self
, uint32_t nvindex
, uint32_t nvindexattrs
,
1200 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_SESSIONS
, 0, TPM2_CC_NV_DEFINESPACE
);
1201 struct tpm2_authblock authblock
= TPM2_AUTHBLOCK_INITIALIZER(TPM2_RS_PW
, 0, 0, 0);
1202 g_autofree
unsigned char *nvpublic
= NULL
;
1203 ssize_t nvpublic_len
;
1204 g_autofree
unsigned char *req
= NULL
;
1207 nvpublic_len
= memconcat(&nvpublic
,
1209 AS4BE(nvindex
), AS2BE(TPM2_ALG_SHA256
), AS4BE(nvindexattrs
),
1210 AS2BE(0), AS2BE(data_len
)}, (size_t)14,
1212 if (nvpublic_len
< 0) {
1213 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
1217 req_len
= memconcat(&req
,
1219 (unsigned char[]){AS4BE(TPM2_RH_PLATFORM
), AS4BE(sizeof(authblock
))}, (size_t)8,
1220 &authblock
, sizeof(authblock
),
1221 (unsigned char[]){AS2BE(0), AS2BE(nvpublic_len
)}, (size_t)4,
1222 nvpublic
, nvpublic_len
,
1225 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
1229 ((struct tpm_req_header
*)req
)->size
= htobe32(req_len
);
1231 return transfer(self
, req
, req_len
, "TPM2_NV_DefineSpace", FALSE
, NULL
, 0);
1234 /* Write the data into the given NVIndex */
1235 static int swtpm_tpm2_nv_write(struct swtpm
*self
, uint32_t nvindex
,
1236 const unsigned char *data
, size_t data_len
)
1238 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_SESSIONS
, 0, TPM2_CC_NV_WRITE
);
1239 struct tpm2_authblock authblock
= TPM2_AUTHBLOCK_INITIALIZER(TPM2_RS_PW
, 0, 0, 0);
1240 g_autofree
unsigned char *req
= NULL
;
1242 size_t offset
= 0, txlen
;
1245 while (offset
< data_len
) {
1246 txlen
= min(data_len
- offset
, 1024);
1249 req_len
= memconcat(&req
,
1252 AS4BE(TPM2_RH_PLATFORM
), AS4BE(nvindex
), AS4BE(sizeof(authblock
))
1254 &authblock
, sizeof(authblock
),
1255 (unsigned char[]){AS2BE(txlen
)}, (size_t)2,
1256 &data
[offset
], txlen
,
1257 (unsigned char[]){AS2BE(offset
)}, (size_t)2,
1260 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
1263 ((struct tpm_req_header
*)req
)->size
= htobe32(req_len
);
1265 ret
= transfer(self
, req
, req_len
, "TPM2_NV_Write", FALSE
, NULL
, 0);
1274 static int swtpm_tpm2_nv_writelock(struct swtpm
*self
, uint32_t nvindex
)
1276 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM2_ST_SESSIONS
, 0, TPM2_CC_NV_WRITELOCK
);
1277 struct tpm2_authblock authblock
= TPM2_AUTHBLOCK_INITIALIZER(TPM2_RS_PW
, 0, 0, 0);
1278 g_autofree
unsigned char *req
;
1281 req_len
= memconcat(&req
,
1284 AS4BE(TPM2_RH_PLATFORM
), AS4BE(nvindex
), AS4BE(sizeof(authblock
))
1286 &authblock
, sizeof(authblock
),
1289 logerr(self
->logfile
, "Internal error in %s: memconcat failed\n", __func__
);
1293 ((struct tpm_req_header
*)req
)->size
= htobe32(req_len
);
1295 return transfer(self
, req
, req_len
, "TPM2_NV_WriteLock", FALSE
, NULL
, 0);
1298 static int swtpm_tpm2_write_nvram(struct swtpm
*self
, uint32_t nvindex
, uint32_t nvindexattrs
,
1299 const unsigned char *data
, size_t data_len
, gboolean lock_nvram
,
1300 const char *purpose
)
1302 int ret
= swtpm_tpm2_nvdefinespace(self
, nvindex
, nvindexattrs
, data_len
);
1304 logerr(self
->logfile
, "Could not create NVRAM area 0x%x for %s.\n", nvindex
, purpose
);
1308 ret
= swtpm_tpm2_nv_write(self
, nvindex
, data
, data_len
);
1310 logerr(self
->logfile
,
1311 "Could not write %s into NVRAM area 0x%x.\n", purpose
, nvindex
);
1316 ret
= swtpm_tpm2_nv_writelock(self
, nvindex
);
1318 logerr(self
->logfile
, "Could not lock EK template NVRAM area 0x%x.\n", nvindex
);
1326 /* Write the platform certificate into an NVRAM area */
1327 static int swtpm_tpm2_write_ek_cert_nvram(struct swtpm
*self
, gboolean isecc
,
1328 unsigned int rsa_keysize
, gboolean lock_nvram
,
1329 const unsigned char *data
, size_t data_len
)
1331 uint32_t nvindex
= 0;
1332 g_autofree gchar
*keytype
= NULL
;
1333 uint32_t nvindexattrs
= TPMA_NV_PLATFORMCREATE
|
1339 TPMA_NV_WRITEDEFINE
;
1343 if (rsa_keysize
== 2048)
1344 nvindex
= TPM2_NV_INDEX_RSA2048_EKCERT
;
1345 else if (rsa_keysize
== 3072)
1346 nvindex
= TPM2_NV_INDEX_RSA3072_HI_EKCERT
;
1347 keytype
= g_strdup_printf("RSA %d", rsa_keysize
);
1349 nvindex
= TPM2_NV_INDEX_ECC_SECP384R1_HI_EKCERT
;
1350 keytype
= g_strdup("ECC");
1353 ret
= swtpm_tpm2_write_nvram(self
, nvindex
, nvindexattrs
, data
, data_len
, lock_nvram
,
1356 logit(self
->logfile
,
1357 "Successfully created NVRAM area 0x%x for %s EK certificate.\n",
1360 logerr(self
->logfile
,
1361 "Could not create NVRAM area 0x%x for %s EK certificate.\n",
1366 static int swtpm_tpm2_write_platform_cert_nvram(struct swtpm
*self
, gboolean lock_nvram
,
1367 const unsigned char *data
, size_t data_len
)
1369 uint32_t nvindex
= TPM2_NV_INDEX_PLATFORMCERT
;
1370 uint32_t nvindexattrs
= TPMA_NV_PLATFORMCREATE
|
1376 TPMA_NV_WRITEDEFINE
;
1379 ret
= swtpm_tpm2_write_nvram(self
, nvindex
, nvindexattrs
, data
, data_len
, lock_nvram
,
1380 "Platform Certificate");
1382 logit(self
->logfile
,
1383 "Successfully created NVRAM area 0x%x for platform certificate.\n", nvindex
);
1385 logerr(self
->logfile
,
1386 "Could not create NVRAM area 0x%x for platform certificate.\n", nvindex
);
1391 static const struct swtpm2_ops swtpm_tpm2_ops
= {
1392 .shutdown
= swtpm_tpm2_shutdown
,
1393 .create_spk
= swtpm_tpm2_create_spk
,
1394 .create_ek
= swtpm_tpm2_create_ek
,
1395 .get_all_pcr_banks
= swtpm_tpm2_get_all_pcr_banks
,
1396 .set_active_pcr_banks
= swtpm_tpm2_set_active_pcr_banks
,
1397 .write_ek_cert_nvram
= swtpm_tpm2_write_ek_cert_nvram
,
1398 .write_platform_cert_nvram
= swtpm_tpm2_write_platform_cert_nvram
,
1404 #define TPM_TAG_RQU_COMMAND 0x00c1
1405 #define TPM_TAG_RQU_AUTH1_COMMAND 0x00c2
1407 #define TPM_ORD_OIAP 0x0000000A
1408 #define TPM_ORD_TAKE_OWNERSHIP 0x0000000D
1409 #define TPM_ORD_PHYSICAL_ENABLE 0x0000006F
1410 #define TPM_ORD_PHYSICAL_SET_DEACTIVATED 0x00000072
1411 #define TPM_ORD_NV_DEFINE_SPACE 0x000000CC
1412 #define TPM_ORD_NV_WRITE_VALUE 0x000000CD
1413 #define TSC_ORD_PHYSICAL_PRESENCE 0x4000000A
1415 #define TPM_ST_CLEAR 0x0001
1417 #define TPM_PHYSICAL_PRESENCE_CMD_ENABLE 0x0020
1418 #define TPM_PHYSICAL_PRESENCE_PRESENT 0x0008
1420 #define TPM_ALG_RSA 0x00000001
1422 #define TPM_KEY_STORAGE 0x0011
1424 #define TPM_AUTH_ALWAYS 0x01
1426 #define TPM_PID_OWNER 0x0005
1428 #define TPM_ES_RSAESOAEP_SHA1_MGF1 0x0003
1429 #define TPM_SS_NONE 0x0001
1431 #define TPM_TAG_PCR_INFO_LONG 0x0006
1432 #define TPM_TAG_NV_ATTRIBUTES 0x0017
1433 #define TPM_TAG_NV_DATA_PUBLIC 0x0018
1434 #define TPM_TAG_KEY12 0x0028
1436 #define TPM_LOC_ZERO 0x01
1437 #define TPM_LOC_ALL 0x1f
1439 #define TPM_NV_INDEX_D_BIT 0x10000000
1440 #define TPM_NV_INDEX_EKCERT 0xF000
1441 #define TPM_NV_INDEX_PLATFORMCERT 0xF002
1443 #define TPM_NV_INDEX_LOCK 0xFFFFFFFF
1445 #define TPM_NV_PER_OWNERREAD 0x00020000
1446 #define TPM_NV_PER_OWNERWRITE 0x00000002
1448 #define TPM_ET_OWNER 0x02
1449 #define TPM_ET_NV 0x0b
1451 #define TPM_KH_EK 0x40000006
1454 static int swtpm_tpm12_tsc_physicalpresence(struct swtpm
*self
, uint16_t physicalpresence
)
1456 struct tpm12_tsc_physicalpresence
{
1457 struct tpm_req_header hdr
;
1460 .hdr
= TPM_REQ_HEADER_INITIALIZER(TPM_TAG_RQU_COMMAND
, sizeof(req
), TSC_ORD_PHYSICAL_PRESENCE
),
1461 .pp
= htobe16(physicalpresence
),
1464 return transfer(self
, &req
, sizeof(req
), "TSC_PhysicalPresence", FALSE
, NULL
, NULL
);
1467 static int swtpm_tpm12_physical_enable(struct swtpm
*self
)
1469 struct tpm_req_header req
= TPM_REQ_HEADER_INITIALIZER(TPM_TAG_RQU_COMMAND
, sizeof(req
), TPM_ORD_PHYSICAL_ENABLE
);
1471 return transfer(self
, &req
, sizeof(req
), "TPM_PhysicalEnable", FALSE
, NULL
, NULL
);
1474 static int swtpm_tpm12_physical_set_deactivated(struct swtpm
*self
, uint8_t state
)
1476 struct tpm12_tsc_physical_set_deactivated
{
1477 struct tpm_req_header hdr
;
1480 .hdr
= TPM_REQ_HEADER_INITIALIZER(TPM_TAG_RQU_COMMAND
, sizeof(req
), TPM_ORD_PHYSICAL_SET_DEACTIVATED
),
1484 return transfer(self
, &req
, sizeof(req
), "TSC_PhysicalSetDeactivated", FALSE
, NULL
, NULL
);
1487 /* Initialize the TPM1.2 */
1488 static int swtpm_tpm12_run_swtpm_bios(struct swtpm
*self
)
1490 if (swtpm_tpm12_tsc_physicalpresence(self
, TPM_PHYSICAL_PRESENCE_CMD_ENABLE
) ||
1491 swtpm_tpm12_tsc_physicalpresence(self
, TPM_PHYSICAL_PRESENCE_PRESENT
) ||
1492 swtpm_tpm12_physical_enable(self
) ||
1493 swtpm_tpm12_physical_set_deactivated(self
, 0))
1499 static int swptm_tpm12_create_endorsement_keypair(struct swtpm
*self
,
1500 gchar
**pubek
, size_t *pubek_len
)
1502 unsigned char req
[] = {
1503 0x00, 0xc1, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, 0x78, 0x38, 0xf0, 0x30, 0x81, 0x07, 0x2b,
1504 0x0c, 0xa9, 0x10, 0x98, 0x08, 0xc0, 0x4B, 0x05, 0x11, 0xc9, 0x50, 0x23, 0x52, 0xc4, 0x00, 0x00,
1505 0x00, 0x01, 0x00, 0x03, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
1506 0x00, 0x02, 0x00, 0x00, 0x00, 0x00
1508 unsigned char tpmresp
[512];
1509 size_t tpmresp_len
= sizeof(tpmresp
);
1513 ret
= transfer(self
, &req
, sizeof(req
), "TPM_CreateEndorsementKeyPair", FALSE
, &tpmresp
, &tpmresp_len
);
1517 if (tpmresp_len
< 34 + sizeof(length
))
1519 memcpy(&length
, &tpmresp
[34], sizeof(length
));
1520 length
= be32toh(length
);
1521 if (length
!= 256) {
1522 logerr(self
->logfile
, "Offset to EK Public key is wrong.\n");
1527 if (tpmresp_len
< 38 + *pubek_len
)
1529 *pubek
= g_malloc(256);
1530 memcpy(*pubek
, &tpmresp
[38], *pubek_len
);
1535 logerr(self
->logfile
, "Response from TPM_CreateEndorsementKeyPair is too short!\n");
1539 /* Create an OIAP session */
1540 static int swtpm_tpm12_oiap(struct swtpm
*self
, uint32_t *authhandle
, unsigned char nonce_even
[SHA_DIGEST_LENGTH
])
1542 struct tpm_req_header req
= TPM_REQ_HEADER_INITIALIZER(TPM_TAG_RQU_COMMAND
, sizeof(req
), TPM_ORD_OIAP
);
1543 unsigned char tpmresp
[64];
1544 size_t tpmresp_len
= sizeof(tpmresp
);
1547 ret
= transfer(self
, &req
, sizeof(req
), "TPM_OIAP", FALSE
, &tpmresp
, &tpmresp_len
);
1551 if (tpmresp_len
< 10 + sizeof(*authhandle
) || tpmresp_len
< 14 + SHA_DIGEST_LENGTH
)
1553 memcpy(authhandle
, &tpmresp
[10], sizeof(*authhandle
));
1554 *authhandle
= be32toh(*authhandle
);
1555 memcpy(nonce_even
, &tpmresp
[14], SHA_DIGEST_LENGTH
);
1560 logerr(self
->logfile
, "Response from TPM_OIAP is too short!\n");
1564 static int swtpm_tpm12_take_ownership(struct swtpm
*self
, const unsigned char ownerpass_digest
[SHA_DIGEST_LENGTH
],
1565 const unsigned char srkpass_digest
[SHA_DIGEST_LENGTH
],
1566 const unsigned char *pubek
, size_t pubek_len
)
1568 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM_TAG_RQU_AUTH1_COMMAND
, 0, TPM_ORD_TAKE_OWNERSHIP
);
1569 EVP_PKEY
*pkey
= NULL
;
1570 EVP_PKEY_CTX
*ctx
= NULL
;
1571 BIGNUM
*exp
= BN_new();
1573 #if OPENSSL_VERSION_NUMBER < 0x30000000L
1574 RSA
*rsakey
= RSA_new();
1577 const EVP_MD
*sha1
= EVP_sha1();
1578 g_autofree
unsigned char *enc_owner_auth
= g_malloc(pubek_len
);
1579 size_t enc_owner_auth_len
= pubek_len
;
1580 g_autofree
unsigned char *enc_srk_auth
= g_malloc(pubek_len
);
1581 size_t enc_srk_auth_len
= pubek_len
;
1582 uint32_t auth_handle
;
1583 unsigned char nonce_even
[SHA_DIGEST_LENGTH
];
1584 unsigned char nonce_odd
[SHA_DIGEST_LENGTH
] = {1, 2, 3, 4, 5, 6, };
1585 g_autofree
unsigned char *tpm_rsa_key_parms
= NULL
;
1586 ssize_t tpm_rsa_key_parms_len
;
1587 g_autofree
unsigned char *tpm_key_parms
= NULL
;
1588 ssize_t tpm_key_parms_len
;
1589 g_autofree
unsigned char *tpm_key12
= NULL
;
1590 ssize_t tpm_key12_len
;
1591 g_autofree
unsigned char *in_auth_setup_params
= NULL
;
1592 ssize_t in_auth_setup_params_len
;
1593 g_autofree
unsigned char *macinput
= NULL
;
1594 ssize_t macinput_len
;
1595 unsigned char in_param_digest
[SHA_DIGEST_LENGTH
];
1596 unsigned char owner_auth
[SHA_DIGEST_LENGTH
];
1597 unsigned int owner_auth_len
= sizeof(owner_auth
);
1598 uint8_t continue_auth_session
= 0;
1599 unsigned char req
[1024];
1600 ssize_t req_len
, len
;
1601 struct tpm_req_header
*trh
;
1603 mod
= BN_bin2bn((const unsigned char *)pubek
, pubek_len
, NULL
);
1604 if (exp
== NULL
|| mod
== NULL
||
1605 BN_hex2bn(&exp
, "10001") == 0) {
1606 logerr(self
->logfile
, "Could not create public RSA key!\n");
1610 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1611 ctx
= EVP_PKEY_CTX_new_from_name(NULL
, "rsa", NULL
);
1613 OSSL_PARAM_BLD
*bld
= OSSL_PARAM_BLD_new();
1617 OSSL_PARAM_BLD_push_BN(bld
, OSSL_PKEY_PARAM_RSA_E
, exp
) != 1 ||
1618 OSSL_PARAM_BLD_push_BN(bld
, OSSL_PKEY_PARAM_RSA_N
, mod
) != 1 ||
1619 (params
= OSSL_PARAM_BLD_to_param(bld
)) == NULL
) {
1620 OSSL_PARAM_BLD_free(bld
);
1623 OSSL_PARAM_BLD_free(bld
);
1625 if (EVP_PKEY_fromdata_init(ctx
) != 1 ||
1626 EVP_PKEY_fromdata(ctx
, &pkey
, EVP_PKEY_PUBLIC_KEY
, params
) != 1) {
1627 logerr(self
->logfile
, "Could not set pkey parameters!\n");
1628 OSSL_PARAM_free(params
);
1631 OSSL_PARAM_free(params
);
1633 EVP_PKEY_CTX_free(ctx
);
1635 logerr(self
->logfile
, "Could not create key creation context!\n");
1638 ctx
= EVP_PKEY_CTX_new_from_pkey(NULL
, pkey
, NULL
);
1642 pkey
= EVP_PKEY_new();
1644 logerr(self
->logfile
, "Could not allocate pkey!\n");
1648 # if OPENSSL_VERSION_NUMBER < 0x10100000
1652 if (RSA_set0_key(rsakey
, mod
, exp
, NULL
) != 1) {
1653 logerr(self
->logfile
, "Could not create public RSA key!\n");
1657 if (EVP_PKEY_assign_RSA(pkey
, rsakey
) != 1) {
1658 logerr(self
->logfile
, "Could not create public RSA key!\n");
1659 goto error_free_pkey_and_rsa
;
1662 ctx
= EVP_PKEY_CTX_new(pkey
, NULL
);
1664 goto error_free_pkey
;
1665 #endif /* OPENSSL_VERSION_NUMBER >= 0x30000000L */
1667 if (EVP_PKEY_encrypt_init(ctx
) < 1 ||
1668 EVP_PKEY_CTX_set_rsa_padding(ctx
, RSA_PKCS1_OAEP_PADDING
) < 1 ||
1669 EVP_PKEY_CTX_set_rsa_mgf1_md(ctx
, sha1
) < 1 ||
1670 EVP_PKEY_CTX_set_rsa_oaep_md(ctx
, sha1
) < 1 ||
1671 EVP_PKEY_CTX_set0_rsa_oaep_label(ctx
, g_strdup("TCPA"), 4) < 1 ||
1672 EVP_PKEY_encrypt(ctx
, enc_owner_auth
, &enc_owner_auth_len
,
1673 ownerpass_digest
, SHA_DIGEST_LENGTH
) < 1||
1674 EVP_PKEY_encrypt(ctx
, enc_srk_auth
, &enc_srk_auth_len
,
1675 srkpass_digest
, SHA_DIGEST_LENGTH
) < 1) {
1676 logerr(self
->logfile
, "Internal error in %s: encryption failed\n", __func__
);
1679 ret
= swtpm_tpm12_oiap(self
, &auth_handle
, nonce_even
);
1683 tpm_rsa_key_parms_len
= memconcat(&tpm_rsa_key_parms
,
1685 AS4BE(2048), AS4BE(2), AS4BE(0)
1688 if (tpm_rsa_key_parms_len
< 0) {
1689 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1693 tpm_key_parms_len
= memconcat(&tpm_key_parms
,
1696 AS2BE(TPM_ES_RSAESOAEP_SHA1_MGF1
),
1698 AS4BE(tpm_rsa_key_parms_len
)}, (size_t)12,
1699 tpm_rsa_key_parms
, tpm_rsa_key_parms_len
,
1701 if (tpm_key_parms_len
< 0) {
1702 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1706 tpm_key12_len
= memconcat(&tpm_key12
,
1708 AS2BE(TPM_TAG_KEY12
), AS2BE(0),
1709 AS2BE(TPM_KEY_STORAGE
), AS4BE(0), TPM_AUTH_ALWAYS
1711 tpm_key_parms
, tpm_key_parms_len
,
1712 (unsigned char[]){AS4BE(0), AS4BE(0), AS4BE(0)}, (size_t)12,
1714 if (tpm_key12_len
< 0) {
1715 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1719 req_len
= concat(req
, sizeof(req
),
1721 (unsigned char[]){AS2BE(TPM_PID_OWNER
), AS4BE(enc_owner_auth_len
)}, (size_t)6,
1722 enc_owner_auth
, enc_owner_auth_len
,
1723 (unsigned char[]){AS4BE(enc_srk_auth_len
)}, (size_t)4,
1724 enc_srk_auth
, enc_srk_auth_len
,
1725 tpm_key12
, tpm_key12_len
,
1728 logerr(self
->logfile
, "Internal error in %s: req is too small\n");
1731 SHA1(&req
[6], req_len
- 6, in_param_digest
);
1733 in_auth_setup_params_len
= memconcat(&in_auth_setup_params
,
1734 nonce_even
, sizeof(nonce_even
),
1735 nonce_odd
, sizeof(nonce_odd
),
1736 &continue_auth_session
, (size_t)1,
1738 if (in_auth_setup_params_len
< 0) {
1739 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1743 macinput_len
= memconcat(&macinput
,
1744 in_param_digest
, sizeof(in_param_digest
),
1745 in_auth_setup_params
, in_auth_setup_params_len
,
1747 if (macinput_len
< 0) {
1748 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1752 HMAC(sha1
, ownerpass_digest
, SHA_DIGEST_LENGTH
, macinput
, macinput_len
,
1753 owner_auth
, &owner_auth_len
);
1755 len
= concat(&req
[req_len
], sizeof(req
) - req_len
,
1756 (unsigned char[]){AS4BE(auth_handle
)}, (size_t)4,
1757 nonce_odd
, sizeof(nonce_odd
),
1758 &continue_auth_session
, (size_t)1,
1759 owner_auth
, owner_auth_len
,
1762 logerr(self
->logfile
, "Internal error in %s: req is too small\n");
1767 trh
= (struct tpm_req_header
*)req
; /* old gcc type-punned pointer */
1768 trh
->size
= htobe32(req_len
);
1770 ret
= transfer(self
, req
, req_len
, "TPM_TakeOwnership", FALSE
, NULL
, 0);
1773 EVP_PKEY_free(pkey
);
1774 EVP_PKEY_CTX_free(ctx
);
1775 #if OPENSSL_VERSION_NUMBER >= 0x30000000L
1785 #if OPENSSL_VERSION_NUMBER < 0x30000000L
1786 error_free_pkey_and_rsa
:
1790 EVP_PKEY_CTX_free(ctx
);
1792 EVP_PKEY_free(pkey
);
1797 static int swtpm_tpm12_nv_define_space(struct swtpm
*self
, uint32_t nvindex
,
1798 uint32_t nvindexattrs
, size_t size
)
1800 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM_TAG_RQU_COMMAND
, 0, TPM_ORD_NV_DEFINE_SPACE
);
1801 g_autofree
unsigned char *pcr_info_short
= NULL
;
1802 ssize_t pcr_info_short_len
;
1803 g_autofree
unsigned char *nv_data_public
= NULL
;
1804 ssize_t nv_data_public_len
;
1805 g_autofree
unsigned char *req
= NULL
;
1807 unsigned char zeroes
[SHA_DIGEST_LENGTH
] = {0, };
1809 pcr_info_short_len
= memconcat(&pcr_info_short
,
1810 (unsigned char[]){AS2BE(3), 0, 0, 0, TPM_LOC_ALL
}, (size_t)6,
1811 zeroes
, sizeof(zeroes
),
1813 if (pcr_info_short_len
< 0) {
1814 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1818 nv_data_public_len
= memconcat(&nv_data_public
,
1820 AS2BE(TPM_TAG_NV_DATA_PUBLIC
), AS4BE(nvindex
)
1822 pcr_info_short
, pcr_info_short_len
,
1823 pcr_info_short
, pcr_info_short_len
,
1825 AS2BE(TPM_TAG_NV_ATTRIBUTES
), AS4BE(nvindexattrs
),
1826 0, 0, 0, AS4BE(size
)
1829 if (nv_data_public_len
< 0) {
1830 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1834 req_len
= memconcat(&req
,
1836 nv_data_public
, nv_data_public_len
,
1837 zeroes
, sizeof(zeroes
),
1840 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1844 ((struct tpm_req_header
*)req
)->size
= htobe32(req_len
);
1846 return transfer(self
, req
, req_len
, "TPM_NV_DefineSpace", FALSE
, NULL
, 0);
1849 static int swtpm_tpm12_nv_write_value(struct swtpm
*self
, uint32_t nvindex
,
1850 const unsigned char *data
, size_t data_len
)
1852 struct tpm_req_header hdr
= TPM_REQ_HEADER_INITIALIZER(TPM_TAG_RQU_COMMAND
, 0, TPM_ORD_NV_WRITE_VALUE
);
1853 g_autofree
unsigned char *req
= NULL
;
1856 req_len
= memconcat(&req
,
1858 (unsigned char[]){AS4BE(nvindex
), AS4BE(0), AS4BE(data_len
)}, (size_t)12,
1862 logerr(self
->logfile
, "Internal error in %s: out of memory\n");
1866 ((struct tpm_req_header
*)req
)->size
= htobe32(req_len
);
1868 return transfer(self
, req
, req_len
, "TPM_NV_DefineSpace", FALSE
, NULL
, 0);
1871 /* Write the EK Certificate into NVRAM */
1872 static int swtpm_tpm12_write_ek_cert_nvram(struct swtpm
*self
,
1873 const unsigned char *data
, size_t data_len
)
1875 uint32_t nvindex
= TPM_NV_INDEX_EKCERT
| TPM_NV_INDEX_D_BIT
;
1876 int ret
= swtpm_tpm12_nv_define_space(self
, nvindex
,
1877 TPM_NV_PER_OWNERREAD
| TPM_NV_PER_OWNERWRITE
, data_len
);
1881 ret
= swtpm_tpm12_nv_write_value(self
, nvindex
, data
, data_len
);
1888 /* Write the Platform Certificate into NVRAM */
1889 static int swtpm_tpm12_write_platform_cert_nvram(struct swtpm
*self
,
1890 const unsigned char *data
, size_t data_len
)
1892 uint32_t nvindex
= TPM_NV_INDEX_PLATFORMCERT
| TPM_NV_INDEX_D_BIT
;
1893 int ret
= swtpm_tpm12_nv_define_space(self
, nvindex
,
1894 TPM_NV_PER_OWNERREAD
| TPM_NV_PER_OWNERWRITE
, data_len
);
1898 ret
= swtpm_tpm12_nv_write_value(self
, nvindex
, data
, data_len
);
1905 static int swtpm_tpm12_nv_lock(struct swtpm
*self
)
1907 return swtpm_tpm12_nv_define_space(self
, TPM_NV_INDEX_LOCK
, 0, 0);
1910 static const struct swtpm12_ops swtpm_tpm12_ops
= {
1911 .run_swtpm_bios
= swtpm_tpm12_run_swtpm_bios
,
1912 .create_endorsement_key_pair
= swptm_tpm12_create_endorsement_keypair
,
1913 .take_ownership
= swtpm_tpm12_take_ownership
,
1914 .write_ek_cert_nvram
= swtpm_tpm12_write_ek_cert_nvram
,
1915 .write_platform_cert_nvram
= swtpm_tpm12_write_platform_cert_nvram
,
1916 .nv_lock
= swtpm_tpm12_nv_lock
,
1919 static void swtpm_init(struct swtpm
*swtpm
,
1920 gchar
**swtpm_exec_l
, const gchar
*state_path
,
1921 const gchar
*keyopts
, const gchar
*logfile
,
1922 int *fds_to_pass
, size_t n_fds_to_pass
,
1925 swtpm
->cops
= &swtpm_cops
;
1926 swtpm
->swtpm_exec_l
= swtpm_exec_l
;
1927 swtpm
->state_path
= state_path
;
1928 swtpm
->keyopts
= keyopts
;
1929 swtpm
->logfile
= logfile
;
1930 swtpm
->fds_to_pass
= fds_to_pass
;
1931 swtpm
->n_fds_to_pass
= n_fds_to_pass
;
1932 swtpm
->is_tpm2
= is_tpm2
;
1935 swtpm
->ctrl_fds
[0] = swtpm
->ctrl_fds
[1] = -1;
1936 swtpm
->data_fds
[0] = swtpm
->data_fds
[1] = -1;
1939 struct swtpm12
*swtpm12_new(gchar
**swtpm_exec_l
, const gchar
*state_path
,
1940 const gchar
*keyopts
, const gchar
*logfile
,
1941 int *fds_to_pass
, size_t n_fds_to_pass
)
1943 struct swtpm12
*swtpm12
= g_malloc0(sizeof(struct swtpm12
));
1945 swtpm_init(&swtpm12
->swtpm
, swtpm_exec_l
, state_path
, keyopts
, logfile
,
1946 fds_to_pass
, n_fds_to_pass
, FALSE
);
1947 swtpm12
->ops
= &swtpm_tpm12_ops
;
1952 struct swtpm2
*swtpm2_new(gchar
**swtpm_exec_l
, const gchar
*state_path
,
1953 const gchar
*keyopts
, const gchar
*logfile
,
1954 int *fds_to_pass
, size_t n_fds_to_pass
)
1956 struct swtpm2
*swtpm2
= g_malloc0(sizeof(struct swtpm2
));
1958 swtpm_init(&swtpm2
->swtpm
, swtpm_exec_l
, state_path
, keyopts
, logfile
,
1959 fds_to_pass
, n_fds_to_pass
, TRUE
);
1960 swtpm2
->ops
= &swtpm_tpm2_ops
;
1965 void swtpm_free(struct swtpm
*swtpm
) {