From 5d58dc534b9109ee261de052cfa49edc3b1f0c1a Mon Sep 17 00:00:00 2001 From: Max Tropets Date: Fri, 20 Mar 2026 12:21:49 +0000 Subject: [PATCH] Avoid phdr/payload copy on TBS --- Cargo.lock | 4 ++-- Cargo.toml | 4 ++-- src/cbor.rs | 22 ++++++++++++++++++++++ src/cose.rs | 18 +++++++++++------- src/sign.rs | 2 +- 5 files changed, 38 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8670fc..895be44 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 4 [[package]] name = "cborrs" version = "0.1.0" -source = "git+https://github.com/project-everest/everparse.git?tag=v2026.02.25#f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" +source = "git+https://github.com/project-everest/everparse.git?rev=f4cd5ffa183edd5cc824d66588012bcf8d0bdccd#f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" dependencies = [ "static_assertions", ] @@ -13,7 +13,7 @@ dependencies = [ [[package]] name = "cborrs-nondet" version = "0.1.0" -source = "git+https://github.com/project-everest/everparse.git?tag=v2026.02.25#f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" +source = "git+https://github.com/project-everest/everparse.git?rev=f4cd5ffa183edd5cc824d66588012bcf8d0bdccd#f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" dependencies = [ "static_assertions", ] diff --git a/Cargo.toml b/Cargo.toml index 6486a63..7ab661e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,5 +14,5 @@ warnings = "deny" [dependencies] openssl-sys = "0.9" -cborrs = { git = "https://github.com/project-everest/everparse.git", tag = "v2026.02.25" } -cborrs-nondet = { git = "https://github.com/project-everest/everparse.git", tag = "v2026.02.25" } +cborrs = { git = "https://github.com/project-everest/everparse.git", rev = "f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" } # v2026.02.25 +cborrs-nondet = { git = "https://github.com/project-everest/everparse.git", rev = "f4cd5ffa183edd5cc824d66588012bcf8d0bdccd" } # v2026.02.25 diff --git a/src/cbor.rs b/src/cbor.rs index 9cc7092..ba6c385 100644 --- a/src/cbor.rs +++ b/src/cbor.rs @@ -287,6 +287,28 @@ fn serialize_det(item: CborDet) -> Result, String> { Ok(buf) } +/// A CBOR item that borrows its data, for zero-copy serialization. +pub enum CborSlice<'a> { + TextStr(&'a str), + ByteStr(&'a [u8]), +} + +/// Serialize a CBOR array of borrowed items without intermediate copies. +pub fn serialize_array(items: &[CborSlice<'_>]) -> Result, String> { + let mut raw: Vec> = items + .iter() + .map(|item| match item { + CborSlice::TextStr(s) => cbor_det_mk_text_string(s) + .ok_or("Failed to make CBOR text string".to_string()), + CborSlice::ByteStr(b) => cbor_det_mk_byte_string(b) + .ok_or("Failed to make CBOR byte string".to_string()), + }) + .collect::>()?; + let array = cbor_det_mk_array(&mut raw) + .ok_or("Failed to build CBOR array".to_string())?; + serialize_det(array) +} + impl std::fmt::Debug for CborValue { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { diff --git a/src/cose.rs b/src/cose.rs index 5741751..5ea1ce3 100644 --- a/src/cose.rs +++ b/src/cose.rs @@ -1,4 +1,4 @@ -use crate::cbor::CborValue; +use crate::cbor::{CborSlice, CborValue, serialize_array}; use crate::ossl_wrappers::{ EvpKey, KeyType, WhichEC, WhichRSA, ecdsa_der_to_fixed, ecdsa_fixed_to_der, rsa_pss_md_for_cose_alg, @@ -56,14 +56,18 @@ fn insert_alg_value( /// To-be-signed (TBS). /// https://www.rfc-editor.org/rfc/rfc9052.html#section-4.4. +/// +/// Uses `serialize_array` with borrowed slices to avoid copying +/// `phdr` and `payload` into intermediate `Vec`s. These can +/// be large (payload especially), so we serialize directly from +/// the caller's buffers. fn sig_structure(phdr: &[u8], payload: &[u8]) -> Result, String> { - CborValue::Array(vec![ - CborValue::TextString(SIG_STRUCTURE1_CONTEXT.to_string()), - CborValue::ByteString(phdr.to_vec()), - CborValue::ByteString(vec![]), - CborValue::ByteString(payload.to_vec()), + serialize_array(&[ + CborSlice::TextStr(SIG_STRUCTURE1_CONTEXT), + CborSlice::ByteStr(phdr), + CborSlice::ByteStr(&[]), + CborSlice::ByteStr(payload), ]) - .to_bytes() } /// Produce a COSE_Sign1 envelope. diff --git a/src/sign.rs b/src/sign.rs index 69b7ce9..3202018 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -33,7 +33,7 @@ fn sign_with_ctx( msg.len(), ); if res != 1 { - return Err(format!("Failed to signature size, err: {}", res)); + return Err(format!("Failed to get signature size, err: {}", res)); } let mut sig = vec![0u8; sig_size];