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

Add CHERIoT support #156

Merged
merged 2 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions impl/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ static int errno;
# include <string.h>
#endif

#if defined (__CHERIOT__)
static int errno;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come <errno.h> exists (since you didn't add checks around its inclusion and usage of constants such as EINTR) but doesn't define errno? Isn't it available as a global?

Copy link
Contributor Author

@PhilDay-CT PhilDay-CT Jan 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see why that would be confusing. CHERIoT is designed to have a very strong compartment model where each compartment is in effect a separate memory domain. When running in a compartment a thread can access only the globals and stack space of that compartment. When making a call from one compartment to another all data has to be explicitly passed in and returned via the stack, and the called compartment has no access to stack of the compartment that called it. If there is a failure inside a compartment, such as an invalid memory access, then the impacts of that are guaranteed to be fully contained to the compartment that failed, and everything in the calling compartment is safe. This lets us, for example, wrap libhydrogen in a compartment and be sure without having to inspect the code, that even if there was some path that could lead to buffer overrun it could never affect anything else in the system. We still have an errno.h because we use some of the enumeration values as return values from cross-compartment calls, but don't have a system wide errno var as that would break the memory mode. Declaring errno it here in effect creates a global just within each compartment that includes libhydrogen.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. libhydrogen only sets errno in codecs, and applications usually just check the return value of the functions anyway. So, not a big deal.

#endif

#if !defined(__unix__) && (defined(__APPLE__) || defined(__linux__))
# define __unix__ 1
#endif
Expand Down
2 changes: 2 additions & 0 deletions impl/random.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ static TLS struct {
# include "random/ch32.h"
#elif defined(CHIBIOS)
# include "random/chibios.h"
#elif defined(__CHERIOT__)
# include "random/cheriot.h"
#else
# error Unsupported platform
#endif
Expand Down
24 changes: 24 additions & 0 deletions impl/random/cheriot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
uint32_t rand_32();

static int
hydro_random_init(void)
{
const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' };
hydro_hash_state st;
uint16_t ebits = 0;

hydro_hash_init(&st, ctx, NULL);

while (ebits < 256) {
uint32_t r = rand_32();

//delay(10);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this delay necessary, or is that leftover debugging code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good spot - not needed, I'll take it out

hydro_hash_update(&st, (const uint32_t *) &r, sizeof r);
ebits += 32;
}

hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state);
hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state);

return 0;
}