Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows TCTI/TBS support #421

Open
onlythisnamewasfree opened this issue Jul 25, 2023 · 35 comments
Open

Windows TCTI/TBS support #421

onlythisnamewasfree opened this issue Jul 25, 2023 · 35 comments

Comments

@onlythisnamewasfree
Copy link

I was wondering how this crate would also work on Windows platforms. I found:

The official tpm2-tss project https://github.com/tpm2-software/tpm2-tss contains a tcti-tbs.c driver and the included INSTALL mentions Windows in one paragraph (the description does not sound enthusiastic). The project indeed does compile to DLLs on Windows (the included VS solutions seems a bit outdated and needs some tweaks). I have no knowledge if it is feasible to compile it (easier?) without VS (e.g. under WSL with a Makefile?)

This crate generates the TSS bindings for 4 platforms: aarch64-unknown-linux-gnu, arm-unknown-linux-gnueabi, x86_64-unknown-darwin and x86_64-unknown-linux.gnu, so no Windows bindings, and does not implement Windows TBS as connection option.

Q: What is missing for this crate to work on Windows, too?

  1. Generate the necessary bindings?
  2. Implement the TBS connection/configuration option?

...or are there some fundamental issues/structures to implement/rework to make this work?

@Superhepper
Copy link
Collaborator

Superhepper commented Jul 25, 2023

When I do development I use WSL on windows. So that works. Well I have never tried it with a real tpm in WSL don't know if the TPM seen in the WSL might just be a virtual one.

I think the points that you stated are correct those are the basic things needed in order to for this to work on windows. If I am not mistaken some of the APIs that might be blocked on windows that might cause some additional problems.
#169

@onlythisnamewasfree
Copy link
Author

Since Windows 7(?) a TPM is managed by TPM Base Services (TBS) https://learn.microsoft.com/en-us/windows/win32/tbs/tpm-base-services-portal - which coordinates applications' access to the TPM. One never gets direct TPM access?

On Linux one can access /dev/tpm0 directly, and with V2 now the /dev/tpmrm0 service multiplexes applications. I have not found a similar service for Windows, so I suspect the TBS does what tpmrm0 does on Linux? It would make sense that some commands don't work therefor on Windows.

Still, Rust is very portable, high-level TPM code should be portable, only the above mentioned low-level plumbing to attach to TBS is missing? Unfortunately, I don't run Windows and have no Win development experience - but it would be nice to just recompile and have a Windows binary for friends/colleagues that do. Hm.....

@Superhepper
Copy link
Collaborator

Yes, the TBS on windows is some kind of resource access manager. I think it serves the role that arbmd had before it was possible to multiplex access to the TPM device on linux. So if you could use some kind of TCTI based on TBS it should probably work.

@onlythisnamewasfree
Copy link
Author

don't know if the TPM seen in the WSL might just be a virtual one

Would you mind to check whether WSDL uses the hardware tpm?
For example run "tpm2_getcap properties-fixed" from the tpm tools and check manufacturer/vendor properties,
and then compare to the TPM reported in Windows itself (Windows Security -> Device Security -> Security Processor)

@Superhepper
Copy link
Collaborator

Would you mind to check whether WSDL uses the hardware tpm?
For example run "tpm2_getcap properties-fixed" from the tpm tools and check manufacturer/vendor properties,
and then compare to the TPM reported in Windows itself (Windows Security -> Device Security -> Security Processor)

The computer I use is so old that it does not have a physical TPM. Not even a 1.2 one.

@ionut-arm
Copy link
Member

I'd like to help and might try to tackle this in the future if no one's done it by then, but I have limited bandwidth for now. I'd be more than glad to accept a patch if someone can share a proof of concept, could try it out on my PC.

Will try out the TPM2 tools idea from WSL, I'll let you know how that goes when I get to it :)

@onlythisnamewasfree
Copy link
Author

onlythisnamewasfree commented Aug 10, 2023

