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

Use NV indexes to store node's seed in TPM #602

Merged
merged 3 commits into from
Oct 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
CC = /usr/bin/gcc
OS := $(shell uname)
TPM_INSTALLED := $(shell ldconfig -p | grep libtss2-esys.so > /dev/null; echo $$?)
TPMFLAGS = -ltss2-esys -ltss2-rc -ltss2-mu -lcrypto

all: compile_c_programs

Expand All @@ -15,8 +16,8 @@ compile_c_programs:


ifeq ($(TPM_INSTALLED),0)
$(CC) src/c/crypto/stdio_helpers.c src/c/crypto/tpm/lib.c src/c/crypto/tpm/port.c -o priv/c_dist/tpm_port -I src/c/crypto/stdio_helpers.h -I src/c/crypto/tpm/lib.h -ltss2-esys
$(CC) src/c/crypto/tpm/keygen.c src/c/crypto/tpm/lib.c -o priv/c_dist/tpm_keygen -I src/c/crypto/tpm/lib.h -ltss2-esys -lcrypto
$(CC) src/c/crypto/stdio_helpers.c src/c/crypto/tpm/lib.c src/c/crypto/tpm/port.c -o priv/c_dist/tpm_port -I src/c/crypto/stdio_helpers.h -I src/c/crypto/tpm/lib.h $(TPMFLAGS)
$(CC) src/c/crypto/tpm/keygen.c src/c/crypto/tpm/lib.c -o priv/c_dist/tpm_keygen -I src/c/crypto/tpm/lib.h $(TPMFLAGS)
endif


Expand Down
4 changes: 2 additions & 2 deletions config/dev.exs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ config :archethic, Archethic.P2P.BootstrappingSeeds,
"127.0.0.1:3002:00011D967D71B2E135C84206DDD108B5925A2CD99C8EBC5AB5D8FD2EC9400CE3C98A:tcp"
)

config :archethic, Archethic.Crypto.NodeKeystore.SoftwareImpl,
seed: System.get_env("ARCHETHIC_CRYPTO_SEED", "node1")
config :archethic, Archethic.Crypto.NodeKeystore.Origin.SoftwareImpl,
node_seed: System.get_env("ARCHETHIC_CRYPTO_SEED", "node1")

config :archethic,
Archethic.Crypto.NodeKeystore.Origin,
Expand Down
4 changes: 2 additions & 2 deletions config/prod.exs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ config :archethic, Archethic.Crypto,
key_certificates_dir: System.get_env("ARCHETHIC_CRYPTO_CERT_DIR", "~/aebot/key_certificates")

config :archethic,
Archethic.Crypto.NodeKeystore.SoftwareImpl,
seed: System.get_env("ARCHETHIC_CRYPTO_SEED")
Archethic.Crypto.NodeKeystore.Origin.SoftwareImpl,
node_seed: System.get_env("ARCHETHIC_CRYPTO_SEED")

config :archethic,
Archethic.Crypto.NodeKeystore.Origin,
Expand Down
1 change: 1 addition & 0 deletions lib/archethic/crypto/keystore/node/origin.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ defmodule Archethic.Crypto.NodeKeystore.Origin do
@callback child_spec(any) :: Supervisor.child_spec()
@callback sign_with_origin_key(data :: iodata()) :: binary()
@callback origin_public_key() :: Crypto.key()
@callback retrieve_node_seed() :: binary()
end
70 changes: 61 additions & 9 deletions lib/archethic/crypto/keystore/node/origin/software_impl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,24 @@ defmodule Archethic.Crypto.NodeKeystore.Origin.SoftwareImpl do
GenServer.call(pid, :origin_public_key)
end

@impl Origin
def retrieve_node_seed(pid \\ __MODULE__) do
GenServer.call(pid, :retrieve_node_seed)
end

@impl GenServer
@spec init(any) :: {:ok, %{origin_keypair: {<<_::16, _::_*8>>, <<_::16, _::_*8>>}}}
def init(_arg \\ []) do
origin_keypair = Crypto.generate_deterministic_keypair(read_seed())
unless File.exists?(Utils.mut_dir("crypto")) do
File.mkdir_p!(Utils.mut_dir("crypto"))
end

origin_keypair = Crypto.generate_deterministic_keypair(read_origin_seed())
node_seed = provision_node_seed()

{:ok,
%{
origin_keypair: origin_keypair
origin_keypair: origin_keypair,
node_seed: node_seed
}}
end

Expand All @@ -44,21 +54,63 @@ defmodule Archethic.Crypto.NodeKeystore.Origin.SoftwareImpl do
{:reply, pub, state}
end

defp read_seed do
unless File.exists?(Utils.mut_dir("crypto")) do
File.mkdir_p!(Utils.mut_dir("crypto"))
def handle_call(:retrieve_node_seed, _from, state = %{node_seed: node_seed}) do
{:reply, node_seed, state}
end

defp provision_node_seed do
seed =
:archethic
|> Application.get_env(__MODULE__, [])
|> Keyword.get(:node_seed)

case seed do
nil ->
read_node_seed()

seed ->
case Base.decode16(seed, case: :mixed) do
:error ->
seed

{:ok, seed} ->
seed
end
end
end

defp read_origin_seed do
case File.read(origin_seed_filename()) do
{:ok, seed} ->
seed

_ ->
seed = :crypto.strong_rand_bytes(32)
File.write!(origin_seed_filename(), seed)
seed
end
end

defp origin_seed_filename, do: Utils.mut_dir("crypto/origin_seed")

case File.read(seed_filename()) do
defp read_node_seed do
case File.read(node_seed_filepath()) do
{:ok, seed} ->
seed

_ ->
# We generate a random seed if no one is given
seed = :crypto.strong_rand_bytes(32)
File.write!(seed_filename(), seed)

# We write the seed on disk for backup later
write_node_seed(seed)
seed
end
end

defp seed_filename, do: Utils.mut_dir("crypto/origin_seed")
defp write_node_seed(seed) when is_binary(seed) do
File.write!(node_seed_filepath(), seed)
end

defp node_seed_filepath, do: Utils.mut_dir("crypto/node_seed")
end
16 changes: 16 additions & 0 deletions lib/archethic/crypto/keystore/node/origin/tpm_impl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ defmodule Archethic.Crypto.NodeKeystore.Origin.TPMImpl do
GenServer.call(__MODULE__, :origin_public_key)
end

@impl Origin
@spec retrieve_node_seed() :: binary()
def retrieve_node_seed do
GenServer.call(__MODULE__, :retrieve_node_seed)
end

@impl GenServer
def init(_) do
tpm_program = Application.app_dir(:archethic, "priv/c_dist/tpm_port")
Expand All @@ -52,6 +58,10 @@ defmodule Archethic.Crypto.NodeKeystore.Origin.TPMImpl do
{:noreply, Map.update!(state, :async_tasks, &Map.put(&1, ref, from))}
end

def handle_call(:retrieve_node_seed, _from, state = %{port_handler: port_handler}) do
{:reply, retrieve_node_seed(port_handler), state}
end

@impl GenServer
def handle_info({ref, result}, state = %{async_tasks: async_tasks}) do
case Map.pop(async_tasks, ref) do
Expand Down Expand Up @@ -99,6 +109,12 @@ defmodule Archethic.Crypto.NodeKeystore.Origin.TPMImpl do

defp initialize_tpm(port_handler) do
# Set TPM root key and key index at 0th
# Generate the node seed
PortHandler.request(port_handler, 1, <<0::16>>)
end

defp retrieve_node_seed(port_handler) do
{:ok, seed} = PortHandler.request(port_handler, 4, <<>>)
seed
end
end
40 changes: 4 additions & 36 deletions lib/archethic/crypto/keystore/node/software_impl.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ defmodule Archethic.Crypto.NodeKeystore.SoftwareImpl do
alias Archethic.Crypto.ID
alias Archethic.Crypto.Ed25519
alias Archethic.Crypto.NodeKeystore
alias Archethic.Crypto.NodeKeystore.Origin

