heap can't be initialized before suspend/resume is checked
bao1x doesn't have suspend/resume, and requires heap early
on to check signatures
so heap initializationg is now optionally included in two
locations to meet the conflicting requirements per platform.
loader was previously just accepting a dev key image and not
doing any countermeasures. now, kernel, detached-app, or swap
not being properly signed activates countermeasuers.
also select the swap key fallback for checking swap. this is
"half" of the solution, the other half will have to be implemented
in userspace - if we do it at all. i'm starting to think that
the swap encryption is not necessary, it was introduced
under the assumption that signature checking swap would be
too slow, but it's not. so maybe this feature will get dropped.
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.
"detached-apps" are Xous applications loaded into a region
of memory-mapped FLASH (and thus memory-mapped applications)
that are separate from the main xous.img image.
This allows developers to work on "just their app" instead
of having to upload the whole Xous ball.
Currently the only configuration that supports this is the
dabao configuration.
Turns out we 'just got lucky' with our previous success
in getting arg extension to work (scary!!): the arg format
is pretty uhh...flexible...in terms of what it will accept
for arguments.
This fixes those bugs, the arg copy looks clean now, and
also removed the over-allocation problem by descending
the new argument list twice, once to sum the space needed,
and once to actually do the copy.
Swap can be "secured" in two ways:
1) it can be re-encrypted to a secure, locally generated key
2) it can be signature-checked with a public key.
(2) is provided as a path to receive updates. Updates are distributed
as "encrypted" (with the "0" key), but signed with a public key.
Once the update is validated, it's meant to be re-encrypted
with a per-device unique key.
A big reason for the re-encryption is because the swap is already
encrypted, we can rely on the AEAD for validation, and skip the
signature check (saves time on boot). Recall that the reason
we don't just do a sig-check and run is that is a TOCTOU:
it's pretty trivial to execute a mux that swaps out the FLASH
memory after the signature check with another version that has
malicious stuff in it. So we go with a sector-by-sector
AEAD that's ideally encrypted to a locally generated key.
It also offers the possibility to prevent malleability of the
swap data between devices, as many public-key signed images
could be floating around, including old versions that include
insecurities (e.g. prevents downgrade attack by replacing
an up to date image with an older signed image with an insecurity).
However, this latter possibility requires the user interface
to be correctly setup to prevent malleability by asking users
to opt-in to partition re-encryption. Need to consider this user
experience flow - kicking the can down the line, but that time
is coming soon.
previously we just panic'd (which is actually the right behavior
for this type of error) but because we now have a reason for it
to fail (e.g. testing the encryption key) we make this fallible.
in all other places we just unwrap() - there is no fallback if
decryption fails, boot should just halt.
but this allows us to check which decryption key is deployed
in phase 1.
- loader heap is now fixed in a "throw-away" region of memory.
this means the heap should only be used sparingly, and somewhat
dangerously, because the values can't persist beyond the lifetime
of the loader.
- signature validation moved earlier
- fixup swap structures to refer to the API so that image creation
is easier/consistent
the original rather unsafe version is replaced with a more readable
version that has a number of safety checks applied.
in the process of doing this, we now support merging of multiple
argument regions and a variable number of tags to merge.
tested to work on at least the base case of one swap region to
merge into the list.
this is a fairly complicated bit of legacy code that we're
trying to make slightly better/more readable.
some docs are added, as well as getting rid of a bunch of
"magic" constants, instead preferring to map things into
structured data where possible.
also fixed the location of the heap allocation relative to
the boot flow. It's now in a spot where I think we can
safely put dynamically allocated kernel arguments.
The loader grew a lot of hair over the past few months as it
was abused as a baremetal environment for chip bring-up.
A baremetal environment was explicitly created to help with that,
so we don't have to pollute the loader with lots of unused features
and ancilliary code.
Furthermore, a decision was made to eliminate updates from the
loader code base - the loader is just for setting up Xous. This
allows the loader to be more platform-agnostic.
Boot1 instead contains all the platform-specific code for doing updates.
For completeness, we note that boot0 is a minimal piece of code that is the
first step in the chain of trust and is intended to be a read-only
segment of code that has public keys baked into it that are used
to bootstrap the rest of the ecosystem.
At this point, the loader is now slimmed down and runs. Still needs
testing to make sure the culling wasn't too aggressive, but I am
much happier with where this is landing as the loader is once again
just focused on getting Xous up and running.
The code base had evolved through several code names, interim
names, company names and chip names that alternatively did or did
not exist.
Baochip is the definitive name of the company, and the Baochip1x
(full part number BAO1X2S4F-WA) is the definitivey part number of
the SoC. For convenience, the part number is shortened to 'bao1x'
in most feature flags and variable references.
This commit fixes all of the odd names and removes some unmaintained
early targets.