Skip to content

Commit 04cc9f4

Browse files
simo5Gemini
andcommitted
Safely handle unaligned CK_MECHANISM pointers
Dereferencing `CK_MECHANISM` pointers directly can lead to unaligned memory access, causing undefined behavior or crashes on certain architectures. This introduces `CK_MECHANISM::from_ptr` to safely read the struct by value using `std::ptr::read_unaligned`. All cryptographic function initialization routines have been updated to use this method to ensure memory safety. Co-authored-by: Gemini <gemini@google.com> Signed-off-by: Simo Sorce <simo@redhat.com>
1 parent e81d439 commit 04cc9f4

File tree

5 files changed

+50
-42
lines changed

5 files changed

+50
-42
lines changed

src/fns/digest.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ fn digest_init(
3232
}
3333
session.check_no_op::<dyn Digest>()?;
3434

35-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
35+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
3636
let token = rstate.get_token_from_slot(session.get_slot_id())?;
3737
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
3838
if mech.info().flags & CKF_DIGEST == CKF_DIGEST {
39-
let operation = mech.digest_new(mechanism)?;
39+
let operation = mech.digest_new(&mechanism)?;
4040
session.set_operation::<dyn Digest>(operation, false);
41+
4142
Ok(())
4243
} else {
4344
Err(CKR_MECHANISM_INVALID)?

src/fns/encryption.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ fn encrypt_init(
3333
}
3434
session.check_no_op::<dyn Encryption>()?;
3535

36-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
36+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
3737
let slot_id = session.get_slot_id();
3838
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
3939
let key = token.get_object_by_handle(key_handle)?;
4040

41-
match check_allowed_mechs(mechanism, &key) {
41+
match check_allowed_mechs(&mechanism, &key) {
4242
CKR_OK => (),
4343
err => return Err(err)?,
4444
}
4545

4646
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
4747
if mech.info().flags & CKF_ENCRYPT == CKF_ENCRYPT {
48-
let operation = mech.encryption_new(mechanism, &key)?;
48+
let operation = mech.encryption_new(&mechanism, &key)?;
4949
session.set_operation::<dyn Encryption>(operation, false);
5050

5151
#[cfg(feature = "fips")]
@@ -312,17 +312,17 @@ fn decrypt_init(
312312
return Ok(());
313313
}
314314
session.check_no_op::<dyn Decryption>()?;
315-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
315+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
316316
let slot_id = session.get_slot_id();
317317
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
318318
let key = token.get_object_by_handle(key_handle)?;
319-
match check_allowed_mechs(mechanism, &key) {
319+
match check_allowed_mechs(&mechanism, &key) {
320320
CKR_OK => (),
321321
err => return Err(err)?,
322322
}
323323
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
324324
if mech.info().flags & CKF_DECRYPT == CKF_DECRYPT {
325-
let operation = mech.decryption_new(mechanism, &key)?;
325+
let operation = mech.decryption_new(&mechanism, &key)?;
326326
session.set_operation::<dyn Decryption>(operation, key.always_auth());
327327

328328
#[cfg(feature = "fips")]
@@ -589,17 +589,17 @@ fn message_encrypt_init(
589589
return Ok(());
590590
}
591591
session.check_no_op::<dyn MsgEncryption>()?;
592-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
592+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
593593
let slot_id = session.get_slot_id();
594594
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
595595
let key = token.get_object_by_handle(key_handle)?;
596-
match check_allowed_mechs(mechanism, &key) {
596+
match check_allowed_mechs(&mechanism, &key) {
597597
CKR_OK => {}
598598
err => return Err(err)?,
599599
}
600600
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
601601
if mech.info().flags & CKF_MESSAGE_ENCRYPT != 0 {
602-
let operation = mech.msg_encryption_op(mechanism, &key)?;
602+
let operation = mech.msg_encryption_op(&mechanism, &key)?;
603603
session.set_operation::<dyn MsgEncryption>(operation, false);
604604
#[cfg(feature = "fips")]
605605
init_fips_approval(session, mechanism.mechanism, CKF_ENCRYPT, &key);
@@ -981,17 +981,18 @@ fn message_decrypt_init(
981981
return Ok(());
982982
}
983983
session.check_no_op::<dyn MsgDecryption>()?;
984-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
984+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
985985
let slot_id = session.get_slot_id();
986986
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
987987
let key = token.get_object_by_handle(key_handle)?;
988-
match check_allowed_mechs(mechanism, &key) {
988+
match check_allowed_mechs(&mechanism, &key) {
989989
CKR_OK => (),
990+
990991
err => return Err(err)?,
991992
}
992993
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
993994
if mech.info().flags & CKF_MESSAGE_DECRYPT != 0 {
994-
let operation = mech.msg_decryption_op(mechanism, &key)?;
995+
let operation = mech.msg_decryption_op(&mechanism, &key)?;
995996
session.set_operation::<dyn MsgDecryption>(operation, false);
996997
#[cfg(feature = "fips")]
997998
init_fips_approval(session, mechanism.mechanism, CKF_DECRYPT, &key);

src/fns/keymgmt.rs

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fn generate_key(
4141
s
4242
};
4343

44-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
44+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
4545
let cnt = usize::try_from(count).map_err(|_| CKR_GENERAL_ERROR)?;
4646
let tmpl: &mut [CK_ATTRIBUTE] =
4747
unsafe { std::slice::from_raw_parts_mut(template, cnt) };
@@ -63,7 +63,7 @@ fn generate_key(
6363
return Err(CKR_MECHANISM_INVALID)?;
6464
}
6565

66-
let key = match mech.generate_key(mechanism, tmpl, mechanisms, factories) {
66+
let key = match mech.generate_key(&mechanism, tmpl, mechanisms, factories) {
6767
#[allow(unused_mut)]
6868
Ok(mut k) => {
6969
#[cfg(feature = "fips")]
@@ -144,7 +144,7 @@ fn generate_key_pair(
144144
s
145145
};
146146

147-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
147+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
148148
let pubcnt = usize::try_from(public_key_attribute_count)
149149
.map_err(|_| CKR_GENERAL_ERROR)?;
150150
let pubtmpl: &mut [CK_ATTRIBUTE] =
@@ -170,7 +170,7 @@ fn generate_key_pair(
170170
return Err(CKR_MECHANISM_INVALID)?;
171171
}
172172

173-
let result = mech.generate_keypair(mechanism, pubtmpl, pritmpl);
173+
let result = mech.generate_keypair(&mechanism, pubtmpl, pritmpl);
174174
match result {
175175
#[allow(unused_mut)]
176176
Ok((mut pubkey, mut privkey)) => {
@@ -275,13 +275,13 @@ fn wrap_key(
275275
s
276276
};
277277

278-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
278+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
279279
let slot_id = session.get_slot_id();
280280
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
281281
let key = token.get_object_by_handle(key_handle)?;
282282
let wkey = token.get_object_by_handle(wrapping_key_handle)?;
283283

284-
match check_allowed_mechs(mechanism, &wkey) {
284+
match check_allowed_mechs(&mechanism, &wkey) {
285285
CKR_OK => (),
286286
err => return Err(err)?,
287287
}
@@ -312,7 +312,8 @@ fn wrap_key(
312312
usize::try_from(pwraplen).map_err(|_| CKR_ARGUMENTS_BAD)?;
313313
unsafe { std::slice::from_raw_parts_mut(wrapped_key, wraplen) }
314314
};
315-
let outlen = match mech.wrap_key(mechanism, &wkey, &key, wrapped, factory) {
315+
let outlen = match mech.wrap_key(&mechanism, &wkey, &key, wrapped, factory)
316+
{
316317
Ok(len) => {
317318
#[cfg(feature = "fips")]
318319
session.set_fips_indicator(fips::indicators::is_approved(
@@ -396,7 +397,7 @@ fn unwrap_key(
396397
s
397398
};
398399

399-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
400+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
400401
let cnt =
401402
usize::try_from(attribute_count).map_err(|_| CKR_GENERAL_ERROR)?;
402403
let tmpl: &mut [CK_ATTRIBUTE] =
@@ -413,7 +414,7 @@ fn unwrap_key(
413414
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
414415
let key = token.get_object_by_handle(unwrapping_key_handle)?;
415416

416-
match check_allowed_mechs(mechanism, &key) {
417+
match check_allowed_mechs(&mechanism, &key) {
417418
CKR_OK => (),
418419
err => return Err(err)?,
419420
}
@@ -433,7 +434,7 @@ fn unwrap_key(
433434
return Err(CKR_WRAPPING_KEY_HANDLE_INVALID)?;
434435
}
435436

436-
let result = mech.unwrap_key(mechanism, &key, data, tmpl, factory);
437+
let result = mech.unwrap_key(&mechanism, &key, data, tmpl, factory);
437438
match result {
438439
#[allow(unused_mut)]
439440
Ok(mut obj) => {
@@ -511,7 +512,7 @@ fn derive_key(
511512
let rstate = STATE.rlock()?;
512513
let session = rstate.get_session(s_handle)?;
513514

514-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
515+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
515516
let cnt =
516517
usize::try_from(attribute_count).map_err(|_| CKR_GENERAL_ERROR)?;
517518
let tmpl: &mut [CK_ATTRIBUTE] =
@@ -540,7 +541,7 @@ fn derive_key(
540541
}
541542
}
542543

543-
match check_allowed_mechs(mechanism, &key) {
544+
match check_allowed_mechs(&mechanism, &key) {
544545
CKR_OK => (),
545546
err => return Err(err)?,
546547
}
@@ -550,7 +551,7 @@ fn derive_key(
550551
return Err(CKR_MECHANISM_INVALID)?;
551552
}
552553

553-
let mut operation = mech.derive_operation(mechanism)?;
554+
let mut operation = mech.derive_operation(&mechanism)?;
554555

555556
/* some derive operation requires additional keys */
556557
match operation.requires_objects() {
@@ -785,7 +786,7 @@ fn encapsulate_key(
785786
let rstate = STATE.rlock()?;
786787
let session = rstate.get_session(s_handle)?;
787788

788-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
789+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
789790
let cnt =
790791
usize::try_from(attribute_count).map_err(|_| CKR_GENERAL_ERROR)?;
791792
let tmpl: &[CK_ATTRIBUTE] =
@@ -804,7 +805,7 @@ fn encapsulate_key(
804805

805806
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
806807
let key = token.get_object_by_handle(pubkey_handle)?;
807-
match check_allowed_mechs(mechanism, &key) {
808+
match check_allowed_mechs(&mechanism, &key) {
808809
CKR_OK => (),
809810
err => return Err(err)?,
810811
}
@@ -833,7 +834,7 @@ fn encapsulate_key(
833834

834835
#[allow(unused_mut)]
835836
let (mut obj, outlen) =
836-
mech.encapsulate(mechanism, &key, factory, tmpl, encpart)?;
837+
mech.encapsulate(&mechanism, &key, factory, tmpl, encpart)?;
837838

838839
#[cfg(feature = "fips")]
839840
{
@@ -925,7 +926,7 @@ fn decapsulate_key(
925926
let rstate = STATE.rlock()?;
926927
let session = rstate.get_session(s_handle)?;
927928

928-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
929+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
929930
let cnt =
930931
usize::try_from(attribute_count).map_err(|_| CKR_GENERAL_ERROR)?;
931932
let tmpl: &[CK_ATTRIBUTE] =
@@ -946,7 +947,7 @@ fn decapsulate_key(
946947

947948
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
948949
let key = token.get_object_by_handle(privkey_handle)?;
949-
match check_allowed_mechs(mechanism, &key) {
950+
match check_allowed_mechs(&mechanism, &key) {
950951
CKR_OK => (),
951952
err => return Err(err)?,
952953
}
@@ -958,7 +959,7 @@ fn decapsulate_key(
958959
}
959960

960961
#[allow(unused_mut)]
961-
let mut obj = mech.decapsulate(mechanism, &key, factory, tmpl, encpart)?;
962+
let mut obj = mech.decapsulate(&mechanism, &key, factory, tmpl, encpart)?;
962963

963964
#[cfg(feature = "fips")]
964965
{

src/fns/signing.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,17 @@ fn sign_init(
3333
}
3434
session.check_no_op::<dyn Sign>()?;
3535

36-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
36+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
3737
let slot_id = session.get_slot_id();
3838
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
3939
let key = token.get_object_by_handle(key_handle)?;
40-
match check_allowed_mechs(mechanism, &key) {
40+
match check_allowed_mechs(&mechanism, &key) {
4141
CKR_OK => (),
4242
err => return Err(err)?,
4343
}
4444
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
4545
if mech.info().flags & CKF_SIGN == CKF_SIGN {
46-
let operation = mech.sign_new(mechanism, &key)?;
46+
let operation = mech.sign_new(&mechanism, &key)?;
4747
session.set_operation::<dyn Sign>(operation, key.always_auth());
4848

4949
#[cfg(feature = "fips")]
@@ -305,17 +305,17 @@ fn verify_init(
305305
return Ok(());
306306
}
307307
session.check_no_op::<dyn Verify>()?;
308-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
308+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
309309
let slot_id = session.get_slot_id();
310310
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
311311
let key = token.get_object_by_handle(key_handle)?;
312-
match check_allowed_mechs(mechanism, &key) {
312+
match check_allowed_mechs(&mechanism, &key) {
313313
CKR_OK => (),
314314
err => return Err(err)?,
315315
}
316316
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
317317
if mech.info().flags & CKF_VERIFY == CKF_VERIFY {
318-
let operation = mech.verify_new(mechanism, &key)?;
318+
let operation = mech.verify_new(&mechanism, &key)?;
319319
session.set_operation::<dyn Verify>(operation, false);
320320

321321
#[cfg(feature = "fips")]
@@ -686,12 +686,13 @@ fn verify_signature_init(
686686
return Ok(());
687687
}
688688
session.check_no_op::<dyn VerifySignature>()?;
689-
let mechanism: &CK_MECHANISM = unsafe { &*mechptr };
689+
let mechanism = CK_MECHANISM::from_ptr(mechptr);
690690
let slot_id = session.get_slot_id();
691691
let mut token = rstate.get_token_from_slot_mut(slot_id)?;
692692
let key = token.get_object_by_handle(key_handle)?;
693-
match check_allowed_mechs(mechanism, &key) {
693+
match check_allowed_mechs(&mechanism, &key) {
694694
CKR_OK => (),
695+
695696
err => return Err(err)?,
696697
}
697698
let mech = token.get_mechanisms().get(mechanism.mechanism)?;
@@ -703,7 +704,7 @@ fn verify_signature_init(
703704
usize::try_from(psignature_len).map_err(|_| CKR_GENERAL_ERROR)?;
704705
let signature: &[u8] =
705706
unsafe { std::slice::from_raw_parts(psignature, sig_len) };
706-
let operation = mech.verify_signature_new(mechanism, &key, signature)?;
707+
let operation = mech.verify_signature_new(&mechanism, &key, signature)?;
707708
session.set_operation::<dyn VerifySignature>(operation, false);
708709

709710
#[cfg(feature = "fips")]

src/pkcs11/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,4 +1022,8 @@ impl CK_MECHANISM {
10221022
}
10231023
Ok(unsafe { std::ptr::read_unaligned(self.pParameter as *const T) })
10241024
}
1025+
1026+
pub fn from_ptr(mechptr: CK_MECHANISM_PTR) -> CK_MECHANISM {
1027+
unsafe { std::ptr::read_unaligned(mechptr as *const CK_MECHANISM) }
1028+
}
10251029
}

0 commit comments

Comments
 (0)