As Rust code is very portable, it would be nice to have Rust code that uses the TPM under Linux, and also work the same under Windows. By my first investigation this looks quite possible, if the missing bindings/config are filled-in. Although the official C-based TSS does seem to be less loved on Windows (see their README: "Windows dlls built [...] are currently prototypes").

Unfortunately, I don't have a Windows machine (borrowed one for testing) or Windows dev experience... (hmm... maybe use a Win VM?)

@Superhepper
Copy link
Collaborator

I tried to build the lib natively on a windows machine. It did not work I got the following error:

error: failed to run custom build command for `tss-esapi-sys v0.4.0 (C:\Users\jag_h\workspace\rust-tss-esapi\tss-esapi-sys)`

Caused by:
  process didn't exit successfully: `C:\Users\jag_h\workspace\rust-tss-esapi\target\debug\build\tss-esapi-sys-babf86740179bba7\build-script-build` (exit code: 101)
  --- stderr
  thread 'main' panicked at 'Compilation target (architecture, OS) tuple (x86_64, windows) is not part of the supported tuples. Please compile with the "generate-bindings" feature or add support for your platform :)', tss-esapi-sys\build.rs:35:17
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
warning: build failed, waiting for other jobs to finish...

But it is interesting to see how much tinkering it will require to get it to build properly.

@onlythisnamewasfree
Copy link
Author

I tried to build the lib natively on a windows machine. It did not work

That is expected, see my first post, the windows targets are not implemented.

However, the more interesting question is which route is easiest to get something running?
x86_64-pc-windows-msvc is the target using the official TSS DLLs built with VS, using the included VS solution.
But there is also x86_64-pc-windows-gnu, which should be closer to the Linux Way and maybe less work to get running, filling in the missing pieces?

@Superhepper
Copy link
Collaborator

Not sure. This was just me trying to get the build chain up on windows and see what would happen. I will have to look into how to generate bindings next when I have the time.

@Superhepper
Copy link
Collaborator

Superhepper commented Aug 27, 2023

Right now I built the tpm2-tss(4.0.1) using Visual Studio 2022 on Windows 11. It required some minor modifications:

  1. Change the #include <unistd.h> to #include <stdint.h> (src/tss2-tcti/tcti-mssim.c)
  2. Cast tcti_mssim->tpm_sock to a proper pointer value, not sure if this will work though. (src/tss2-tcti/tcti-mssim.c)
  3. Make all projects target a the available windows SDK. ( I Used 10.0 latests)
  4. Change toolchain to LLVM (clang-cl).
  5. Download and install OpenSSL SDK. I chosed a packaged version from https://slproweb.com/products/Win32OpenSSL.html. The .sln file assumes this is installed to "C:\OpenSSL-v11-Win64" if you do not have installed it there you need to modify the include dir paths and library paths in the tss2-esys.vcxproj.

@onlythisnamewasfree
Copy link
Author

When I tried (see in my first post: "the included VS solutions seems a bit outdated and needs some tweaks"), I used current git snapshot and had to do 3-5, but I not 1-2 as far as I remember. Hm... probably current git already fixed this?

@Superhepper
Copy link
Collaborator

I am not sure why I had to do all that but it did not matter to because what I was more intressted in was to try to modify the build.rs in the sys crate in order to recognise the header files on windows. Without pkg I was struggling with how to pass version values. Because no version information is built into the lib or dll files.

@yafetgetachew
Copy link

Hey guys, are the windows targets implemented yet?

@Superhepper
Copy link
Collaborator

No, I have written a little bit of code to try to get it running. But it is experimental in tpm2-tss and my code is not really working yet.

@Superhepper
Copy link
Collaborator

