Skip to content

Commit

Permalink
Merge pull request #1 from redwirelabs/add-basic-swtpm
Browse files Browse the repository at this point in the history
Initial builder wrapper for swtpm
  • Loading branch information
abelino authored Dec 20, 2024
2 parents bee58ef + 8fc36dc commit 0263c1d
Show file tree
Hide file tree
Showing 6 changed files with 227 additions and 3 deletions.
87 changes: 87 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
on: push

jobs:
build:
name: Build
strategy:
matrix:
os:
- ubuntu-24.04
- ubuntu-22.04
- macos-13
runs-on: ${{ matrix.os }}
steps:
- name: Set up Elixir
if: ${{ startsWith(matrix.os, 'ubuntu') }}
uses: erlef/setup-beam@v1
with:
otp-version: "27.1.3"
elixir-version: "1.17.3"
- name: Set up Elixir
if: ${{ startsWith(matrix.os, 'macos') }}
run: brew install elixir
- name: Checkout repository
uses: actions/checkout@v4
- name: Get dependencies
run: mix deps.get --only dev
- name: Restore PLTs
uses: actions/cache@v4
with:
path: _build/dev/plt
key: plt-${{ github.ref }}-${{ github.sha }}
restore-keys: |
plt-${{ github.ref }}-${{ github.sha }}
plt-${{ github.ref }}-
plt-refs/heads/master-
- name: Install system deps
if: ${{ startsWith(matrix.os, 'ubuntu') }}
run: |
sudo apt install \
build-essential \
devscripts \
equivs \
libtasn1-6-dev \
libjson-glib-dev \
libseccomp-dev \
libgmp-dev
- name: Install system deps
if: ${{ startsWith(matrix.os, 'macos') }}
run: brew install automake gawk socat json-glib
- name: Compile
run: mix compile
type_check:
name: Type Check
runs-on: ubuntu-24.04
steps:
- name: Set up Elixir
uses: erlef/setup-beam@v1
with:
otp-version: "27.1.3"
elixir-version: "1.17.3"
- name: Checkout repository
uses: actions/checkout@v4
- name: Get dependencies
run: mix deps.get --only dev
- name: Restore PLTs
uses: actions/cache@v4
with:
path: _build/dev/plt
key: plt-${{ github.ref }}-${{ github.sha }}
restore-keys: |
plt-${{ github.ref }}-${{ github.sha }}
plt-${{ github.ref }}-
plt-refs/heads/master-
- name: Install system deps
run: |
sudo apt install \
build-essential \
devscripts \
equivs \
libtasn1-6-dev \
libjson-glib-dev \
libseccomp-dev \
libgmp-dev
- name: Compile
run: mix compile
- name: Run dialyzer
run: mix dialyzer
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/_build/
/cover/
/data/
/deps/
/doc/
/.fetch
Expand Down
57 changes: 57 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,60 @@ if(NOT EXISTS ${CPM_PATH})
file(DOWNLOAD ${CPM_RELEASE_URL} ${CPM_PATH})
endif()
include(${CPM_PATH})

# dependencies
set(LIBTPMS_VER v0.10.0)
set(SWTPM_VER v0.10.0)

if(DEFINED ENV{LIBTPMS_VER})
set(LIBTPMS_VER $ENV{LIBTPMS_VER})
endif()

if(DEFINED ENV{SWTPM_VER})
set(SWTPM_VER $ENV{SWTPM_VER})
endif()

CPMFindPackage(
NAME libtpms
GITHUB_REPOSITORY stefanberger/libtpms
GIT_TAG ${LIBTPMS_VER})

CPMFindPackage(
NAME swtpm
GITHUB_REPOSITORY stefanberger/swtpm
GIT_TAG ${SWTPM_VER})

# build
project(swtpm_ex)

include(ExternalProject)
include(ProcessorCount)

find_program(MAKE make REQUIRED)
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBTASN1 libtasn1 REQUIRED)
pkg_check_modules(LIBJASON_GLIB json-glib-1.0 REQUIRED)
pkg_check_modules(LIBGMP gmp REQUIRED)

if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
pkg_check_modules(LIBSECCOMP libseccomp REQUIRED)
endif()

ProcessorCount(NPROC)

