2024-02-19 15:55:46 +00:00
|
|
|
use cosmwasm_std::ensure_eq;
|
|
|
|
use num_bigint::BigUint;
|
|
|
|
use sha2::{Digest, Sha256};
|
|
|
|
|
2024-05-07 22:34:09 +00:00
|
|
|
use crate::intel_sgx::{
|
|
|
|
epid::{types::IASReport, Error as EpidError, INTEL_ROOT_EXPONENT, INTEL_ROOT_MODULUS},
|
|
|
|
Error,
|
|
|
|
};
|
2024-02-19 15:55:46 +00:00
|
|
|
|
|
|
|
/// Given an RSA signature and the signer's exponent + modulus we recover the digest that was signed by the signature.
|
|
|
|
pub fn recover_signature_digest(signature: &[u8], exponent: &[u8], modulus: &[u8]) -> Vec<u8> {
|
|
|
|
let sig_as_bignum_be = BigUint::from_bytes_be(signature);
|
|
|
|
let intel_modulus_be = BigUint::from_bytes_be(modulus);
|
|
|
|
let intel_exponent_be = BigUint::from_bytes_be(exponent);
|
|
|
|
|
|
|
|
let digest_be = sig_as_bignum_be.modpow(&intel_exponent_be, &intel_modulus_be);
|
|
|
|
|
|
|
|
// last 32 bytes contain the digest
|
|
|
|
let digest_bytes = digest_be.to_bytes_be();
|
|
|
|
let n = digest_bytes.len();
|
|
|
|
digest_bytes[n - 32..n].to_vec()
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn verify(
|
|
|
|
ias_report: IASReport,
|
|
|
|
mrenclave: impl AsRef<[u8]>,
|
|
|
|
user_data: impl AsRef<[u8]>,
|
|
|
|
) -> Result<(), Error> {
|
|
|
|
// Extract the payload from the quote body
|
|
|
|
let user_data_in_quote = ias_report.report.isv_enclave_quote_body.user_data();
|
|
|
|
|
|
|
|
// check user_report_data
|
|
|
|
ensure_eq!(
|
|
|
|
user_data_in_quote,
|
|
|
|
user_data.as_ref(),
|
|
|
|
Error::UserDataMismatch
|
|
|
|
);
|
|
|
|
|
|
|
|
// Extract the mrenclave from the quote body
|
|
|
|
let mrenclave_in_quote = ias_report.report.isv_enclave_quote_body.mrenclave();
|
|
|
|
|
|
|
|
// check mrenclave
|
|
|
|
ensure_eq!(
|
|
|
|
mrenclave_in_quote,
|
|
|
|
mrenclave.as_ref(),
|
|
|
|
Error::MrEnclaveMismatch
|
|
|
|
);
|
|
|
|
|
|
|
|
// Recover the RSA signature's digest
|
|
|
|
let recovered_digest = recover_signature_digest(
|
|
|
|
ias_report.report_sig.as_slice(),
|
|
|
|
INTEL_ROOT_EXPONENT,
|
|
|
|
INTEL_ROOT_MODULUS,
|
|
|
|
);
|
|
|
|
// Convert the recovered digest into a byte slice
|
|
|
|
let recovered_digest = recovered_digest.as_slice();
|
|
|
|
|
|
|
|
// Convert the ias report as a json string, removing all the backslashes to escape stuff
|
|
|
|
let ias_report_asjson = serde_json::to_string(&ias_report.report)
|
|
|
|
.expect("infallible serializer for IASReport")
|
|
|
|
.replace('\\', "");
|
|
|
|
// Convert the ias report without the back slashes to bytes
|
|
|
|
let ias_report_asbytes = ias_report_asjson.as_bytes();
|
|
|
|
// We are going to calculate our own digest of the ias report
|
|
|
|
let mut hasher = Sha256::default();
|
|
|
|
// Update the hasher contents with that of the ias report json
|
|
|
|
hasher.update(ias_report_asbytes);
|
|
|
|
// finalize the sha256 hasher so that it produces a byte slice of the digest, should be 32 bytes
|
|
|
|
let ias_report_digest = &hasher.finalize()[..];
|
|
|
|
|
|
|
|
// ensure that the recovered digest from the signature matches the digest of the report
|
|
|
|
ensure_eq!(
|
|
|
|
ias_report_digest,
|
|
|
|
recovered_digest,
|
|
|
|
EpidError::RecoveredDigestMismatch
|
|
|
|
);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use cosmwasm_schema::cw_serde;
|
|
|
|
use cosmwasm_std::HexBinary;
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[cw_serde]
|
|
|
|
pub enum QueryMsg {
|
|
|
|
/// Verify an attestation
|
|
|
|
VerifyEpidAttestation {
|
|
|
|
// The report that is generated by an enclave
|
|
|
|
report: IASReport,
|
|
|
|
// The MRENCLAVE of this enclave (as hex string)
|
|
|
|
mrenclave: HexBinary,
|
|
|
|
// User data - whose commitment is in the `user_report_data` (as hex string)
|
|
|
|
user_data: HexBinary,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
fn parse_attestation(query_verifier: &str) -> (IASReport, HexBinary, HexBinary) {
|
|
|
|
let query_verifier: QueryMsg =
|
|
|
|
serde_json::from_str(query_verifier).expect("deserialize query");
|
|
|
|
match query_verifier {
|
|
|
|
QueryMsg::VerifyEpidAttestation {
|
|
|
|
report,
|
|
|
|
mrenclave,
|
|
|
|
user_data,
|
|
|
|
} => (report, mrenclave, user_data),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn verify_attestation(query_verifier: &str) {
|
|
|
|
let (report, mrenclave, user_data) = parse_attestation(query_verifier);
|
|
|
|
verify(report, mrenclave, user_data).expect("RA verification failure");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_verifier_ok() {
|
|
|
|
verify_attestation(
|
|
|
|
r#"{
|
|
|
|
"verify_epid_attestation": {
|
|
|
|
"report": {"report":{"id":"5246688123689513540899231107533660789","timestamp":"2024-02-07T17:06:23.913745","version":4,"epidPseudonym":"+CUyIi74LPqS6M0NF7YrSxLqPdX3MKs6D6LIPqRG/ZEB4WmxZVvxAJwdwg/0m9cYnUUQguLnJotthX645lAogfJgO8Xg5/91lSegwyUKvHmKgtjOHX/YTbVe/wmgWiBdaL+KmarY0Je459Px/FqGLWLsAF7egPAJRd1Xn88Znrs=","advisoryURL":"https://security-center.intel.com","advisoryIDs":["INTEL-SA-00161","INTEL-SA-00219","INTEL-SA-00289","INTEL-SA-00334","INTEL-SA-00615"],"isvEnclaveQuoteStatus":"CONFIGURATION_AND_SW_HARDENING_NEEDED","platformInfoBlob":"150200650000080000141402040180070000000000000000000D00000C000000020000000000000CB0F08115F3DE71AE97980FE5E10B042054930ACE356C79EC44603D3F890756EC6ED73927A7C58CDE9AF1E754AEC77E335E8D80294407936BEB6404F27669FF7BB1","isvEnclaveQuoteBody":"AgABALAMAAAPAA8AAAAAAFHK9aSLRQ1iSu/jKG0xSJQAAAAAAAAAAAAAAAAAAAAAFBQCBwGAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAHAAAAAAAAAOPC8qW4QNieBprK/8rbZRDvhmpz06nuVxAO1fhkbuS7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc8uUpEUEPvz8ZkFapjVh5WlWaLoAJM/f80T0EhGInHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRE7C+d+1dDWhoDsdyBrjVh+1AZ5txMhzN1UBeTVSmggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"reportsig":"YcY4SPvkfR4P2E8A5huutCeS+vY/ir+xq6disalNfNtAcUyOIOqTPVXhAZgY1M5B47Hjj1oYWf2qC2w+dnj7VcZjzO9oR0pJYdA+A7jaVrNzH2eXA79yICkuU8WE/x58I0j5vjXLoHXahaKlpZkMeTphqBY8u+FTVSdP3cWPho4viPapTfQRuEWmYq4KIq2zSr6wLg3Pz+yQ+G3e9BASVkLYxdYGTDFH1pMmfas9SEI7V4I+j8DaXmL8bucSRakmcQdmDMPGiA7mvIhSAlprzCrdxM7CHeUC6MPLN1fmFFcc9kyO/ved69j/651MWC83GgxSJ15L80U+DQzmrSW8xg=="},
|
|
|
|
"mrenclave": "e3c2f2a5b840d89e069acaffcadb6510ef866a73d3a9ee57100ed5f8646ee4bb",
|
|
|
|
"user_data": "9113b0be77ed5d0d68680ec77206b8d587ed40679b71321ccdd5405e4d54a6820000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
}
|
|
|
|
}"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_verifier_bad_mrenclave() {
|
|
|
|
verify_attestation(
|
|
|
|
r#"{
|
|
|
|
"verify_epid_attestation": {
|
|
|
|
"report": {"report":{"id":"5246688123689513540899231107533660789","timestamp":"2024-02-07T17:06:23.913745","version":4,"epidPseudonym":"+CUyIi74LPqS6M0NF7YrSxLqPdX3MKs6D6LIPqRG/ZEB4WmxZVvxAJwdwg/0m9cYnUUQguLnJotthX645lAogfJgO8Xg5/91lSegwyUKvHmKgtjOHX/YTbVe/wmgWiBdaL+KmarY0Je459Px/FqGLWLsAF7egPAJRd1Xn88Znrs=","advisoryURL":"https://security-center.intel.com","advisoryIDs":["INTEL-SA-00161","INTEL-SA-00219","INTEL-SA-00289","INTEL-SA-00334","INTEL-SA-00615"],"isvEnclaveQuoteStatus":"CONFIGURATION_AND_SW_HARDENING_NEEDED","platformInfoBlob":"150200650000080000141402040180070000000000000000000D00000C000000020000000000000CB0F08115F3DE71AE97980FE5E10B042054930ACE356C79EC44603D3F890756EC6ED73927A7C58CDE9AF1E754AEC77E335E8D80294407936BEB6404F27669FF7BB1","isvEnclaveQuoteBody":"AgABALAMAAAPAA8AAAAAAFHK9aSLRQ1iSu/jKG0xSJQAAAAAAAAAAAAAAAAAAAAAFBQCBwGAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAHAAAAAAAAAOPC8qW4QNieBprK/8rbZRDvhmpz06nuVxAO1fhkbuS7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc8uUpEUEPvz8ZkFapjVh5WlWaLoAJM/f80T0EhGInHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRE7C+d+1dDWhoDsdyBrjVh+1AZ5txMhzN1UBeTVSmggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"reportsig":"YcY4SPvkfR4P2E8A5huutCeS+vY/ir+xq6disalNfNtAcUyOIOqTPVXhAZgY1M5B47Hjj1oYWf2qC2w+dnj7VcZjzO9oR0pJYdA+A7jaVrNzH2eXA79yICkuU8WE/x58I0j5vjXLoHXahaKlpZkMeTphqBY8u+FTVSdP3cWPho4viPapTfQRuEWmYq4KIq2zSr6wLg3Pz+yQ+G3e9BASVkLYxdYGTDFH1pMmfas9SEI7V4I+j8DaXmL8bucSRakmcQdmDMPGiA7mvIhSAlprzCrdxM7CHeUC6MPLN1fmFFcc9kyO/ved69j/651MWC83GgxSJ15L80U+DQzmrSW8xg=="},
|
|
|
|
"mrenclave": "f3c2f2a5b840d89e069acaffcadb6510ef866a73d3a9ee57100ed5f8646ee4bb",
|
|
|
|
"user_data": "9113b0be77ed5d0d68680ec77206b8d587ed40679b71321ccdd5405e4d54a6820000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
}
|
|
|
|
}"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_verifier_bad_user_data() {
|
|
|
|
verify_attestation(
|
|
|
|
r#"{
|
|
|
|
"verify_epid_attestation": {
|
|
|
|
"report": {"report":{"id":"5246688123689513540899231107533660789","timestamp":"2024-02-07T17:06:23.913745","version":4,"epidPseudonym":"+CUyIi74LPqS6M0NF7YrSxLqPdX3MKs6D6LIPqRG/ZEB4WmxZVvxAJwdwg/0m9cYnUUQguLnJotthX645lAogfJgO8Xg5/91lSegwyUKvHmKgtjOHX/YTbVe/wmgWiBdaL+KmarY0Je459Px/FqGLWLsAF7egPAJRd1Xn88Znrs=","advisoryURL":"https://security-center.intel.com","advisoryIDs":["INTEL-SA-00161","INTEL-SA-00219","INTEL-SA-00289","INTEL-SA-00334","INTEL-SA-00615"],"isvEnclaveQuoteStatus":"CONFIGURATION_AND_SW_HARDENING_NEEDED","platformInfoBlob":"150200650000080000141402040180070000000000000000000D00000C000000020000000000000CB0F08115F3DE71AE97980FE5E10B042054930ACE356C79EC44603D3F890756EC6ED73927A7C58CDE9AF1E754AEC77E335E8D80294407936BEB6404F27669FF7BB1","isvEnclaveQuoteBody":"AgABALAMAAAPAA8AAAAAAFHK9aSLRQ1iSu/jKG0xSJQAAAAAAAAAAAAAAAAAAAAAFBQCBwGAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAHAAAAAAAAAOPC8qW4QNieBprK/8rbZRDvhmpz06nuVxAO1fhkbuS7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc8uUpEUEPvz8ZkFapjVh5WlWaLoAJM/f80T0EhGInHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRE7C+d+1dDWhoDsdyBrjVh+1AZ5txMhzN1UBeTVSmggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"reportsig":"YcY4SPvkfR4P2E8A5huutCeS+vY/ir+xq6disalNfNtAcUyOIOqTPVXhAZgY1M5B47Hjj1oYWf2qC2w+dnj7VcZjzO9oR0pJYdA+A7jaVrNzH2eXA79yICkuU8WE/x58I0j5vjXLoHXahaKlpZkMeTphqBY8u+FTVSdP3cWPho4viPapTfQRuEWmYq4KIq2zSr6wLg3Pz+yQ+G3e9BASVkLYxdYGTDFH1pMmfas9SEI7V4I+j8DaXmL8bucSRakmcQdmDMPGiA7mvIhSAlprzCrdxM7CHeUC6MPLN1fmFFcc9kyO/ved69j/651MWC83GgxSJ15L80U+DQzmrSW8xg=="},
|
|
|
|
"mrenclave": "e3c2f2a5b840d89e069acaffcadb6510ef866a73d3a9ee57100ed5f8646ee4bb",
|
|
|
|
"user_data": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
}
|
|
|
|
}"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
#[should_panic]
|
|
|
|
fn test_verifier_bad_platform_info_blob() {
|
|
|
|
verify_attestation(
|
|
|
|
r#"{
|
|
|
|
"verify_epid_attestation": {
|
|
|
|
"report": {"report":{"id":"5246688123689513540899231107533660789","timestamp":"2024-02-07T17:06:23.913745","version":4,"epidPseudonym":"+CUyIi74LPqS6M0NF7YrSxLqPdX3MKs6D6LIPqRG/ZEB4WmxZVvxAJwdwg/0m9cYnUUQguLnJotthX645lAogfJgO8Xg5/91lSegwyUKvHmKgtjOHX/YTbVe/wmgWiBdaL+KmarY0Je459Px/FqGLWLsAF7egPAJRd1Xn88Znrs=","advisoryURL":"https://security-center.intel.com","advisoryIDs":["INTEL-SA-00161","INTEL-SA-00219","INTEL-SA-00289","INTEL-SA-00334","INTEL-SA-00615"],"isvEnclaveQuoteStatus":"CONFIGURATION_AND_SW_HARDENING_NEEDED","platformInfoBlob":"150200650000080000141402040180070000000000000000000D00000C000000020000000000000CB0F08115F3DE71AE97980FE5E10B042054930ACE356C79EC44603D3F890756EC6ED73927A7C58CDE9AF1E754AEC77E335E8D80294407936BEB6404F27669FF7BB1","isvEnclaveQuoteBody":"AgABALAMAAAPAA8AAAAAAFHK9aSLRQ1iSu/jKG0xSJQAAAAAAAAAAAAAAAAAAAAAFBQCBwGAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAHAAAAAAAAAOPC8qW4QNieBprK/8rbZRDvhmpz06nuVxAO1fhkbuS7AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAc8uUpEUEPvz8ZkFapjVh5WlWaLoAJM/f80T0EhGInHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACRE7C+d+1dDWhoDsdyBrjVh+1AZ5txMhzN1UBeTVSmggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"reportsig":"YaY4SPvkfR4P2E8A5huutCeS+vY/ir+xq6disalNfNtAcUyOIOqTPVXhAZgY1M5B47Hjj1oYWf2qC2w+dnj7VcZjzO9oR0pJYdA+A7jaVrNzH2eXA79yICkuU8WE/x58I0j5vjXLoHXahaKlpZkMeTphqBY8u+FTVSdP3cWPho4viPapTfQRuEWmYq4KIq2zSr6wLg3Pz+yQ+G3e9BASVkLYxdYGTDFH1pMmfas9SEI7V4I+j8DaXmL8bucSRakmcQdmDMPGiA7mvIhSAlprzCrdxM7CHeUC6MPLN1fmFFcc9kyO/ved69j/651MWC83GgxSJ15L80U+DQzmrSW8xg=="},
|
|
|
|
"mrenclave": "e3c2f2a5b840d89e069acaffcadb6510ef866a73d3a9ee57100ed5f8646ee4bb",
|
|
|
|
"user_data": "9113b0be77ed5d0d68680ec77206b8d587ed40679b71321ccdd5405e4d54a6820000000000000000000000000000000000000000000000000000000000000000"
|
|
|
|
}
|
|
|
|
}"#,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|