Skip to content

New feature: SerializableState#48

Draft
ounsworth wants to merge 3 commits into
bcgit:release/0.1.2alphafrom
ounsworth:feature/serialize_state
Draft

New feature: SerializableState#48
ounsworth wants to merge 3 commits into
bcgit:release/0.1.2alphafrom
ounsworth:feature/serialize_state

Conversation

@ounsworth

Copy link
Copy Markdown
Contributor

This was a feature requested by Simo to be able to pause an operation -- particularly in the middle of a do_update() ... do_update() ... do_final() flow -- stick the serialized crypto operation into a cache, and then resume it later. This is an important feature for implementing TLS loadbalancers that want to be able to cache out the HKDF state and resume it from a different box when the next flight of TCP messages come in.

The only "creative" thing I've added here is that all serialized states are prefixed with a 3-byte semantic version of the library and it's checked on load back in. The idea is that if we ever need to change the serialization of some object, then we can add a guard to refuse to load a serialized object from before the guard (or keep both versions of the deserializer and switch based on the version tag, or whatever ... #futureProofing).

@ounsworth

Copy link
Copy Markdown
Contributor Author

For now, I have added the trait and impl'd it for SHA2.

I'll pause here and give a chance for people to give feedback before I continue with doing the same for:

  • SHA3
  • HMAC
  • HKDF
  • ML-DSA

///* if a == b => 0
///* if a > b => 1
pub fn cmp_lib_ver(a: &[u8; 3], b: &[u8; 3]) -> i8 {
if a[0] < b[0] {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

let a_ver = a[2] << 16 | a[1] << 8 | a[0]
let b_ver = b[2] << 16 | b[1] << 8 | b[0]

if a_ver < b_ver
   return -1;
else if ...

Also, give it a type such as SemVer([u8; 3]), and then impl Ord would be a much rusty way. Or even better,

struct SemVer(u32);
impl SemVer
   fn new(major: u8, minor: u8, patch: u8) -> Self {
     Self(major << 16 | ...)
   }

Comment thread crypto/sha2/src/sha256.rs
// insert the version tag
let out: &mut [u8; 105] = add_lib_ver(&mut out_to_return).try_into().unwrap();

// state.h: [u32; 8]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

What is state.h?

Comment thread crypto/sha2/src/sha256.rs
out[40..104].copy_from_slice(&self.x_buf);

// x_buf_off: usize
// in general, a usize should be serialized into a u64, but in this case, it can't ever be larger than 64

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

However, usize can be u32 on 32-bit platforms.

Comment thread crypto/sha2/src/sha256.rs

impl<PARAMS: SHA2Params> SerializableState<108> for SHA256Internal<PARAMS> {
fn serialize_state(&self) -> [u8; 108] {
let mut out_to_return = [0u8; 108];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Where 108 and other sizes coming from?

Comment thread crypto/sha2/Cargo.toml
[dependencies]
bouncycastle-core.workspace = true
bouncycastle-utils.workspace = true
serde = { version = "1.0.228", features = ["derive"] }

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Is it used?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants