Skip to content

Commit d2c0cbe

Browse files
authored
Merge pull request #249 from jaeparker22/ulivbits-optional-assign
Set ulIvBits and more graceful error handling
2 parents 1daf63f + a3a791f commit d2c0cbe

File tree

2 files changed

+32
-18
lines changed

2 files changed

+32
-18
lines changed

cryptoki/src/mechanism/aead.rs

+16-16
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// SPDX-License-Identifier: Apache-2.0
33
//! AEAD block cipher mechanism types
44
5+
use crate::error::Error;
56
use crate::types::Ulong;
67
use cryptoki_sys::*;
78
use std::convert::TryInto;
@@ -31,12 +32,10 @@ impl<'a> GcmParams<'a> {
3132
/// `tag_bits` - The length, in **bits**, of the authentication tag. Must
3233
/// be between 0 and 128. The tag is appended to the end of the
3334
/// ciphertext.
34-
///
35-
/// # Panics
36-
///
37-
/// This function panics if the length of `iv` or `aad` does not
35+
/// # Errors
36+
/// This function returns an error if the length of `iv` or `aad` does not
3837
/// fit into an [Ulong].
39-
pub fn new(iv: &'a mut [u8], aad: &'a [u8], tag_bits: Ulong) -> Self {
38+
pub fn new(iv: &'a mut [u8], aad: &'a [u8], tag_bits: Ulong) -> Result<Self, Error> {
4039
// The ulIvBits parameter seems to be missing from the 2.40 spec,
4140
// although it is included in the header file. In [1], OASIS clarified
4241
// that the header file is normative. In 3.0, they added the parameter
@@ -53,23 +52,24 @@ impl<'a> GcmParams<'a> {
5352
// set it to zero.
5453
//
5554
// [1]: https://www.oasis-open.org/committees/document.php?document_id=58032&wg_abbrev=pkcs11
56-
GcmParams {
55+
56+
let iv_len = iv.len();
57+
// Some HSMs may require the ulIvBits field to be populated, while others don't pay attention to it.
58+
let iv_bit_len = iv_len * 8;
59+
60+
Ok(GcmParams {
5761
inner: CK_GCM_PARAMS {
5862
pIv: iv.as_mut_ptr(),
59-
ulIvLen: iv
60-
.len()
61-
.try_into()
62-
.expect("iv length does not fit in CK_ULONG"),
63-
ulIvBits: 0,
63+
ulIvLen: iv_len.try_into()?,
64+
// Since this field isn't universally used, set it to 0 if it doesn't fit in CK_ULONG.
65+
// If the HSM doesn't require the field, it won't mind; and it it does, it would break anyways.
66+
ulIvBits: iv_bit_len.try_into().unwrap_or_default(),
6467
pAAD: aad.as_ptr() as *mut _,
65-
ulAADLen: aad
66-
.len()
67-
.try_into()
68-
.expect("aad length does not fit in CK_ULONG"),
68+
ulAADLen: aad.len().try_into()?,
6969
ulTagBits: tag_bits.into(),
7070
},
7171
_marker: PhantomData,
72-
}
72+
})
7373
}
7474

7575
/// The initialization vector.

cryptoki/tests/basic.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,19 @@ fn sha256_digest() -> TestResult {
12681268
Ok(())
12691269
}
12701270

1271+
#[test]
1272+
#[serial]
1273+
fn gcm_param_graceful_failure() -> TestResult {
1274+
// Try to generate GcmParams with max size IV (2^32-1)
1275+
// Verify that the ulIvBits doesn't cause failover
1276+
// setting this as a [u8] array causes stack overflow before operation has even begun
1277+
let mut iv = vec![0; 4294967295];
1278+
let aad = [0; 16];
1279+
GcmParams::new(&mut iv, &aad, 96.into())?;
1280+
1281+
Ok(())
1282+
}
1283+
12711284
#[test]
12721285
#[serial]
12731286
// Currently empty AAD crashes SoftHSM, see: https://github.com/opendnssec/SoftHSMv2/issues/605
@@ -1295,7 +1308,7 @@ fn aes_gcm_no_aad() -> TestResult {
12951308
Attribute::Encrypt(true),
12961309
];
12971310
let key_handle = session.create_object(&template)?;
1298-
let mechanism = Mechanism::AesGcm(GcmParams::new(&mut iv, &aad, 96.into()));
1311+
let mechanism = Mechanism::AesGcm(GcmParams::new(&mut iv, &aad, 96.into())?);
12991312
let cipher_and_tag = session.encrypt(&mechanism, key_handle, &plain)?;
13001313
assert_eq!(expected_cipher_and_tag[..], cipher_and_tag[..]);
13011314
Ok(())
@@ -1326,7 +1339,8 @@ fn aes_gcm_with_aad() -> TestResult {
13261339
Attribute::Encrypt(true),
13271340
];
13281341
let key_handle = session.create_object(&template)?;
1329-
let mechanism = Mechanism::AesGcm(GcmParams::new(&mut iv, &aad, 96.into()));
1342+
let gcm_params = GcmParams::new(&mut iv, &aad, 96.into())?;
1343+
let mechanism = Mechanism::AesGcm(gcm_params);
13301344
let cipher_and_tag = session.encrypt(&mechanism, key_handle, &plain)?;
13311345
assert_eq!(expected_cipher_and_tag[..], cipher_and_tag[..]);
13321346
Ok(())

0 commit comments

Comments
 (0)