So this is my progress so far:

  1. I used this PR to build tpm2-tss

  2. Download and install OpenSSL SDK. I chosed a packaged version from https://slproweb.com/products/Win32OpenSSL.html.

  3. I an installation directory that looked like this: | -> tpm2-tss-Win64 | -> include | -> tss2 | -> ...... | -> lib | -> ..... | ->VERSION
    The version file is not generated by the solution but if you read my comment in the CR you can see how you can fix that or just add the file manually to the folder.

  4. I used my very experimental win-build branch

  5. I ran the following command:

    • The lib clang path can either be the one in visual studio or you can download LLVM.
    • The tpm2 tss path needs to be set the install directory.

    LIBCLANG_PATH="<Path to the llvm bin folder> "TPM2_TSS_PATH="<Path to the install directory>" cargo build --features=generate-bindings

    So for me this looked something like:

    LIBCLANG_PATH="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin" TPM2_TSS_PATH="C:\Program Files\tpm2-tss-Win64" cargo build --features=generate-bindings

    Unfortunately this resulted in bindgen generating a lot of stuff that rust could not build. So that is something I will look into another time.

@Superhepper
Copy link
Collaborator

I need to get this in #471 then I might have something that actually builds. But I have no idea how to test it. Does any one know how to use the Microsoft simulator?

@Superhepper
Copy link
Collaborator

I have incorporated the latest changes so it now builds under windows. But I have no idea how to test it under windows so if any one have any ideas please provide them so I can see if I can setup some kind of CI for it.

@Superhepper
Copy link
Collaborator

#477 has been merged.
and #523 is almost done I think which will make it a lot easier to build this crate under windows.

Unfortunately we still have #518 issue open. I would not claim that we would officially be supporting windows without it.

@sathibault
Copy link

sathibault commented May 31, 2024

I'm trying to build this on Windows following the comments above. I addition to LIBCLANG_PATH, I also had to define BINDGEN_EXTRA_CLANG_ARGS with additional -isystem paths for all the system header files. It didn't seem to find them on there own.

The clang call seems to pass now, but I'm getting a fatal error from bindgen:

  --- stdout
  cargo:rustc-link-search=native=D:/grokit/ext/tpm2-tss\lib
  cargo:rustc-link-lib=tss2-sys
  cargo:rustc-link-lib=tss2-esys
  cargo:version=4.1.0

  cargo:rustc-link-lib=tss2-tctildr
  cargo:rustc-link-lib=tss2-mu
  cargo:rustc-link-lib=tss2-tcti-tbs

  --- stderr
  thread 'main' panicked at C:\Users\thiba\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bindgen-0.66.1\codegen\mod.rs:717:71:
  called `Result::unwrap()` on an `Err` value: FromBytesWithNulError { kind: InteriorNul(1) }
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

