Skip to content

Commit

Permalink
Add support for raw RSA signatures.
Browse files Browse the repository at this point in the history
Signed-off-by: Simo Sorce <[email protected]>
  • Loading branch information
simo5 committed Dec 10, 2024
1 parent 152ec71 commit 9dddc4f
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 52 deletions.
88 changes: 48 additions & 40 deletions src/ossl/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ impl RsaPKCSOperation {
hash: CK_MECHANISM_TYPE,
) -> Result<usize> {
match mech {
CKM_RSA_X_509 => Ok(modulus),
CKM_RSA_PKCS => Ok(modulus - 11),
CKM_RSA_PKCS_OAEP => {
let hs = Self::hash_len(hash)?;
Expand Down Expand Up @@ -331,6 +332,7 @@ impl RsaPKCSOperation {
Ok(RsaPKCSOperation {
mech: mech.mechanism,
max_input: match mech.mechanism {
CKM_RSA_X_509 => modulus.len(),
CKM_RSA_PKCS => modulus.len() - 11,
CKM_RSA_PKCS_PSS => Self::hash_len(pss_params.hash)?,
_ => 0,
Expand All @@ -341,7 +343,6 @@ impl RsaPKCSOperation {
finalized: false,
in_use: false,
sigctx: match mech.mechanism {
CKM_RSA_PKCS => None,
#[cfg(feature = "fips")]
_ => Some(ProviderSignatureCtx::new(name_as_char(RSA_NAME))?),
#[cfg(not(feature = "fips"))]
Expand Down Expand Up @@ -372,6 +373,7 @@ impl RsaPKCSOperation {
Ok(RsaPKCSOperation {
mech: mech.mechanism,
max_input: match mech.mechanism {
CKM_RSA_X_509 => modulus.len(),
CKM_RSA_PKCS => modulus.len() - 11,
_ => 0,
},
Expand All @@ -381,7 +383,6 @@ impl RsaPKCSOperation {
finalized: false,
in_use: false,
sigctx: match mech.mechanism {
CKM_RSA_PKCS => None,
#[cfg(feature = "fips")]
_ => Some(ProviderSignatureCtx::new(name_as_char(RSA_NAME))?),
#[cfg(not(feature = "fips"))]
Expand Down Expand Up @@ -849,10 +850,10 @@ impl Sign for RsaPKCSOperation {
return Err(CKR_OPERATION_NOT_INITIALIZED)?;
}
match self.mech {
CKM_RSA_PKCS | CKM_RSA_PKCS_PSS => {
CKM_RSA_X_509 | CKM_RSA_PKCS | CKM_RSA_PKCS_PSS => {
self.finalized = true;
if match self.mech {
CKM_RSA_PKCS => data.len() > self.max_input,
CKM_RSA_X_509 | CKM_RSA_PKCS => data.len() > self.max_input,
CKM_RSA_PKCS_PSS => data.len() != self.max_input,
_ => return Err(CKR_GENERAL_ERROR)?,
} {
Expand Down Expand Up @@ -921,8 +922,11 @@ impl Sign for RsaPKCSOperation {
return Err(CKR_OPERATION_NOT_INITIALIZED)?;
}
if !self.in_use {
if self.mech == CKM_RSA_PKCS || self.mech == CKM_RSA_PKCS_PSS {
return Err(CKR_OPERATION_NOT_INITIALIZED)?;
match self.mech {
CKM_RSA_X_509 | CKM_RSA_PKCS | CKM_RSA_PKCS_PSS => {
return Err(CKR_OPERATION_NOT_INITIALIZED)?;
}
_ => (),
}
self.in_use = true;

Expand Down Expand Up @@ -1023,43 +1027,47 @@ impl Verify for RsaPKCSOperation {
if self.finalized {
return Err(CKR_OPERATION_NOT_INITIALIZED)?;
}
if self.mech == CKM_RSA_PKCS {
self.finalized = true;
if data.len() > self.max_input {
return Err(CKR_DATA_LEN_RANGE)?;
}
if signature.len() != self.output_len {
return Err(CKR_GENERAL_ERROR)?;
}
let mut ctx = some_or_err!(mut self.public_key).new_ctx()?;
let res = unsafe { EVP_PKEY_verify_init(ctx.as_mut_ptr()) };
if res != 1 {
return Err(CKR_DEVICE_ERROR)?;
}
let params = self.rsa_sig_params();
let res = unsafe {
EVP_PKEY_CTX_set_params(ctx.as_mut_ptr(), params.as_ptr())
};
if res != 1 {
return Err(CKR_DEVICE_ERROR)?;
}
match self.mech {
CKM_RSA_X_509 | CKM_RSA_PKCS | CKM_RSA_PKCS_PSS => {
self.finalized = true;
if data.len() > self.max_input {
return Err(CKR_DATA_LEN_RANGE)?;
}
if signature.len() != self.output_len {
return Err(CKR_GENERAL_ERROR)?;
}
let mut ctx = some_or_err!(mut self.public_key).new_ctx()?;
let res = unsafe { EVP_PKEY_verify_init(ctx.as_mut_ptr()) };
if res != 1 {
return Err(CKR_DEVICE_ERROR)?;
}
let params = self.rsa_sig_params();
let res = unsafe {
EVP_PKEY_CTX_set_params(ctx.as_mut_ptr(), params.as_ptr())
};
if res != 1 {
return Err(CKR_DEVICE_ERROR)?;
}

let res = unsafe {
EVP_PKEY_verify(
ctx.as_mut_ptr(),
signature.as_ptr(),
signature.len(),
data.as_ptr(),
data.len(),
)
};
if res != 1 {
return Err(CKR_SIGNATURE_INVALID)?;
let res = unsafe {
EVP_PKEY_verify(
ctx.as_mut_ptr(),
signature.as_ptr(),
signature.len(),
data.as_ptr(),
data.len(),
)
};
if res != 1 {
return Err(CKR_SIGNATURE_INVALID)?;
}
Ok(())
}
_ => {
self.verify_update(data)?;
self.verify_final(signature)
}
return Ok(());
}
self.verify_update(data)?;
self.verify_final(signature)
}

fn verify_update(&mut self, data: &[u8]) -> Result<()> {
Expand Down
25 changes: 13 additions & 12 deletions src/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -374,18 +374,19 @@ impl RsaPKCSMechanism {
}

pub fn register_mechanisms(mechs: &mut Mechanisms) {
mechs.add_mechanism(
CKM_RSA_PKCS,
Self::new_mechanism(
CKF_ENCRYPT
| CKF_DECRYPT
| CKF_SIGN
| CKF_VERIFY
| CKF_WRAP
| CKF_UNWRAP,
),
);

for ckm in &[CKM_RSA_X_509, CKM_RSA_PKCS] {
mechs.add_mechanism(
*ckm,
Self::new_mechanism(
CKF_ENCRYPT
| CKF_DECRYPT
| CKF_SIGN
| CKF_VERIFY
| CKF_WRAP
| CKF_UNWRAP,
),
);
}
for ckm in &[
CKM_SHA1_RSA_PKCS,
CKM_SHA224_RSA_PKCS,
Expand Down
64 changes: 64 additions & 0 deletions src/tests/rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,5 +391,69 @@ fn test_rsa_operations() {
);
assert_eq!(ret, CKR_OK);

#[cfg(not(feature = "fips"))]
{
/* RSA PKCS Sig */
let pri_key_handle = match get_test_key_handle(
session,
"SigVer15_186-3.rsp [mod = 2048]",
CKO_PRIVATE_KEY,
) {
Ok(k) => k,
Err(e) => panic!("{}", e),
};
let pub_key_handle = match get_test_key_handle(
session,
"SigVer15_186-3.rsp [mod = 2048]",
CKO_PUBLIC_KEY,
) {
Ok(k) => k,
Err(e) => panic!("{}", e),
};

/* Test Raw Signature */
let mut mechanism: CK_MECHANISM = CK_MECHANISM {
mechanism: CKM_RSA_X_509,
pParameter: std::ptr::null_mut(),
ulParameterLen: 0,
};

let ret = fn_sign_init(session, &mut mechanism, pri_key_handle);
assert_eq!(ret, CKR_OK);

let mut sig_len: CK_ULONG = 0;
let data = "check";
let ret = fn_sign(
session,
byte_ptr!(data.as_ptr()),
data.len() as CK_ULONG,
std::ptr::null_mut(),
&mut sig_len,
);
assert_eq!(ret, CKR_OK);

let mut signature = vec![0; sig_len as usize];
let ret = fn_sign(
session,
byte_ptr!(data.as_ptr()),
data.len() as CK_ULONG,
signature.as_mut_ptr(),
&mut sig_len,
);
assert_eq!(ret, CKR_OK);

let ret = fn_verify_init(session, &mut mechanism, pub_key_handle);
assert_eq!(ret, CKR_OK);

let ret = fn_verify(
session,
byte_ptr!(data.as_ptr()),
data.len() as CK_ULONG,
byte_ptr!(signature.as_ptr()),
signature.len() as CK_ULONG,
);
assert_eq!(ret, CKR_OK);
}

testtokn.finalize();
}

0 comments on commit 9dddc4f

Please sign in to comment.