alias Archethic.Utils

Expand Down Expand Up @@ -94,26 +95,12 @@ defmodule Archethic.Crypto.NodeKeystore.SoftwareImpl do
end

@impl GenServer
def init(opts) do
# Initialize the crypto backup folder
def init(_arg \\ []) do
unless File.exists?(Utils.mut_dir("crypto")) do
File.mkdir_p!(Utils.mut_dir("crypto"))
end

node_seed =
case Keyword.get(opts, :seed) do
nil ->
read_seed()

seed ->
case Base.decode16(seed, case: :mixed) do
:error ->
seed

{:ok, seed} ->
seed
end
end
node_seed = Origin.retrieve_node_seed()

nb_keys = read_index()

Expand Down Expand Up @@ -158,21 +145,6 @@ defmodule Archethic.Crypto.NodeKeystore.SoftwareImpl do
:ets.insert(@keystore_table, {:index, index})
end

defp read_seed do
case File.read(seed_filepath()) do
{:ok, seed} ->
seed

_ ->
# We generate a random seed if no one is given
seed = :crypto.strong_rand_bytes(32)

# We write the seed on disk for backup later
write_seed(seed)
seed
end
end

defp read_index do
case File.read(index_filepath()) do
{:ok, ""} ->
Expand All @@ -187,15 +159,10 @@ defmodule Archethic.Crypto.NodeKeystore.SoftwareImpl do
end
end

defp write_seed(seed) when is_binary(seed) do
File.write!(seed_filepath(), seed)
end

defp write_index(index) when is_integer(index) and index >= 0 do
File.write!(index_filepath(), to_string(index))
end

defp seed_filepath, do: Utils.mut_dir("crypto/seed")
defp index_filepath, do: Utils.mut_dir("crypto/index")

defp set_keypair(keypair_name, keypair) when is_tuple(keypair) do
Expand Down Expand Up @@ -243,6 +210,7 @@ defmodule Archethic.Crypto.NodeKeystore.SoftwareImpl do
def handle_call({:update, index}, _from, state) do
[{_, node_seed}] = :ets.lookup(@keystore_table, :seed)
do_set_node_key_index(node_seed, index)

{:reply, :ok, state}
end
end
7 changes: 2 additions & 5 deletions lib/archethic/crypto/keystore/node_supervisor.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,9 @@ defmodule Archethic.Crypto.NodeKeystore.Supervisor do
end

def init(_) do
node_keystore_impl = Application.get_env(:archethic, NodeKeystore, NodeKeystore.SoftwareImpl)
node_keystore_conf = Application.get_env(:archethic, node_keystore_impl)

children = [
{NodeKeystore, node_keystore_conf},
Origin
Origin,
NodeKeystore
]

Supervisor.init(Utils.configurable_children(children), strategy: :one_for_one)
Expand Down
28 changes: 12 additions & 16 deletions src/c/crypto/tpm/keygen.c
Original file line number Diff line number Diff line change
@@ -1,22 +1,18 @@
#include <stdio.h>
#include <openssl/sha.h>
#include "lib.h"
#include <openssl/sha.h>
#include <stdio.h>

void main()
{
initializeTPM(1);
void main() {
initializeTPM(1);

INT publicKeySize = 0;
BYTE *asnkey;
INT publicKeySize = 0;
BYTE *asnkey;

for (int z = 0; z < 500; z++)
{
asnkey = getPublicKey(z, &publicKeySize);
for (int v = 26; v < publicKeySize; v++)
{
printf("%02x", asnkey[v]);
}
printf("\n");
for (int z = 0; z < 500; z++) {
asnkey = getPublicKey(z, &publicKeySize);
for (int v = 26; v < publicKeySize; v++) {
printf("%02x", asnkey[v]);
}
printf("\n");
}
}

Loading