(I'm building with main branch of this repo)

Any thoughts about this error?

@Superhepper
Copy link
Collaborator

What feature flags are you using when building?

@sathibault
Copy link

What feature flags are you using when building?

tss-esapi = {git = "https://github.com/parallaxsecond/rust-tss-esapi.git", features=["generate-bindings"] }

@Superhepper
Copy link
Collaborator

Did you build it using powershell or what shell did you use? And how did your build command look like?

@Superhepper
Copy link
Collaborator

With powershell I did like this:

PS C:\workspace\rust-tss-esapi> $Env:LIBCLANG_PATH = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin"
PS C:\workspace\rust-tss-esapi> $Env:TPM2_TSS_PATH = "C:\Program Files\tpm2-tss-Win64"
PS C:\workspace\rust-tss-esapi> cargo build --features=generate-bindings

<C:\Program Files\tpm2-tss-Win64> = The directory where I manually setup the tpm2-tss installation.

And the latest from master builds fine for me.
Windows 11
rustc 1.73.0
cargo 1.73.0

@sathibault
Copy link

sathibault commented Jun 3, 2024

With powershell I did like this:

PS C:\workspace\rust-tss-esapi> $Env:LIBCLANG_PATH = "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin"
PS C:\workspace\rust-tss-esapi> $Env:TPM2_TSS_PATH = "C:\Program Files\tpm2-tss-Win64"
PS C:\workspace\rust-tss-esapi> cargo build --features=generate-bindings

<C:\Program Files\tpm2-tss-Win64> = The directory where I manually setup the tpm2-tss installation.

And the latest from master builds fine for me. Windows 11 rustc 1.73.0 cargo 1.73.0

This is not working for me. How did you install tpm2-tss? Is it a binary install? What version?
(I built tpm2-tss from master since the PR you mentioned above was merged).

@Superhepper
Copy link
Collaborator

Superhepper commented Jun 3, 2024

So the tpm2-tss-Win64 (can be named anything) needs to be setup in a very specific way. You need to build all the binaries locally. And then manually move them into this directory.

I realize that my first description might not have been so easy to understand.

This is how the directory should look like.

├── tpm2-tss-Win64
│   ├── include
│   │   ├── tss2
│   │       ├── tss2_*.h
│   ├── lib
│   │   ├── tss2-*.lib
│   │   ├── tss2-*.dll
│   │   ├── tss2-*.pdb
│   └── VERSION

@sathibault
Copy link

│   │   ├── tss2

Yes, I had done that properly. I've tried to match your setup. So I have:
Visual Studio 2022 with Clang tools
tpm2-tss/master
rust-tss-esapi/main
Developer PowerShell for Visual Studio 2022

Without adding any extra include path, my result was:

  Unable to generate bindings to TSS2 ESYS APIs.: ClangDiagnostic("C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.19041.0\\\\um/windows.h:167:10: fatal error: 'excpt.h' file not found\n")

I then added an extra include path:

$Env:BINDGEN_EXTRA_CLANG_ARGS = '"-isystemC:/Program Files/Microsoft Visual Studio/2022/Professional/SDK/ScopeCppSDK/vc15/VC/include"'

With that my result is:

  thread 'main' panicked at C:\Users\thiba\.cargo\registry\src\index.crates.io-6f17d22bba15001f\bindgen-0.66.1\codegen\mod.rs:717:71:
  called `Result::unwrap()` on an `Err` value: FromBytesWithNulError { kind: InteriorNul(1) }

@Superhepper
Copy link
Collaborator

When I am trying to use tpm2-tss master I get the same error.

I updated bindgen to 0.69.4. And now it builds fine.

@sathibault
Copy link

When I am trying to use tpm2-tss master I get the same error.

I updated bindgen to 0.69.4. And now it builds fine.

Confirmed, it is working for me as well with that change. Thank you!

@onlythisnamewasfree
Copy link
Author

onlythisnamewasfree commented Sep 5, 2024

Reading through this bug (and related bugs) some seem to have succeeded, however I havn't figured it out myself yet.
I have C:\OpenSSL-v11-Win64, with VS2022Community and a git checkout of tpm2-tss I successfully generated tpm2-tss/x64/Debug, which contains the 7 tss2-*.dll/.lib./pdb files.
I also have a Rust project open in VSCodium, it uses tss-esapi 7.5.1 and the hardware TPM under Linux just fine.

Now... how do I build this project under native Windows, generate the tss-esapi-sys bindings and use the HW TPM?
In a current git checkout of tss-esapi-sys I see no signs of Windows support - yet?

Thank you!

@Superhepper
Copy link
Collaborator

Currently there is no released version tss-esapi that can build natively on Windows. So you will have to use master if you want to try it out.

@nicolaspernoud
Copy link

Hello,
I managed to build on windows, but as I understand, there is now way for now to bind to the physical TPM ?
Or what would be the windows equivalent of :

    let context = Context::new(
        TctiNameConf::from_environment_variable()
            .expect("Failed to get TCTI / TPM2TOOLS_TCTI from environment. Try `export TCTI=device:/dev/tpmrm0`"),
    )
    .expect("Failed to create Context");

@Superhepper
Copy link
Collaborator

Superhepper commented Sep 9, 2024

On windows you have to use the TBS TCTI. And you are right it seems as it has not been added. And that is being added #523.

@nicolaspernoud
Copy link

Good new, I hope that #523 will be merged soon !

@Superhepper
Copy link
Collaborator

Good new, I hope that #523 will be merged soon !

The main branch now have support for the TBS TCTI but the bundled feature has not been merged yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants