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

shared: Introduce max_message_size_… features #331

Merged
merged 10 commits into from
Feb 3, 2025
2 changes: 1 addition & 1 deletion lakers-python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ license.workspace = true
pyo3 = { version = "0.22", features = ["extension-module"] }
lakers = { package = "lakers", path = "../lib", default-features = false, features = [ "log" ] }
lakers-ead-authz = { path = "../ead/lakers-ead-authz", features = [ "log" ] }
lakers-shared = { path = "../shared", features = ["python-bindings", "quadruple_sizes"] }
lakers-shared = { path = "../shared", features = ["python-bindings", "large_buffers"] }
lakers-crypto = { path = "../crypto", default-features = false, features = ["rustcrypto"] }
log = "0.4"
pyo3-log = "0.11.0"
Expand Down
3 changes: 2 additions & 1 deletion lakers-python/test/test_lakers.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,9 @@ def test_edhoc_error():

def test_buffer_error():
initiator = EdhocInitiator()
initiator.prepare_message_1()
with pytest.raises(ValueError) as err:
_ = initiator.parse_message_2([1] * 1000)
_ = initiator.parse_message_2(cbor2.dumps(bytes([1] * 10000)))
assert str(err.value) == "MessageBufferError::SliceTooLong"

@pytest.mark.parametrize("cred_r_transfer", [CredentialTransfer.ByReference, CredentialTransfer.ByValue])
Expand Down
55 changes: 48 additions & 7 deletions shared/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,52 @@ rstest = "0.21.0"
default = [ ]
python-bindings = ["pyo3", "hex"]

## For all arbitrarily limited buffers, pick 4x the current default.
## For all arbitrarily limited buffers, pick the maximum.
##
## On the long run, this might be replaced with a more fine-grained feature set
## picking the minimum size of all the items, or even an option to generalize,
## but this provides an easy way to allow unconstrained systems to stomach
## larger sizes (especially for experimentation) without making sizes explode
## on embedded.
quadruple_sizes = []
## This provides an easy way to allow unconstrained systems to stomach larger
## sizes (especially for experimentation).
large_buffers = [
"max_message_size_len_1024",
"max_kdf_content_len_1024",
"max_buffer_len_1024",
"max_connid_encoded_len_24",
]

## Precise control of `MAX_MESSAGE_SIZE_LEN`.
##
## If any of those is set, they override the default of 192. If multiple are
## set, the highest wins.

max_message_size_len_256 = []
max_message_size_len_320 = []
max_message_size_len_384 = []
max_message_size_len_448 = []
max_message_size_len_512 = []
max_message_size_len_1024 = []

## Precise control of `MAX_KDF_CONTENT_LEN`.
##
## If any of those is set, they override the default of 256. If multiple are
## set, the highest wins.

max_kdf_content_len_320 = []
max_kdf_content_len_384 = []
max_kdf_content_len_448 = []
max_kdf_content_len_512 = []
max_kdf_content_len_1024 = []

## Precise control of `MAX_BUFFER_LEN`.
##
## If any of those is set, they override the default of 320. If multiple are
## set, the highest wins.

max_buffer_len_384 = []
max_buffer_len_448 = []
max_buffer_len_512 = []
max_buffer_len_1024 = []

## Control of `MAX_CONNID_ENCODED_LEN`.
##
## If this is not set, the minimum sensible default (8 bytes) is used.

max_connid_encoded_len_24 = []
77 changes: 74 additions & 3 deletions shared/cbindgen.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,83 @@ header = """
* ================================================================================================
* WARNING: This file is automatically generated by cbindgen. Manual edits are likely to be lost.
* ================================================================================================
*/"""
include_guard = "LAKERS_SHARED_H"
*/

#ifndef LAKERS_SHARED_H
#define LAKERS_SHARED_H

/* Manually implemented to work around https://github.com/mozilla/cbindgen/issues/1018 */

