rust/pv: Signing messages

Adds the ability to sign and verify messages using ECDH or RSA keys.

Reviewed-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Signed-off-by: Steffen Eiden <seiden@linux.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
Steffen Eiden
2024-01-30 12:55:32 +01:00
committed by Jan Höppner
parent 1450f85ada
commit bfd0e12d22
9 changed files with 237 additions and 3 deletions

View File

@@ -3,15 +3,17 @@
// Copyright IBM Corp. 2023
use crate::{error::Result, secret::Secret, Error};
use openssl::rand::rand_bytes;
use openssl::{
derive::Deriver,
ec::{EcGroup, EcKey},
hash::{DigestBytes, MessageDigest},
md::MdRef,
nid::Nid,
pkey::{Id, PKey, Private, Public},
pkey::{HasPublic, Id, PKey, PKeyRef, Private, Public},
pkey_ctx::{HkdfMode, PkeyCtx},
rand::rand_bytes,
rsa::Padding,
sign::{Signer, Verifier},
symm::{encrypt, encrypt_aead, Cipher},
};
use std::convert::TryInto;
@@ -209,10 +211,100 @@ pub fn hash(t: MessageDigest, data: &[u8]) -> Result<DigestBytes> {
openssl::hash::hash(t, data).map_err(Error::Crypto)
}
/// Calculate a digital signature scheme.
///
/// Calculates the digital signature of the provided message using the signing key. [`Id::EC`],
/// and [`Id::RSA`] keys are supported. For [`Id::RSA`] [`Padding::PKCS1_PSS`] is used.
///
/// # Errors
///
/// This function will return an error if OpenSSL could not compute the signature.
pub fn sign_msg(skey: &PKeyRef<Private>, dgst: MessageDigest, msg: &[u8]) -> Result<Vec<u8>> {
match skey.id() {
Id::EC => {
let mut sgn = Signer::new(dgst, skey)?;
sgn.sign_oneshot_to_vec(msg).map_err(Error::Crypto)
}
Id::RSA => {
let mut sgn = Signer::new(dgst, skey)?;
sgn.set_rsa_padding(Padding::PKCS1_PSS)?;
sgn.sign_oneshot_to_vec(msg).map_err(Error::Crypto)
}
_ => Err(Error::UnsupportedSigningKey),
}
}
/// Verify the digital signature of a message.
///
/// Verifies the digital signature of the provided message using the signing key.
/// [`Id::EC`] and [`Id::RSA`] keys are supported. For [`Id::RSA`] [`Padding::PKCS1_PSS`] is used.
///
/// # Returns
/// true if signature could be verified, false otherwise
///
/// # Errors
///
/// This function will return an error if OpenSSL could not compute the signature.
pub fn verify_signature<T: HasPublic>(
skey: &PKeyRef<T>,
dgst: MessageDigest,
msg: &[u8],
sign: &[u8],
) -> Result<bool> {
match skey.id() {
Id::EC => {
let mut ctx = Verifier::new(dgst, skey)?;
ctx.update(msg)?;
ctx.verify(sign).map_err(Error::Crypto)
}
Id::RSA => {
let mut ctx = Verifier::new(dgst, skey)?;
ctx.set_rsa_padding(Padding::PKCS1_PSS)?;
ctx.verify_oneshot(sign, msg).map_err(Error::Crypto)
}
_ => Err(Error::UnsupportedVerificationKey),
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::test_utils::*;
use crate::{get_test_asset, test_utils::*};
#[test]
fn sign_ec() {
let (ec_key, _) = get_test_keys();
let data = "sample".as_bytes();
let sign = sign_msg(&ec_key, MessageDigest::sha512(), data).unwrap();
assert!(sign.len() <= 139 && sign.len() >= 137);
assert!(verify_signature(&ec_key, MessageDigest::sha512(), data, &sign).unwrap());
}
#[test]
fn sign_rsa_2048() {
let keypair = get_test_asset!("keys/rsa2048key.pem");
let keypair = PKey::private_key_from_pem(keypair).unwrap();
let data = "sample".as_bytes();
let sign = sign_msg(&keypair, MessageDigest::sha512(), data).unwrap();
assert_eq!(256, sign.len());
assert!(verify_signature(&keypair, MessageDigest::sha512(), data, &sign).unwrap());
}
#[test]
fn sign_rsa_3072() {
let keypair = get_test_asset!("keys/rsa3072key.pem");
let keypair = PKey::private_key_from_pem(keypair).unwrap();
let data = "sample".as_bytes();
let sign = sign_msg(&keypair, MessageDigest::sha512(), data).unwrap();
assert_eq!(384, sign.len());
assert!(verify_signature(&keypair, MessageDigest::sha512(), data, &sign).unwrap());
}
#[test]
fn derive_key() {

View File

@@ -32,6 +32,12 @@ pub enum Error {
#[error("Internal (unexpected) error: {0}, caused by {1}")]
InternalSsl(&'static str, #[source] openssl::error::ErrorStack),
#[error("Signing is only supported for EC and RSA keys")]
UnsupportedSigningKey,
#[error("Verifying signatures is only supported for EC and RSA keys")]
UnsupportedVerificationKey,
// errors from other crates
#[error(transparent)]
PvCore(#[from] pv_core::Error),

View File

@@ -63,6 +63,7 @@ pub mod request {
pub use crate::crypto::random_array;
pub use crate::crypto::{encrypt_aes, encrypt_aes_gcm, gen_ec_key};
pub use crate::crypto::{hash, hkdf_rfc_5869};
pub use crate::crypto::{sign_msg, verify_signature};
pub use crate::crypto::{Aes256Key, SymKey, SymKeyType};
pub use crate::req::{Aad, Encrypt, Keyslot, ReqEncrCtx, Request};
pub use crate::secret::{Secret, Zeroize};

View File

@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZzCCAk+gAwIBAgIUK4kgzElokcI7s6XNCRD1iA7NfMQwDQYJKoZIhvcNAQEL
BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAgFw0yNDAxMjkxNzAxMjRaGA8zMDIzMDYw
MTE3MDEyNFowQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEc
MBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAOYCZGvIP+X8Y8gpHnjg57Oo45k+jsO1GeZGBtM+MfXP1HaV
bT48VlaxaLB+K0GbQ5ykBdP7Xa1nLdbFVWtmATkbrS78xzUsefpXG8WKtA3gtE9/
v3licc34dBHiDBNrZf/elC2P3EZOkwX7AYJSlhg5uehgy0Jp4MvAWZMHOgDNRf41
Tr/jCpuntUKUcdv9+CdhzD0Z634gzPckO4QXWKaBKwa8AU4GTb41/RTOF6U5Zh1Q
exx4rdf8h7s3sbfEa5ELLpMKSUeWXd7LVFUM6TSP+/zTgRxLHmiM3gGEawYFEvla
UluGqGtC2MVpu0bGQvxgJmuy0cw7rPE5RzudIOUCAwEAAaNTMFEwHQYDVR0OBBYE
FBheoZmtoNcYxXMwzZsujv51NgslMB8GA1UdIwQYMBaAFBheoZmtoNcYxXMwzZsu
jv51NgslMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADeRY7AS
waBH/YnZ/q/cixkaeMqtM9zRpOAVnBGOEbQiLVFhLXaT7XMT8r9JjbbYQW7RgaQS
fOHIxlG4jjly+/kXluF+Di54dMwrMCeAbxg7C/QQvMGVEWCufoJ9UGXWCzdZTziO
xREupk7RvjWUZL88kO9peGgsAelnvjWtgwEXpYpfOY7zwLvvm9RR7qujfjRMsip+
WTGjh4hksGQ9Yh8yFTx96QEnhZ69sU6ohtagOdW0/G2Yeh4fO/k77Afq1KNRatrZ
W3IeLGIVZIfajxfCYQ/ARmJg3I1h1Hw1pnw50h6Q8AQf50s0MtxIe6UaVUz4KqJH
RgLQPVsWXaWw5KA=
-----END CERTIFICATE-----

View File

@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDmAmRryD/l/GPI
KR544OezqOOZPo7DtRnmRgbTPjH1z9R2lW0+PFZWsWiwfitBm0OcpAXT+12tZy3W
xVVrZgE5G60u/Mc1LHn6VxvFirQN4LRPf795YnHN+HQR4gwTa2X/3pQtj9xGTpMF
+wGCUpYYObnoYMtCaeDLwFmTBzoAzUX+NU6/4wqbp7VClHHb/fgnYcw9Get+IMz3
JDuEF1imgSsGvAFOBk2+Nf0UzhelOWYdUHsceK3X/Ie7N7G3xGuRCy6TCklHll3e
y1RVDOk0j/v804EcSx5ojN4BhGsGBRL5WlJbhqhrQtjFabtGxkL8YCZrstHMO6zx
OUc7nSDlAgMBAAECggEACx1seuTnaZbDv6V1CoRbzgvIS9yBC6YRxVX2+HhV87oC
W2SnLc2+olvaYkUGlBoLr2MhwPextDJ7PZi1owX/4yGaQd4HRmOK1XUmK2qjftQw
AnN67kO6mih6e27ABKQ4/p9j67u6+k7Lvgs+LG0PQcZwXHFpASGasl3uNjOwMt+h
IJxo1UJcNM4s0WyFLWWg7dWHE/m8QWA0Qc9zBL3cIewTgr6SiTTgQGeNFpSQThgJ
E1G9cpLvchKLCcsc3L8/03ZJX00R/GyBYcJsvsTfsva5FzFG6OSt4G+73jthEC8E
jUeI0D/tw27XjBGRYNbMlsdIHqdTWxraB1HiK3CpIQKBgQD2nYXrr5isnlOSaeww
de1QMUTY7A/IUtYGknZxCj1Q/xS483er/bmfrNRAo2YMGqO/vcJxqy7vA3yACMqR
mUP8XInkfkTILYaLEECfW4+g6/f6wgBnFdIjn4vqR8XGPFwYX6IoSvzjh5iqOTon
LVx1v2Co9cdvFiD+rGT2t9FZyQKBgQDuwxjWw2bx0iH4CXQRtqv97lDu/eB9SiIl
Nb0AYGYf6/QhVkVxOBjUHitgSDWdOy2vJ8tojuxM2qT2SmGYFmjI33WAReHvPPE0
BzjIHdCAzKRJgHk02Sh86vw9NMDiGE37Tc9GdGNz8hXF4BTyuPbnDu7ta54bn7JQ
U4xVQgLcPQKBgFnM0k8YCcgRfuz5lP+wcVGaHy++BaE0SKrr+iT/TYSI3crbHOCL
62OxUziWRzpxGN9hAcTSSKzP4C3fBaQu4wqpx6xkLjeWHD/XEzDz7kDyq8Grkun2
kCZYmmIc8G9W21IkwK9bXuqbHYQegoZxhhF6NoBPvuc8b5dMvxb3qEvBAoGBAJaL
556LCN8TWx3VgB0nLF1pphh7ddAqLUt/DdQt9FbOZVmb1x9jeqxM9Za5ES05wj19
/xDHhZGUD43IKq9F+f4mgCVIawR5TbE7mH795ZlA75n06vf6sT/Kvw8ssy4cmxcI
4dgPzSGvlDD3cN326J+aV+bWA5RxZnKlq4eanskVAoGBAK+QvIp17Lq2RdcBcFr3
1Do0M2tDzjBgdzIp+8bfJHSfe3v4EEupeNa2tD2lnRlETc2JjIMFx1SMHYTi9+ax
Iuhwl7txcijtXT+5kUO4Km8oiQGbskJLwH1iVAGIMMASJf8lQHODby2R8x3OUQnX
YdC+wJJq6gfNo436A4lkPQsM
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5gJka8g/5fxjyCkeeODn
s6jjmT6Ow7UZ5kYG0z4x9c/UdpVtPjxWVrFosH4rQZtDnKQF0/tdrWct1sVVa2YB
ORutLvzHNSx5+lcbxYq0DeC0T3+/eWJxzfh0EeIME2tl/96ULY/cRk6TBfsBglKW
GDm56GDLQmngy8BZkwc6AM1F/jVOv+MKm6e1QpRx2/34J2HMPRnrfiDM9yQ7hBdY
poErBrwBTgZNvjX9FM4XpTlmHVB7HHit1/yHuzext8RrkQsukwpJR5Zd3stUVQzp
NI/7/NOBHEseaIzeAYRrBgUS+VpSW4aoa0LYxWm7RsZC/GAma7LRzDus8TlHO50g
5QIDAQAB
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,26 @@
-----BEGIN CERTIFICATE-----
MIIEZzCCAs+gAwIBAgIUK67CEnpp4Hbp9awAbW67M6M8t9cwDQYJKoZIhvcNAQEL
BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAgFw0yNDAxMjkxNzAxMzZaGA8zMDIzMDYw
MTE3MDEzNlowQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEc
MBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCAaIwDQYJKoZIhvcNAQEBBQAD
ggGPADCCAYoCggGBAJy1pz6/Xzq9Gicai7se9HC49cPATTPXrcdVjCi11LiPDMoL
eFCeCJhXCBNLpWWDTcl2t1EFTuIv9SDguY4nWgaxVaOz0c0FLXi0DCLEUUwjPt4L
EZoRxwOAbut1N3ACE1NY0cQnDhqHUeFehp4wXUuAmCk+z3zPVRNhFjjBKXcLOphQ
ak/3C8/ajJJBznXC4r8o4MNZSl6BjJxfLArpC4xM8/5rQ2qu1CoW6nrDLeFRfFGu
CvhJ89NHnvqvUjDSb+G5gfBRFwsjw3rI80o8VYIPeM79PWILy5nMtWZDQ/J6L713
eRhrXyr42kre3c6tkkSjfciEUTwyXxcCOThX/wnN8mWg9PQY7UqyrR8mPFbSFTi0
CIL8nPi3U9tcpHOMKzrVyaYELeNhUNpDfkWE5s1XYdfiDl3Jd60GxOKpU9gCgof8
Sf21cSIcHCITqjG6Oga10ZxeCZrGEZrm/46p+KWXuWL+Tp12SvQqm7Fjc7W8MjSC
ZXEWltQcWzgq+DkOfQIDAQABo1MwUTAdBgNVHQ4EFgQU9QUBlQYenYdS6Jeo0//F
4S+xRZEwHwYDVR0jBBgwFoAU9QUBlQYenYdS6Jeo0//F4S+xRZEwDwYDVR0TAQH/
BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAYEAOjinmH5+2smoKj0fkKmgFWQqH2St
TbwtC4M7xJpge4uwEj/48CZPECZzMmkKs//x1bRepX3wBfCSrVZNjoynFxZtyjCA
2Ss86F3h/FGQaLJoIGUJN1EW8MIqxQRkv0KRBPKiGay2xocErjNjxlkDeyuDliyP
y5GUF4h+pgjlVO0b5uR03loYty65jmHucPijGkF7Kgr208SCOXArWZEyLZx1Pian
PiVxJP2mnsK9wsBBNvjH1DB+gMbOW3v6nl/2xD1Q/Lz0gif7fZZiTTnt47mlqD4d
QWOH22uPO1EMG7K66CgYQd2mo3ZKpMhPeAC3OajEnY2hXOeI/w3dsvaMwIAMUQgu
y585iOfifUgEwXXAgGS0Hq1nQwDK1TjvM5sP7nbBfIlPwI78NoK9QM7p/O7UvccD
UHAjsDgmU5q/hhqs6v6gvlX3GqOnFSdviUQGeX2l9Hw6lFWM9HIKC968ykzlp9m6
uOv1xi5CIF/ZqIkDF//ZdISgZuyB4zWOcRIT
-----END CERTIFICATE-----

View File

@@ -0,0 +1,40 @@
-----BEGIN PRIVATE KEY-----
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
ErvUlL2xPdMTZ14eNgDwQk8=
-----END PRIVATE KEY-----

View File

@@ -0,0 +1,11 @@
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAnLWnPr9fOr0aJxqLux70
cLj1w8BNM9etx1WMKLXUuI8Mygt4UJ4ImFcIE0ulZYNNyXa3UQVO4i/1IOC5jida
BrFVo7PRzQUteLQMIsRRTCM+3gsRmhHHA4Bu63U3cAITU1jRxCcOGodR4V6GnjBd
S4CYKT7PfM9VE2EWOMEpdws6mFBqT/cLz9qMkkHOdcLivyjgw1lKXoGMnF8sCukL
jEzz/mtDaq7UKhbqesMt4VF8Ua4K+Enz00ee+q9SMNJv4bmB8FEXCyPDesjzSjxV
gg94zv09YgvLmcy1ZkND8novvXd5GGtfKvjaSt7dzq2SRKN9yIRRPDJfFwI5OFf/
Cc3yZaD09BjtSrKtHyY8VtIVOLQIgvyc+LdT21ykc4wrOtXJpgQt42FQ2kN+RYTm
zVdh1+IOXcl3rQbE4qlT2AKCh/xJ/bVxIhwcIhOqMbo6BrXRnF4JmsYRmub/jqn4
pZe5Yv5OnXZK9CqbsWNztbwyNIJlcRaW1BxbOCr4OQ59AgMBAAE=
-----END PUBLIC KEY-----