i feel a little more comfortable with this because there are
checks that *any* key in that slot would be treated as a devkey
and would lead to key erasure. so just in case i messed up
something in the other checks, this would trigger a key erasure.
I think there is no way around signing at least a beta image
containing the third party keys if i truly want to check all
the paths, so trying to isolate what it can do is important.
by doing this we make this safer by ensuring that the public
keys are valid public keys, allowing us to sign these images
with production keys and not accidentally signing a weak
public key.
this allows us to simulate a third party firmware's behavior
so we can test that collateral key states go through the right
set of state transitions in various test cases.
the collateral test is also made more precise and can now
report unititialized/permission denied state
This just populates a pubkey block with random data, simulating
a third party firmware. A fake pubkey block can't boot anything
else because we can't sign a firmware that matches that. But,
it's also good enough to be able to test collateral key states.
The original check on public key tag was "if the tag doesn't match
one of four approved tags erase secrets".
With third party images, third parties can pick their own tags - so
as-writ this would constrain third parties to have to use the same tags
as baochip, which is too restrictive.
Change the check to explicitly trigger erasure if and only if
the tag is "dev ". Note there are plenty of other checks around as
well so this is not the sole check, thus I think loosening this
permission is good for keeping hygiene between third party firmwwares
and baochips own firmwares.
Now that the sensitive keys are provisioned in Xous and not in
boot1, there is no need to have a dependency on the avalanche
generator (and in fact, in practice, it's never used because
the random data that is collected is always collected before
the board type is set to even allow usage of the avalanche generator).
To wit: The only bits that are created using the ring oscillator
are public random identifiers such as the UUID, which are not
security critical pieces of data.
Removing this unused path simplifies the bootloader code.
Reviewing the code, I was decomposing multi-element slots
into individual slots, but erasing them as a multi-element slot.
This results in unnecessary churn.
The barrier to doing a simple check on the full slot all at
once was a missing API for unchecked reads of the full slot:
during checking, we want to be able to retrieve the contents
even if technically the ACL access is denied (note that the
ACL is enforced in *hardware*, the software based check of
the ACL is just a "belt and suspenders" check).
So, this patch adds a routine that allows for an `unsafe`
retrieval of the slot data regardless of the ACL, where the
safety condition is that the caller has to be aware that
junk data could be passed to it if the ACL isn't correct.
this will at least give us a hint as to why a boot1 failed to
boot. It does hand an attacker some information, but we also
need information to debug e.g. RMA and field failures.
this allows the BIO to continue to function even though
the CPU core is in WFI. It isn't running at full speed, but
for some applications (such as WS2812 LED driving) the lower
speed is perfectly adequate and you save a lot of power
by turning off the CPU core.
while debugging the disconnect issue, discovered that the timeout
routine in `std` was extremely wastefully blasting the name server
to connect to the ticktimer every time it was called. yowch!
this patch does the following:
- cache the ticktimer connection in an AtomicU32
- check if the transaction is done on the "Fast path" before
doing any waiting
- check again after fetching time - at this point, most transacitons
are actually likely done
- only then, do the wait loop
this greatly speeds up screen drawing, it seems.
the library is a bit too specific to a given application
without the generic API being exposed. i.e. the way it was
originally generated would imply that every scenario for
the driver would need to be implemented in the library-side
HAL, when in reality, I think it makes much more sense for
the customization of registers (especially when debugging)
to live near the device side.
the implementation is flawed - because multiple APIs hit
a single server, the reference count can reach zeoro for
a given interface, and trigger a disconnect, while another
API is still using it.
the long-term fix for this, if we wanted auto-disconnect,
would be to wrap the connection query into a helper that
uses an Arc to ensure the count is maintained across all
possible interfaces.
However, for the HAL, it's likely that pretty much every
server is going to want this connection, and want it to
stay around so - we'll just remove the auto-disconnect
idiom for now and figure something out if we end up
hitting a connection resource limit on a service that
truly only needs the HAL connection early on in its
lifecycle and never needs it again.
the kernel is supposed to first search for an existing
connection before allocating a new one. this patch fixes the
order of search so that it meets this spec.
previously it was preferring to allocate a new connection
before re-using an old one. I think we got away with this
because we just didn't have that many connections.
it'll be interesting to see if this causes any regressions
on Precursor.
Default apps for base xous configs are now eliminated - this
allows third party builds to add their apps without having to
delete the default apps used for initial testing (the upshot is
that the CI scripts elsewhere are now all modified to include the
apps I'm using to test the system; which is fine).
So now, `dabao` and `baosec` build what is a baseline set of
services that I think are expected in either platform. In the case
of dabao, apps get stuck in the detached-app area; in the case of baosec,
apps are stick in swap.
So:
`cargo xtask baosec bao-console vault2`
by default sticks the app `bao-console` and `vault2` into swap.
If you want one of these programs to go into RRAM instead, you would
specify the build like this:
`cargo xtask baosec bao-console~flash vault2`
The `~<region>` syntax indicates that the thing to the left of `~`
is the name of the app; and to the right is a region spec, one of:
[swap, flash, ram].
No checking is done that these regions are valid or even good
for placing these things, the image just tries its best to whack 'em
in there. If you blow out the size of the kernel, at least, a
warning will be emitted.
This change enables more flexible out-of-tree options for
developers who don't want to build the whole Xous kernel, but
at the moment, caveat hacker - things are still in flux and under
heavy development. I think in about 2-3 months things will settle
down enough that we'll cut a release and then the APIs should be
cleaner/more stable, but for now anyone developing with a pre-release
dabao board is recommended to either build kernel from scratch or
at least fetch the latest CI image off of the CI server if things
seem squirrelly.
for out of tree builds, we'll just stick with the default code
of '1': if you're doing a build out of tree, it's assumed that
you don't care about security (not tying your application to
a given OS version opens up an attack surface; presumably if
you're doing something security-critical, the extra hundred
megabytes to clone the xous-core repo isn't a big deal? but
if you're just trying to blink some LEDs you really don't care
about the anti-rollback feature).
this forces the semver to nil so that we don't get errors in
a signing routine that lacks access to versioning.
The upshot is that out of tree apps have no version assigned
to them, and they can't be checked for version compatibility.
The problem is that this feature, while neat, pulls in a huge
amount of code into the SBOM, a lot of which looks pretty scary,
and we're also including the ability to hit the network in the
build system which is also scary and potentially full of software
supply chain exploits.
So, while it would be "neat" to have the system be "smart enough"
to guess a semver based on a git rev of xous-core without having
to pull down tags or clone the full repo, the cost is a huge amount
of tooling and code and trusting a very large attack surface to
also not use the same mechanism to exfiltrate your keys, hack
your computer, or otherwise cause abuse.
For such a minor feature, I think this risk is not worth it.
cargo xtask renode-image can create teh renode images
I think make-renode-boot is actually a really old experiment
that was then pulled into the xtask image generator, but never
pruned. This *has* to be pruned now in order for cargo publish
to work so that the xous bin utils can be installable.
The panic on failure causes incompatibility with older boot0's
that don't set up the collateral area correctly.
Make the failure more graceful, but we also promise ourselves
to add CI tests to check for this explicitly, because we can't
just rely on panics to enforce behavior.