#if defined(_MAX_MESSAGE_SIZE_LEN_1024)
#define MAX_MESSAGE_SIZE_LEN 1024
#elif defined(_MAX_MESSAGE_SIZE_LEN_512)
#define MAX_MESSAGE_SIZE_LEN 512
#elif defined(_MAX_MESSAGE_SIZE_LEN_448)
#define MAX_MESSAGE_SIZE_LEN 448
#elif defined(_MAX_MESSAGE_SIZE_LEN_384)
#define MAX_MESSAGE_SIZE_LEN 384
#else
#define MAX_MESSAGE_SIZE_LEN 256 + 64
#endif

#if defined(_MAX_KDF_CONTENT_LEN_1024)
#define MAX_KDF_CONTEXT_LEN 1024
#elif defined(_MAX_KDF_CONTENT_LEN_512)
#define MAX_KDF_CONTEXT_LEN 512
#elif defined(_MAX_KDF_CONTENT_LEN_448)
#define MAX_KDF_CONTEXT_LEN 448
#elif defined(_MAX_KDF_CONTENT_LEN_384)
#define MAX_KDF_CONTEXT_LEN 384
#elif defined(_MAX_KDF_CONTENT_LEN_320)
#define MAX_KDF_CONTEXT_LEN 320
#else
#define MAX_KDF_CONTEXT_LEN 256
#endif

#if defined(_MAX_KDF_CONTENT_LEN_1024)
#define MAX_BUFFER_LEN 1024
#elif defined(_MAX_KDF_CONTENT_LEN_512)
#define MAX_BUFFER_LEN 512
#elif defined(_MAX_KDF_CONTENT_LEN_448)
#define MAX_BUFFER_LEN 448
#elif defined(_MAX_KDF_CONTENT_LEN_384)
#define MAX_BUFFER_LEN 384
#else
#define MAX_BUFFER_LEN 256 + 64
#endif

