Skip to content

Commit f9bdcd3

Browse files
committed
Debug more
1 parent 33fa615 commit f9bdcd3

2 files changed

Lines changed: 49 additions & 18 deletions

File tree

src/aead.rs

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ mod recprot {
245245
mod recprot {
246246
use std::{
247247
fmt,
248-
os::raw::{c_char, c_int, c_uint},
248+
os::raw::{c_char, c_int, c_uint, c_ulong},
249249
ptr::{null, null_mut},
250250
};
251251

@@ -271,8 +271,24 @@ mod recprot {
271271
reason = "NONCE_LEN = 12 and TAG_LEN = 16 both fit in u32"
272272
)]
273273
const TAG_LEN_C: c_uint = TAG_LEN as c_uint;
274-
const NONCE_LEN_UL: u64 = NONCE_LEN as u64;
275-
const TAG_BITS_UL: u64 = (TAG_LEN * 8) as u64;
274+
// On Windows c_ulong is u32; on other platforms it is u64 (same width as usize),
275+
// so cast_possible_truncation only fires on Windows.
276+
#[cfg_attr(
277+
target_os = "windows",
278+
expect(
279+
clippy::cast_possible_truncation,
280+
reason = "NONCE_LEN = 12 fits in u32"
281+
)
282+
)]
283+
const NONCE_LEN_UL: c_ulong = NONCE_LEN as c_ulong;
284+
#[cfg_attr(
285+
target_os = "windows",
286+
expect(
287+
clippy::cast_possible_truncation,
288+
reason = "TAG_LEN * 8 = 128 fits in u32"
289+
)
290+
)]
291+
const TAG_BITS_UL: c_ulong = (TAG_LEN * 8) as c_ulong;
276292
#[expect(
277293
clippy::cast_possible_truncation,
278294
reason = "CK_GCM_MESSAGE_PARAMS is a small fixed struct"
@@ -645,10 +661,14 @@ mod recprot {
645661

646662
#[test]
647663
fn ck_gcm_message_params_size() {
664+
use std::os::raw::c_ulong;
648665
eprintln!(
649-
"size_of::<CK_GCM_MESSAGE_PARAMS>() = {}, GCM_PARAMS_LEN_C = {}",
666+
"size_of::<CK_GCM_MESSAGE_PARAMS>()={} GCM_PARAMS_LEN_C={} \
667+
size_of::<c_ulong>()={} size_of::<*mut u8>()={}",
650668
size_of::<freebl::CK_GCM_MESSAGE_PARAMS>(),
651669
super::GCM_PARAMS_LEN_C,
670+
size_of::<c_ulong>(),
671+
size_of::<*mut u8>(),
652672
);
653673
}
654674

@@ -688,6 +708,21 @@ mod recprot {
688708
pTag: tag.as_mut_ptr(),
689709
ulTagBits: super::TAG_BITS_UL,
690710
};
711+
eprintln!(
712+
"params: pIv={:?} ulIvLen={} ulIvFixedBits={} ivGenerator={} pTag={:?} ulTagBits={}",
713+
params.pIv, params.ulIvLen, params.ulIvFixedBits,
714+
params.ivGenerator, params.pTag, params.ulTagBits,
715+
);
716+
// Show the raw bytes NSS will receive so we can spot any layout mismatch.
717+
let params_bytes: &[u8] = unsafe {
718+
std::slice::from_raw_parts(
719+
(&raw const params).cast::<u8>(),
720+
size_of::<freebl::CK_GCM_MESSAGE_PARAMS>(),
721+
)
722+
};
723+
eprintln!("params raw bytes: {params_bytes:02x?}");
724+
// Clear any stale error so we know exactly what AES_AEAD sets (if anything).
725+
unsafe { crate::err::PR_SetError(0, 0) };
691726
let rv = unsafe {
692727
freebl::AES_AEAD(
693728
ctx_enc,

src/freebl.rs

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// self-test gate. This is intentional for neqo (non-FIPS) and saves ~7.6%
1414
// CPU on the PK11_AEADOp hot path (sftk_SessionFromHandle + mutex overhead).
1515

16-
use std::os::raw::{c_int, c_uchar, c_uint, c_void};
16+
use std::os::raw::{c_int, c_uchar, c_uint, c_ulong, c_void};
1717

1818
// NSS_AES_GCM = 4 (from blapit.h)
1919
pub const NSS_AES_GCM: c_int = 4;
@@ -35,27 +35,23 @@ pub type ChaCha20Poly1305Context = ChaCha20Poly1305ContextStr;
3535
// For CKG_NO_GENERATE (ivGenerator = 0), pIv/ulIvLen supply the full nonce.
3636
// For encrypt, pTag is the output tag buffer; for decrypt, pTag is the input
3737
// tag to verify. ulTagBits = TAG_LEN * 8 = 128.
38-
//
39-
// CK_ULONG maps to `unsigned long` in C, which is 8 bytes on LP64 (Linux/macOS)
40-
// and also on the Windows NSS build (whose freebl/gcm libraries are compiled
41-
// with an LP64 toolchain). Using u64 here ensures a uniform 48-byte layout
42-
// on all 64-bit targets and avoids a sizeof mismatch in the AES_AEAD paramLen
43-
// check on Windows.
4438
#[repr(C)]
4539
#[derive(Copy, Clone)]
4640
#[expect(non_snake_case, reason = "PKCS#11 naming conventions.")]
4741
pub struct CK_GCM_MESSAGE_PARAMS {
4842
pub pIv: *mut c_uchar,
49-
pub ulIvLen: u64,
50-
pub ulIvFixedBits: u64,
51-
pub ivGenerator: u64, // CK_GENERATOR_FUNCTION; 0 = CKG_NO_GENERATE
43+
pub ulIvLen: c_ulong,
44+
pub ulIvFixedBits: c_ulong,
45+
pub ivGenerator: c_ulong, // CK_GENERATOR_FUNCTION; 0 = CKG_NO_GENERATE
5246
pub pTag: *mut c_uchar,
53-
pub ulTagBits: u64,
47+
pub ulTagBits: c_ulong,
5448
}
5549

56-
// All 6 fields are 8 bytes wide (two 8-byte pointers and four u64 values),
57-
// so the struct is 48 bytes on all 64-bit targets — no platform-specific padding.
58-
const _: () = assert!(size_of::<CK_GCM_MESSAGE_PARAMS>() == 6 * 8);
50+
// On LP64 (Linux/macOS) pointer == c_ulong == 8 bytes, so all 6 fields are
51+
// the same width. On Windows LLP64, c_ulong is 4 bytes but pointers are 8,
52+
// so the layout differs and the check would be wrong — skip it there.
53+
#[cfg(not(target_os = "windows"))]
54+
const _: () = assert!(size_of::<CK_GCM_MESSAGE_PARAMS>() == 6 * size_of::<c_ulong>());
5955

6056
unsafe extern "C" {
6157
/// Allocate and initialise an AES context. Pass `NULL` for `iv` when

0 commit comments

Comments
 (0)