Skip to content

Commit

Permalink
Use NV indexes to store node's seed in TPM (#602)
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmanzanera authored Oct 7, 2022
1 parent 46187c7 commit fa5fad4
Show file tree
Hide file tree
Showing 15 changed files with 725 additions and 716 deletions.
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

0 comments on commit fa5fad4

Please sign in to comment.