#if defined(_MAX_CONNID_ENCODED_LEN_24)
#define MAX_CONNID_ENCODED_LEN 24
#else
#define MAX_CONNID_ENCODED_LEN 8
#endif
"""
trailer = """
#endif /* LAKERS_SHARED_H */
"""
# Done manually so that the manual parts of the MAX_MESSAGE_SIZE_LEN_xxx etc
# features can be placed after the include guard:
# include_guard = "LAKERS_SHARED_H"
cpp_compat = true

[defines]
"feature = quadruple_sizes" = "QUADRUPLE_SIZES"
"feature = large_buffers" = "LARGE_BUFFERS"
"feature = max_message_size_len_256" = "_MAX_MESSAGE_SIZE_LEN_256"
"feature = max_message_size_len_320" = "_MAX_MESSAGE_SIZE_LEN_320"
"feature = max_message_size_len_384" = "_MAX_MESSAGE_SIZE_LEN_384"
"feature = max_message_size_len_448" = "_MAX_MESSAGE_SIZE_LEN_448"
"feature = max_message_size_len_512" = "_MAX_MESSAGE_SIZE_LEN_512"
"feature = max_message_size_len_1024" = "_MAX_MESSAGE_SIZE_LEN_1024"
"feature = max_kdf_content_len_320" = "_MAX_KDF_CONTENT_LEN_320"
"feature = max_kdf_content_len_384" = "_MAX_KDF_CONTENT_LEN_384"
"feature = max_kdf_content_len_448" = "_MAX_KDF_CONTENT_LEN_448"
"feature = max_kdf_content_len_512" = "_MAX_KDF_CONTENT_LEN_512"
"feature = max_kdf_content_len_1024" = "_MAX_KDF_CONTENT_LEN_1024"
"feature = max_buffer_len_384" = "_MAX_BUFFER_LEN_384"
"feature = max_buffer_len_448" = "_MAX_BUFFER_LEN_448"
"feature = max_buffer_len_512" = "_MAX_BUFFER_LEN_512"
"feature = max_buffer_len_1024" = "_MAX_BUFFER_LEN_1024"
"feature = max_connid_encoded_len_24" = "_MAX_CONNID_ENCODED_LEN_24"

[export]
include = [
Expand Down
69 changes: 51 additions & 18 deletions shared/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,23 @@ use pyo3::prelude::*;
#[cfg(feature = "python-bindings")]
mod python_bindings;

/// Configured upscaling applied to fixed-size buffers
///
/// Do not rely on this: It is only pub because cbindgen needs it.
#[cfg(not(feature = "quadruple_sizes"))]
#[doc(hidden)]
pub const SCALE_FACTOR: usize = 1;
#[cfg(feature = "quadruple_sizes")]
#[doc(hidden)]
pub const SCALE_FACTOR: usize = 4;

// TODO: find a way to configure the buffer size
// need 128 to handle EAD fields, and 192 for the EAD_1 voucher
pub const MAX_MESSAGE_SIZE_LEN: usize = SCALE_FACTOR * (128 + 64);
// When changing this, beware that it is re-implemented in cbindgen.toml
pub const MAX_MESSAGE_SIZE_LEN: usize = if cfg!(feature = "max_message_size_len_1024") {
1024
} else if cfg!(feature = "max_message_size_len_512") {
512
} else if cfg!(feature = "max_message_size_len_448") {
448
} else if cfg!(feature = "max_message_size_len_384") {
384
} else if cfg!(feature = "max_message_size_len_320") {
320
} else if cfg!(feature = "max_message_size_len_256") {
256
} else {
// need 128 to handle EAD fields, and 192 for the EAD_1 voucher
128 + 64
};

pub const ID_CRED_LEN: usize = 4;
pub const SUITES_LEN: usize = 9;
Expand All @@ -61,9 +65,35 @@ pub const MAC_LENGTH_3: usize = MAC_LENGTH_2;
pub const ENCODED_VOUCHER_LEN: usize = 1 + MAC_LENGTH; // 1 byte for the length of the bstr-encoded voucher

// maximum supported length of connection identifier for R
pub const MAX_KDF_CONTEXT_LEN: usize = SCALE_FACTOR * 256;
//
// When changing this, beware that it is re-implemented in cbindgen.toml
pub const MAX_KDF_CONTEXT_LEN: usize = if cfg!(feature = "max_kdf_content_len_1024") {
1024
} else if cfg!(feature = "max_kdf_content_len_512") {
512
} else if cfg!(feature = "max_kdf_content_len_448") {
448
} else if cfg!(feature = "max_kdf_content_len_384") {
384
} else if cfg!(feature = "max_kdf_content_len_320") {
320
} else {
256
};
pub const MAX_KDF_LABEL_LEN: usize = 15; // for "KEYSTREAM_2"
pub const MAX_BUFFER_LEN: usize = SCALE_FACTOR * 256 + 64;

// When changing this, beware that it is re-implemented in cbindgen.toml
pub const MAX_BUFFER_LEN: usize = if cfg!(feature = "max_buffer_len_1024") {
1024
} else if cfg!(feature = "max_buffer_len_512") {
512
} else if cfg!(feature = "max_buffer_len_448") {
448
} else if cfg!(feature = "max_buffer_len_384") {
384
} else {
256 + 64
};
pub const CBOR_BYTE_STRING: u8 = 0x58u8;
pub const CBOR_TEXT_STRING: u8 = 0x78u8;
pub const CBOR_UINT_1BYTE: u8 = 0x18u8;
Expand All @@ -89,13 +119,16 @@ pub const KID_LABEL: u8 = 4;

pub const ENC_STRUCTURE_LEN: usize = 8 + 5 + SHA256_DIGEST_LEN; // 8 for ENCRYPT0

pub const MAX_EAD_SIZE_LEN: usize = SCALE_FACTOR * 64;
pub const MAX_EAD_SIZE_LEN: usize = 64;

/// Maximum length of a [`ConnId`] (`C_x`).
///
/// This length includes the leading CBOR encoding byte(s).
// If ints had a const `.clamp()` feature, this could be (8 * SCALE_FACTOR).clamp(1, 23).
const MAX_CONNID_ENCODED_LEN: usize = if cfg!(feature = "quadruple_sizes") {
// Note that when implementing larger sizes than 24, the encoding will need to use actual CBOR
// rather than masking a known short length into a byte.
//
// When changing this, beware that it is re-implemented in cbindgen.toml
const MAX_CONNID_ENCODED_LEN: usize = if cfg!(feature = "max_connid_encoded_len_24") {
24
} else {
8
Expand Down