ExternalProject_Add(libtpms
SOURCE_DIR ${libtpms_SOURCE_DIR}
CONFIGURE_COMMAND ${libtpms_SOURCE_DIR}/autogen.sh
--with-tpm2
--with-openssl
--prefix=$ENV{MIX_APP_PATH}/priv
BUILD_COMMAND ${MAKE} -j ${NPROC})

ExternalProject_Add(swtpm
SOURCE_DIR ${swtpm_SOURCE_DIR}
CONFIGURE_COMMAND PKG_CONFIG_PATH=$ENV{MIX_APP_PATH}/priv/lib/pkgconfig
${swtpm_SOURCE_DIR}/autogen.sh
--disable-tests
--with-openssl
--prefix=$ENV{MIX_APP_PATH}/priv
BUILD_COMMAND ${MAKE} -j ${NPROC})
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
# swtpm

An easy way to bring a Software TPM emulator into your elixir application by
wrapping [swtpm](https://github.com/stefanberger/swtpm).

## Prerequisites

Ensure the following are installed on your host system:
* [libtasn1](https://www.gnu.org/software/libtasn1/)
* [json-glib-1.0](https://wiki.gnome.org/Projects/JsonGlib)
* [libseccomp](https://github.com/seccomp/libseccomp)
* [gmp](https://gmplib.org/)

## Installation

The package can be installed by adding `swtpm` to your list of dependencies
Expand All @@ -12,3 +23,16 @@ def deps do
]
end
```

## Supervision

Add the `SWTPM` module spec to your `application.ex`. For more details see docs
for `&SWTPM.child_spec/1`.

```elixir
defp children(:host) do
[
{SWTPM, [state_dir: "data/tpm"]}
]
end
```
55 changes: 55 additions & 0 deletions lib/swtpm.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,59 @@ defmodule SWTPM do
@moduledoc """
Software TPM emulator.
"""

@doc """
Integrates the `SWTPM` module with a supervision tree, providing a
standardized way to configure and start the Software TPM emulator as a
supervised process.
## Options
- `:state_dir` - Specifies the directory where the TPM state will be stored.
- `:server_port` - Specifies the TCP port used for the TPM server. Defaults
to `2321`.
- `:ctrl_port` - Specifies the TCP port used for TPM control commands.
Defaults to `2322`.
- `:flags` - Refer to https://man.archlinux.org/man/swtpm.8.en for full list
of flags. Defaults to `[:not_need_init, :startup_clear]`.
## Example
```elixir
children = [
{SWTPM, [state_dir: "/data/tpm"]}
]
Supervisor.start_link(children, [strategy: :one_for_one, name: MySupervisor])
```
"""
@spec child_spec(keyword) :: Supervisor.child_spec()
def child_spec(opts) do
state_dir = opts[:state_dir]
server_port = opts[:server_port] || 2321
ctrl_port = opts[:ctrl_port] || 2322

flags =
Keyword.get(opts, :flags, [:not_need_init, :startup_clear])
|> Enum.map(& to_string(&1) |> String.replace("_", "-"))
|> Enum.join(",")

command = Path.join([:code.priv_dir(:swtpm), "bin", "swtpm"])
args = [
"socket",
"--tpm2",
"--tpmstate", "dir=#{state_dir}",
"--server", "type=tcp,port=#{server_port}",
"--ctrl", "type=tcp,port=#{ctrl_port}",
"--flags", flags,
]

%{
id: __MODULE__,
start: {MuonTrap.Daemon, :start_link, [command, args, []]},
type: :worker,
restart: :permanent,
}
end
end
6 changes: 3 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ defmodule SWTPM.MixProject do

def application do
[
extra_applications: [:logger]
extra_applications: [:logger],
]
end

Expand All @@ -38,7 +38,7 @@ defmodule SWTPM.MixProject do
cookie: "#{@app}_cookie",
include_erts: &Nerves.Release.erts/0,
steps: [&Nerves.Release.init/1, :assemble],
strip_beams: Mix.env() == :prod or [keep: ["Docs"]]
strip_beams: Mix.env() == :prod or [keep: ["Docs"]],
]
end

Expand Down Expand Up @@ -68,7 +68,7 @@ defmodule SWTPM.MixProject do
defp docs do
[
main: "readme",
extras: ["README.md"]
extras: ["README.md"],
]
end

Expand Down

0 comments on commit 0263c1d

Please sign in to comment.