swtpm icon indicating copy to clipboard operation
swtpm copied to clipboard

Running on FreeBSD

Open mekanix opened this issue 1 year ago • 11 comments

Describe the bug

There is a swtpm port in FreeBSD but I don't know how to use it. With socket and cuse there is an error. Socket can not be opened by client apps, cuse fails with an error.

Required: To Reproduce (without these steps your issue may be deleted)

Steps to reproduce the behavior/issue showing all commands on command line, needed XML or JSON (if necessary), etc.:

Socket

  1. pkg install swtpm
  2. mkdir /tmp/mytpm1
  3. swtpm socket --tpmstate dir=/tmp/mytpm1 --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --tpm2 --log level=20
  4. swtpm_ioctl --tpm-device /tmp/mytpm1/swtpm-sock -i (error: Unable to open device '/tmp/mytpm1/swtpm-sock'.)

CUSE

  1. pkg install swtpm
  2. mkdir /tmp/mytpm1
  3. swtpm cuse -n mytpm1 --tpmstate dir=/tmp/mytpm1 --tpm2 (error: fuse: unknown option 'fsname=cuse')

Expected behavior

I expect no error at this stage. Maybe later, but I would expect that I can at least run it.

Desktop (please complete the following information):

  • OS: FreeBSD
  • Version 14-CURRENT

Versions of relevant components

  • swtpm: 0.8.1
  • libtpms: 0.9.6
  • openssl: 3.0
  • gnutls: 3.7.9

Log files No log files are produced, yet.

Additional context I know FreeBSD is not a target platform and that errors might indicate faults in other libraries, not swtpm itself, but can you help me at least narrow the problem down? It would be great if CUSE would start working as recently bhyve, FreeBSD's hypervisor, got TPM pass-through feature so swtpm could be used right away.

mekanix avatar Aug 18 '23 09:08 mekanix

Colegue told me that CUSE on FreeBSD is not extension of FUSE, hence the error. OK, that makes sense, now only to narrow down socket.

mekanix avatar Aug 18 '23 12:08 mekanix

Try these steps with --unix:

swtpm socket --tpmstate dir=/tmp/mytpm1 --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --tpm2 --log level=20
swtpm_ioctl --unix /tmp/mytpm1/swtpm-sock -i

stefanberger avatar Aug 18 '23 13:08 stefanberger

All right, that's a progress. On the "daemon" side I got

swtpm socket --tpmstate dir=/tmp/mytpm1 --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --tpm2 --log level=20
 Ctrl Cmd: length 8
 00 00 00 02 00 00 00 01
 Ctrl Rsp: length 4
 00 00 00 00

Is that what I'm supposed to see?

mekanix avatar Aug 18 '23 13:08 mekanix

Is that what I'm supposed to see?

Looks good.

Your swtpm only has a control channel. If you wanted to add a data/command channel you would need to add something like this so that you can send TPM commands to it. Have a look at this here.

swtpm socket --tpmstate dir=/tmp/mytpm1 --ctrl type=unixio,path=/tmp/mytpm1/swtpm-sock --tpm2 --log level=20 --server type=tcp,port=2321

stefanberger avatar Aug 18 '23 13:08 stefanberger

It does start, but I can't do anything with it. The port is opened on 127.0.0.1 and checking with nmap it appears to be so, but I get an error trying to reach it:

# sockstat -46l | grep 2321
root     swtpm      73007 4   tcp4   127.0.0.1:2321        *:*

# nmap -p 2321 127.0.0.1
Starting Nmap 7.94 ( https://nmap.org ) at 2023-08-19 09:57 CEST
Nmap scan report for localhost (127.0.0.1)
Host is up (0.00031s latency).

PORT     STATE SERVICE
2321/tcp open  rdlap

Nmap done: 1 IP address (1 host up) scanned in 0.02 seconds

# swtpm_ioctl -i --tcp 127.0.0.1:2321
Could not execute PTM_INIT: Operation timed out

mekanix avatar Aug 19 '23 07:08 mekanix

Oh, I realize what's my error here. swtpm_ioctl -i is for --ctrl and --server is used by tss* family of commands. OK, for now I can at least work on init function in bhyve. Thank you so much for your help!

mekanix avatar Aug 19 '23 08:08 mekanix

I created a little playground to learn and experiment more, and for now I have init, deinit and ctrlcmd ripped from swtpm_ioctl. I suppose logical next step is to implement something like datacmd? If yes, what command would be easiest to implement? I guess I will need to look into tss* commands to learn more, but if you have a suggestion how I can learn more, I'm all ears.

mekanix avatar Aug 20 '23 09:08 mekanix

I created a little playground to learn and experiment more, and for now I have init, deinit and ctrlcmd ripped from swtpm_ioctl. I suppose logical next step is to implement something like datacmd? If yes, what command would be easiest to implement? I guess I will need to look into tss* commands to learn more, but if you have a suggestion how I can learn more, I'm all ears.

What do you want to achieve at this point?

Generally the first command you should implement support for is TPM_Startup() since this command is always needed. You could avoid implementing support for it if you passed swtpm ... --flags not-need-init,startup-clear or if you used the TSS 2 tools (IBM or Intel). The TSS 2 tools implement a whole lot of commands if you are fine with invoking them from command line or bash script.

stefanberger avatar Aug 21 '23 10:08 stefanberger

I would like to write backend for bhyve, which is FreeBSD's hypervisor. What I was thinking would be the easiest way to achieve that is by learning from existing tools and implementing at least one command for ctrl/data channel in order to verify it works. As my code will just be a proxy for the VM, I don't need comprehensive set of commands, just one or a handful to verify code works before I turn it into bhyve backend for TPM.

mekanix avatar Aug 21 '23 15:08 mekanix

Next simple command would be TPM_PcrRead to read a PCR.

As for passthrough: We have that also with QEMU and I would not recommend using it but us a vTPM instance (swtpm) per VM. Multiple VMs sharing TPM 'resources' like PCRs is not 'good'.

stefanberger avatar Aug 21 '23 17:08 stefanberger

Maybe I used the wrong word. Passthrough is already implemented and I use it to learn about how to add swtpm to bhyve. Of course, it will be used as a one swtpm instance per VM. Anyway, when I make progress, I'll report it here. Thank you!

mekanix avatar Aug 22 '23 07:08 mekanix