-
Notifications
You must be signed in to change notification settings - Fork 31
Design
This section explains some design related topics of orion and how orion is built.
The types that orion uses have mostly been an inspiration based upon how sodiumoxide and Mundane use types.
Types are used extensively in the high-level API and this section gives an overview how a type that could hold sensitive data might be implemented.
orion uses the same approach to opaque types as those described by Mundane. Types are represented through a struct, where data is kept in a private field to limit access.
Specifically in the high-level interface, the type SecretKey
has a private field named value
, which is only accessible from the methods and traits that SecretKey
implements.
There are several traits that are important to implement, when a type is holding sensitive data or otherwise needs extra protection, to avoid a user accidentally misusing it. These are the traits that the SecretKey
in the high-level API implement:
-
Drop
: This trait is theSecretKey
's destructor. As soon as it goes out of scope,Drop
zeroes out the sensitive data located in the fieldvalue
ofSecretKey
. Relevant information on this in the Security section. -
PartialEq
: This trait is implemented forSecretKey
to ensure that, wheneverSecretKey
is compared with another object of that type, the comparison will happen in constant-time. As such, if someone were to unknowingly try to insecurely compare, for example to authentication tags:A == B
, this would not result in a timing vulnerability. This is mainly implemented for misuse-resistance, as most modules already provide a secure verification function. -
Debug
: This trait is implemented in a way that makes it much harder for sensitive data inSecretKey
to be leaked into logs. Should someone try to print the data contained inSecretKey
, it would displaySecretKey {***OMITTED***}
instead of the actual data in thevalue
field. -
Default
: TheDefault
implementation lets a user initialize an object of typeSecretKey
by callinglet key = SecretKey::default();
. This will use a CSPRNG to generate aSecretKey
of a pre-defined length, which in this case is 256 bits. This is only provided to make it as easy as possible, for the user to useSecretKey
securely.
The functions presented here are what aim to give the minimum amount of access to SecretKey
, while still offering all the functionality one might need.
These are the functions that the SecretKey
in the high-level API implement:
-
from_slice()
: This lets the user initialize aSecretKey
object from a slice passed to this function. orion does not zero out the source slice, and a user of orion would have to take care of that themselves. -
unprotected_as_bytes()
: This function returns the data in thevalue
field ofSecretKey
as a byte slice. It is called unprotected because a user could copy the returned byte slice and save it elsewhere, without any of the protections thatSecretKey
offers. The documentation warns about the use of this, and the name has been selected to hopefully nudge users towards not using this function, unless strictly necessary. -
get_length()
: A simple function that returns the length of the data contained in thevalue
field ofSecretKey
. -
generate()
: This lets a user initialize aSecretKey
object by generating it using a CSPRNG with a provided length. This is offered in case users need longer keys than the default 256 bit.