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

securechip/optiga: limit unlock to 10 failed attempts #1344

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

benma
Copy link
Collaborator

@benma benma commented Dec 18, 2024

See commit messages.

@benma benma changed the title Optiga lowctr securechip/optiga: limit unlock to 10 failed attempts Dec 18, 2024
@benma benma requested a review from NickeZ December 18, 2024 10:34
@benma benma marked this pull request as ready for review December 18, 2024 10:34
benma and others added 4 commits January 21, 2025 13:34
This commit implements the securechip.h interface for the Optiga Trust
M V3, with an interface and configuration roughly corresponding to how
we use the ATECC608 secure chip:

- A KDF key that is internally generated and cannot be read and
written from the host MCU
- A KDF key that is generated on the host
- A monotonic counter attached to the first KDF key which limits the
  maxmium number of uses of the key over the lifetime of the device
- Attestation key that is internally generated and used to sign
  attestation challenges

The factory setup configures the metadata of each object we use,
setting the state to Operational. After this, metadata cannot be
changed, and the access conditions apply as specified.

Shielded communication encrypts the communication with the chip and is
active and enforced through the metadata access configs. It roughly
corresponds to IO protection in the ATECC608.

In the ATECC608, we additionally authorize each command with the
authorization_key, another pre-shared secret. The Optiga offers the
same functionality, but we don't use it to authorize all commands, as
it is redundant to using the shielded communication in terms of
enabling the host MCU to execute commands.

Co-Authored-By: Niklas <[email protected]>
To disable interrupts when processing Optiga commands.
So the two different securechip implementations (ATECC608 and Optiga
Trust M V3) can implement stretching differently. This is needed
because in the Optiga, we will add an additional stretching step.
The MCU limits unlock attempts to 10 before resetting.

The ATECC securechip further limits the total unlock
attempts (successful or failed) to a large monotonic counter, ~730k.

In the Optiga we have the same, but with a lower limit due to the chip
spec (~600k).

This commit additionally adds a small counter that limits the unlocks
to 10 failed attempts, same as the MCU. When the counte reaches the
limit, no further attempts are possible until reset.

When the correct password is entered, the small counter resets to 0.

To achieve this, three new slots are added that specifically deal with
this small counter. The PASSWORD_SECRET is a key included in the
password key stretch, so overwriting/resetting invalidates the
password and makes it impossible to unlock or brute force.

The PASSWORD_SECRET is initialized to a random value when a password
is set. It also authorizes changing the PASSWORD object and the
PASSWORD_COUNTER small counter in order to reset it. It can only be
read when authorized using the PASSWORD object, i.e. when entering the
correct password, which allows us to reset the counter and also to use
the PASSWORD_SECRET in the password stretching.

The approach is inspired by Trezor, which has a similar setup a small
monotonic counter: https://github.com/trezor/trezor-firmware/blob/78cce0ba04436b2ec8a72d00d157a1dd37055572/core/embed/sec/optiga/optiga.c#L35

securechip_init_new_password and securechip_reset_keys are added to
the securechip interface to set the new password and to reset all keys
involved in the key stretch and the password.

When the small counter threshold is reached, further attempts always
fail until reset. The MCU also keeps track of the 10 attempts and
resets after 10 failed ones, so the securechip error condition is
never exercised, similar to the large lifetime counter.
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

Successfully merging this pull request may close these issues.

1 participant