Skip to content

Commit d6db981

Browse files
committed
add device_type paramter to read/put settings, use proper writeable slot for trust and go chips
1 parent c1f1395 commit d6db981

File tree

1 file changed

+53
-25
lines changed

1 file changed

+53
-25
lines changed

lib/nerves_key.ex

Lines changed: 53 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,8 @@ defmodule NervesKey do
77
alias NervesKey.{Config, OTP, Data, ProvisioningInfo}
88

99
@build_year DateTime.utc_now().year
10-
@settings_slots [8, 7, 6, 5]
11-
@settings_max_length Enum.reduce(@settings_slots, 0, fn slot, acc ->
12-
acc + ATECC508A.DataZone.slot_size(slot)
13-
end)
10+
@settings_slots_nerves_key [8, 7, 6, 5]
11+
@settings_slot_trust_and_go 8
1412

1513
@typedoc "Which device/signer certificate pair to use"
1614
@type certificate_pair() :: :primary | :aux
@@ -431,29 +429,54 @@ defmodule NervesKey do
431429
%ProvisioningInfo{manufacturer_sn: Base.encode32(sn, padding: false), board_name: "NervesKey"}
432430
end
433431

432+
@doc """
433+
Return the max length of settings
434+
"""
435+
@spec max_settings_len(device_type()) :: integer()
436+
def max_settings_len(:nerves_key) do
437+
Enum.reduce(@settings_slots_nerves_key, 0, fn slot, acc ->
438+
acc + ATECC508A.DataZone.slot_size(slot)
439+
end)
440+
end
441+
442+
def max_settings_len(:trust_and_go) do
443+
ATECC508A.DataZone.slot_size(@settings_slot_trust_and_go)
444+
end
445+
434446
@doc """
435447
Return the settings block as a binary
436448
"""
437-
@spec get_raw_settings(ATECC508A.Transport.t()) :: {:ok, binary()} | {:error, atom()}
438-
def get_raw_settings(transport) do
439-
all_reads = Enum.map(@settings_slots, &ATECC508A.DataZone.read(transport, &1))
449+
@spec get_raw_settings(ATECC508A.Transport.t(), device_type()) ::
450+
{:ok, binary()} | {:error, atom()}
451+
def get_raw_settings(transport, device_type \\ :nerves_key) do
452+
if device_type == :nerves_key do
453+
all_reads = Enum.map(@settings_slots_nerves_key, &ATECC508A.DataZone.read(transport, &1))
454+
455+
case Enum.find(all_reads, fn {result, _} -> result != :ok end) do
456+
nil ->
457+
raw = Enum.map_join(all_reads, fn {:ok, contents} -> contents end)
458+
{:ok, raw}
440459

441-
case Enum.find(all_reads, fn {result, _} -> result != :ok end) do
442-
nil ->
443-
raw = Enum.map_join(all_reads, fn {:ok, contents} -> contents end)
444-
{:ok, raw}
460+
error ->
461+
error
462+
end
463+
else
464+
case ATECC508A.DataZone.read(transport, @settings_slot_trust_and_go) do
465+
{:ok, data} ->
466+
{:ok, data}
445467

446-
error ->
447-
error
468+
error ->
469+
error
470+
end
448471
end
449472
end
450473

451474
@doc """
452475
Return all of the setting stored in the NervesKey as a map
453476
"""
454-
@spec get_settings(ATECC508A.Transport.t()) :: {:ok, map()} | {:error, atom()}
455-
def get_settings(transport) do
456-
with {:ok, raw_settings} <- get_raw_settings(transport) do
477+
@spec get_settings(ATECC508A.Transport.t(), device_type()) :: {:ok, map()} | {:error, atom()}
478+
def get_settings(transport, device_type \\ :nerves_key) do
479+
with {:ok, raw_settings} <- get_raw_settings(transport, device_type) do
457480
try do
458481
settings = :erlang.binary_to_term(raw_settings, [:safe])
459482
{:ok, settings}
@@ -470,10 +493,10 @@ defmodule NervesKey do
470493
be used with care since there's no protection against a race condition with
471494
other NervesKey users.
472495
"""
473-
@spec put_settings(ATECC508A.Transport.t(), map()) :: :ok
474-
def put_settings(transport, settings) when is_map(settings) do
496+
@spec put_settings(ATECC508A.Transport.t(), map(), device_type()) :: :ok
497+
def put_settings(transport, settings, device_type \\ :nerves_key) when is_map(settings) do
475498
raw_settings = :erlang.term_to_binary(settings)
476-
put_raw_settings(transport, raw_settings)
499+
put_raw_settings(transport, raw_settings, device_type)
477500
end
478501

479502
@doc """
@@ -482,14 +505,19 @@ defmodule NervesKey do
482505
This overwrites all of the settings and should be used with care since there's
483506
no protection against race conditions with other users of this API.
484507
"""
485-
@spec put_raw_settings(ATECC508A.Transport.t(), binary()) :: :ok
486-
def put_raw_settings(transport, raw_settings) when is_binary(raw_settings) do
487-
if byte_size(raw_settings) > @settings_max_length do
488-
raise "Settings are too large and won't fit in the NervesKey. The max raw size is #{@settings_max_length}."
508+
@spec put_raw_settings(ATECC508A.Transport.t(), binary(), device_type()) :: :ok
509+
def put_raw_settings(transport, raw_settings, device_type) when is_binary(raw_settings) do
510+
if byte_size(raw_settings) > max_settings_len(device_type) do
511+
raise "Settings are too large and won't fit in the NervesKey. The max raw size is #{max_settings_len(device_type)}."
489512
end
490513

491-
padded_settings = pad(raw_settings, @settings_max_length)
492-
slots = break_into_slots(padded_settings, @settings_slots)
514+
padded_settings = pad(raw_settings, max_settings_len(device_type))
515+
516+
slots =
517+
case device_type do
518+
:nerves_key -> break_into_slots(padded_settings, @settings_slots_nerves_key)
519+
:trust_and_go -> break_into_slots(padded_settings, [@settings_slot_trust_and_go])
520+
end
493521

494522
Enum.each(slots, fn {slot, data} -> ATECC508A.DataZone.write(transport, slot, data) end)
495523
end

0 commit comments

Comments
 (0)