identify_flash_reset_qpi's behavior has been revised to
include setting all relevant parameters so that the device
that is identified behaves identically to the model device
(e.g. Macronix), to the extent that it is possible. This
includes setting the QE bit.
The routine to check QE has been renamed to `flash_ensure_eq()`
to reflect that it is safe to call multiple times: it checks
if the bit is already set, and if so, doesn't do anything.
Thus it can be routinely called without worry of wearing
out the device.
xtx devices still not fully working, but at least able to switch
in and out of spim modes in the face of uncertainty over which
device type is present.
also fixup a return-type bug in the std implementation for
bio pin settings
much more bio abstractions will be needed, but for now,
this branch is just focused on the keystore.
just learned of another ECO incoming that will tie the key
and data areas together in terms of access control from
the IFR region, so the nuisance key range has to have
its access control redefined to steer clear of the data
slots allocated that have write-protects on them.
pubkey block is added to the data ranges
also a oneway counter to keep track of pubkey validation
failures in boot0 is added
The motivation for this is to make the tester configuration
exactly identical to that used in production. Right now a
"cheater" step is used to set the board type to dabao and
enable boot waiting because in the test environment there
isn't a physical switch anyone can press to invoke that
behavior.
So, in order to get the test environment to work just like
production, the behavior goes from insta-die if no valid
image is found on the next stage, to "wait for new image".
This is slightly less secure of a default, but only slightly
so. Basically the previous scheme required someone to be
physically present to press the "give me a new image" button,
this one causes the system to automatically accept a new image.
I suppose the main downside is this does allow the possibility
of say, a fully remote, automated exploit to be delivered
if an adversary can damage the loader image such that it
doesn't pass signature check and then it will automatically
go into a mode looking for a new image, at which point
an arbitrary image could be potentially loaded (although
because the image would need to be signed, and there is
a trap that destroys secrets if a developer image is
presented, it wouldn't instantly lead to secret disclosure,
but it would be a denial of service).
The flip side is that with the paranoid default, developers
are "confused" by the silent failure of a brand new chip that
has no code loaded in it (because it goes catatonic until
the developer knows to press the load button).
The loader image is protected from writes after boot, so
in theory there isn't a direct path to "spoil" the loader
image and trigger this path, so it's not like we're just
hanging in the wind. It just means that there isn't a
full human-presence requirement as a defense in depth against
a potential denial of service if an adversary could find
a way to spoil the loader image.
If the DoS path is a concern, one option is to configure
the system such that the developer key is revoked. This
would disallow that from being recognized as a valid
image, and would also prevent the DoS from happening,
as it would require the adversary to present a valid,
signed image which presumably they can't as long as
the signing keys are kept safe.
rram handler for `std` requires the following additional features
over baremetal:
- mapped pages list, because a process has to "own" a page of RRAM
before writing to it. It's anticipated that the rram writer hardware is
"owned" by the keystore, so all write-access will be mediated by a
service in that PID
- irq-context handling of writes. this prevents writes from being
detached from their staging data, or other concurrent writes
from conflicting.
the more i test things the less confidence i have.
this fixes up a missing table entry in the table definition,
and then also adds a bypass routine - this is not actually
a hidden vulnerability, it's an explicit vulnerability until
the protect() routine is called. But it looks like we may have
to exploit it in order to transform our userstate in
the bootloader to one that has write-access to keys in order
to erase them in case of a developer boot.
only some keys are marked as writeable to harden against
potential oracle attacks, i.e., if we made all keys
erasable and an oracle attack was found, then the entire
key region can be exposed by the oracle attack.
Instead, some key material always persists, but a sufficiently
large amount of seed material is erased such that the key is not
recoverable by guessing the key.
the key setup seems to work correctly
but the data ACL setting doesn't "stick". The region
could be write-protected by some other element in the
CP/IFR config, need to dig a lot more. For now we need
to move on and crank out something to stick on the alpha
dabao boards...
add read/write specs as well to the slot definitions.
Not terribly happy with how this all worked out. The subtle
differences between Data and Keys is really irritating.
it's the sort of thing you would say "let's make a trait"
for it but then the two behave just differently enough
that I worry I can't make a trait generic enough to encompass
all the weird stuff that exists in the hardware.
The existing implementation definitely looks like trait
territory, but it currently hides the subtleties around
key/data chaining and secure crypto engine handling of
the two regions as distinct entities. so long as we don't
plan to use those things, traits are a good idea, but
i don't feel like I can reject using the crypto engine
features out of hand this early on just to make the
APIs nice and square.
'coreuser' is a slightly confusing term from the hardware
system because it's overloaded to mean some conceptually
related items that aren't implementation-wise essentially linked.
coreuser defines both some access protections on the main
array of the RRAM, and also some access protections on key
and data slots.
this patch includes some code that sets up the coreuser
functionality to a very simple scheme where just one PID
is trusted and the rest are not trusted. More complicated
schemes could be introduced with varying levels of trust
and dependencies but I like the analytical simplicity of
two states, so let's start there and complicate only when
absolutely necessary.
Data and key slots are hardware access-controlled areas that
can store sensitive data. Slot definitions come with a "spec"
field that defines what the access controls *should* be,
so that we can check them later.
In practice no user code should be manipulating these, but
there is an initial stage where a totally blank device needs
to be provisioned, hence the focus on correct specification
and checking of state, rather than convenient runtime manipulation
and update of the same.
on dabao targets the duart is unavailable, so, it's convenient to
have a uart-based debug option in the HAL. this patch creates a
flag that can allow either target.
- add range checking to control access to main array or secure
array. This is purely a software enforced check, but it is in
theory backed by hardware gating that is a back stop in case
an adversary can gain arbitrary code access
- rework the rram primitive to return an error type
- add a `std` implementation stub. It is still missing an IRQ
context handler which ensures that all RRAM writes are atomic,
e.g. you can't take an interrupt in the middle of an RRAM
write because it would screw up the buffer staging.
auth_data actually changes with each signing operation (ostensibly
to prevent replay of signatures coming from tokens) so it has
to be presented as data parallel to the signature, instead of
as a static filed baked into the key header.
This commit revises the header record to reflect this organizatio
of data and also revises the signature check to be in-line
with the protocol.
have to absorb a version change due to xous-semver change
might as well also update the utra/svd generator dependencies
since that's been held off for a long time now.
this is the agnostic version of all of the board targets, which
allows the boot1 to lookup based on the current configuration
which configurations to apply.
I think I've talked myself into giving away $0.20 of parts with
every dabao board so that everyone can run at full frequency.
Originally I thought I'd limit to the minimal configuration with
low frequency operation but since this is the main developer
platform all the benchmarks and first impressions will come
through this board. Crippling it with a slower clock frequency
by omitting the supplementary digital regulator seems
short-sighted, even if it means up slightly subsidizing things
with this extra cost.