From fe9d87991dece2dcea395530a2ea62c80ba376be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 15:08:33 +0530 Subject: [PATCH 01/44] first code integration --- .gitmodules | 6 + .../onchainRA/AutomataDcapV3Attestation.sol | 707 ++++++++++++++++++ .../onchainRA/assets/0923/identity.json | 87 +++ .../onchainRA/assets/0923/tcbInfo.json | 221 ++++++ .../onchainRA/assets/0923/v3quote.json | 57 ++ .../thirdparty/onchainRA/assets/v3quote.json | 57 ++ .../onchainRA/interfaces/IAttestation.sol | 6 + .../onchainRA/interfaces/ISigVerifyLib.sol | 62 ++ .../onchainRA/lib/EnclaveIdStruct.sol | 28 + .../onchainRA/lib/PEMCertChainLib.sol | 347 +++++++++ .../onchainRA/lib/QuoteV3Auth/V3Parser.sol | 335 +++++++++ .../onchainRA/lib/QuoteV3Auth/V3Struct.sol | 79 ++ .../onchainRA/lib/TCBInfoStruct.sol | 27 + .../lib/interfaces/IPEMCertChainLib.sol | 43 ++ .../thirdparty/onchainRA/utils/Asn1Decode.sol | 202 +++++ .../thirdparty/onchainRA/utils/BytesUtils.sol | 341 +++++++++ .../thirdparty/onchainRA/utils/RsaVerify.sol | 226 ++++++ .../thirdparty/onchainRA/utils/SHA1.sol | 156 ++++ .../onchainRA/utils/SigVerifyLib.sol | 119 +++ .../onchainRA/utils/X509DateUtils.sol | 68 ++ packages/protocol/lib/solady | 1 + .../packages/protocol/lib/p256-verifier | 1 + .../protocol/packages/protocol/lib/solady | 1 + 23 files changed, 3177 insertions(+) create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol create mode 100644 packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol create mode 160000 packages/protocol/lib/solady create mode 160000 packages/protocol/packages/protocol/lib/p256-verifier create mode 160000 packages/protocol/packages/protocol/lib/solady diff --git a/.gitmodules b/.gitmodules index d075cf60403..ab5962bbf53 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,3 +14,9 @@ path = packages/protocol/lib/forge-std url = https://github.com/foundry-rs/forge-std branch = chore/v1.5.1 +[submodule "packages/protocol/lib/solady"] + path = packages/protocol/lib/solady + url = https://github.com/Vectorized/solady +[submodule "packages/protocol/lib/p256-verifier"] + path = packages/protocol/lib/p256-verifier + url = https://github.com/daimo-eth/p256-verifier diff --git a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol new file mode 100644 index 00000000000..b05eeb52a3e --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol @@ -0,0 +1,707 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {V3Struct} from "./lib/QuoteV3Auth/V3Struct.sol"; +import {V3Parser} from "./lib/QuoteV3Auth/V3Parser.sol"; +import {IPEMCertChainLib} from "./lib/interfaces/IPEMCertChainLib.sol"; +import {PEMCertChainLib} from "./lib/PEMCertChainLib.sol"; +import {TCBInfoStruct} from "./lib/TCBInfoStruct.sol"; +import {EnclaveIdStruct} from "./lib/EnclaveIdStruct.sol"; +import {IAttestation} from "./interfaces/IAttestation.sol"; + +// Internal Libraries +import {Base64} from "solady/src/utils/Base64.sol"; +import {LibString} from "solady/src/utils/LibString.sol"; +import {BytesUtils} from "./utils/BytesUtils.sol"; + +// External Libraries +import {ISigVerifyLib} from "./interfaces/ISigVerifyLib.sol"; + +// import "hardhat/console.sol"; +// import "forge-std/console.sol"; + +contract AutomataDcapV3Attestation is IAttestation { + using BytesUtils for bytes; + + ISigVerifyLib public immutable sigVerifyLib; + IPEMCertChainLib public immutable pemCertLib; + + // https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/e7604e02331b3377f3766ed3653250e03af72d45/QuoteVerification/QVL/Src/AttestationLibrary/src/CertVerification/X509Constants.h#L64 + uint256 constant CPUSVN_LENGTH = 16; + + // keccak256(hex"0ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394") + // the uncompressed (0x04) prefix is not included in the pubkey pre-image + bytes32 constant ROOTCA_PUBKEY_HASH = + 0x89f72d7c488e5b53a77c23ebcb36970ef7eb5bcf6658e9b8292cfbe4703a8473; + + uint8 constant INVALID_EXIT_CODE = 255; + + bool private checkLocalEnclaveReport; + mapping(bytes32 => bool) private trustedUserMrEnclave; + mapping(bytes32 => bool) private trustedUserMrSigner; + + // Quote Collateral Configuration + + // Index definition: + // 0 = Quote PCKCrl + // 1 = RootCrl + mapping(uint256 => mapping(bytes => bool)) private serialNumIsRevoked; + // fmspc => tcbInfo + mapping(string => TCBInfoStruct.TCBInfo) public tcbInfo; + EnclaveIdStruct.EnclaveId public qeIdentity; + + address public owner; + + constructor(address sigVerifyLibAddr, address pemCertLibAddr) { + sigVerifyLib = ISigVerifyLib(sigVerifyLibAddr); + pemCertLib = PEMCertChainLib(pemCertLibAddr); + owner = msg.sender; + } + + modifier onlyOwner() { + require(msg.sender == owner, "onlyOwner"); + _; + } + + function setMrSigner(bytes32 _mrSigner, bool _trusted) external onlyOwner { + trustedUserMrSigner[_mrSigner] = _trusted; + } + + function setMrEnclave( + bytes32 _mrEnclave, + bool _trusted + ) external onlyOwner { + trustedUserMrEnclave[_mrEnclave] = _trusted; + } + + function addRevokedCertSerialNum( + uint256 index, + bytes[] calldata serialNumBatch + ) external onlyOwner { + for (uint256 i = 0; i < serialNumBatch.length; i++) { + if (serialNumIsRevoked[index][serialNumBatch[i]]) { + continue; + } + serialNumIsRevoked[index][serialNumBatch[i]] = true; + } + } + + function removeRevokedCertSerialNum( + uint256 index, + bytes[] calldata serialNumBatch + ) external onlyOwner { + for (uint256 i = 0; i < serialNumBatch.length; i++) { + if (!serialNumIsRevoked[index][serialNumBatch[i]]) { + continue; + } + delete serialNumIsRevoked[index][serialNumBatch[i]]; + } + } + + function configureTcbInfoJson( + string calldata fmspc, + TCBInfoStruct.TCBInfo calldata tcbInfoInput + ) public onlyOwner { + // 2.2M gas + tcbInfo[fmspc] = tcbInfoInput; + } + + function configureQeIdentityJson( + EnclaveIdStruct.EnclaveId calldata qeIdentityInput + ) external onlyOwner { + // 250k gas + qeIdentity = qeIdentityInput; + } + + function toggleLocalReportCheck() external onlyOwner { + checkLocalEnclaveReport = !checkLocalEnclaveReport; + } + + function _attestationTcbIsValid( + TCBInfoStruct.TCBStatus status + ) internal pure virtual returns (bool valid) { + return + status == TCBInfoStruct.TCBStatus.OK || + status == TCBInfoStruct.TCBStatus.TCB_SW_HARDENING_NEEDED || + status == + TCBInfoStruct.TCBStatus.TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED; + } + + function verifyAttestation( + bytes calldata data + ) external view returns (bool) { + (bool success, ) = _verify(data); + return success; + } + + /// @dev Provide the raw quote binary as input + /// @dev The attestation data (or the returned data of this method) + /// is constructed depending on the validity of the quote verification. + /// @dev After confirming that a quote has been verified, the attestation's validity then depends on the + /// status of the associated TCB. + /// @dev Example scenarios as below: + /// -------------------------------- + /// @dev Invalid quote verification: returns (false, INVALID_EXIT_CODE) + /// + /// @dev For all valid quote verification, the validity of the attestation depends on the status of a + /// matching TCBInfo and this is defined in the _attestationTcbIsValid() method, which can be overwritten + /// in derived contracts. (Except for "Revoked" status, which also returns (false, INVALID_EXIT_CODE) value) + /// @dev For all valid quote verification, returns the following data: + /// (_attestationTcbIsValid(), abi.encodePacked(sha256(quote), uint8 exitCode)) + /// @dev exitCode is defined in the {{ TCBInfoStruct.TCBStatus }} enum + function _verify( + bytes calldata quote + ) private view returns (bool, bytes memory) { + bytes memory retData = abi.encodePacked(INVALID_EXIT_CODE); + + // Step 1: Parse the quote input = 152k gas + ( + bool successful, + , + V3Struct.EnclaveReport memory localEnclaveReport, + bytes memory signedQuoteData, + V3Struct.ECDSAQuoteV3AuthData memory authDataV3 + ) = V3Parser.parseInput(quote); + if (!successful) { + return (false, retData); + } + // //console.log("signedQuoteData ="); + //console.logBytes(signedQuoteData); + + // Step 2: Verify application enclave report MRENCLAVE and MRSIGNER + { + if (checkLocalEnclaveReport) { + // 4k gas + bool mrEnclaveIsTrusted = trustedUserMrEnclave[ + localEnclaveReport.mrEnclave + ]; + bool mrSignerIsTrusted = trustedUserMrSigner[ + localEnclaveReport.mrSigner + ]; + + if (!mrEnclaveIsTrusted || !mrSignerIsTrusted) { + return (false, retData); + } + } + } + + // Step 3: Verify enclave identity = 43k gas + V3Struct.EnclaveReport memory qeEnclaveReport; + EnclaveIdStruct.EnclaveIdStatus qeTcbStatus; + { + qeEnclaveReport = V3Parser.parseEnclaveReport( + authDataV3.rawQeReport + ); + bool verifiedEnclaveIdSuccessfully; + ( + verifiedEnclaveIdSuccessfully, + qeTcbStatus + ) = _verifyQEReportWithIdentity(qeEnclaveReport); + if (!verifiedEnclaveIdSuccessfully) { + return (false, retData); + } + if ( + !verifiedEnclaveIdSuccessfully || + qeTcbStatus == + EnclaveIdStruct + .EnclaveIdStatus + .SGX_ENCLAVE_REPORT_ISVSVN_REVOKED + ) { + return (false, retData); + } + } + + // Step 4: Parse Quote CertChain + IPEMCertChainLib.ECSha256Certificate[] memory parsedQuoteCerts; + TCBInfoStruct.TCBInfo memory fetchedTcbInfo; + { + // 660k gas + ( + bool certParsedSuccessfully, + bytes[] memory quoteCerts + ) = pemCertLib.splitCertificateChain( + authDataV3.certification.certData, + 3 + ); + if (!certParsedSuccessfully) { + return (false, retData); + } + + // 536k gas + parsedQuoteCerts = new IPEMCertChainLib.ECSha256Certificate[](3); + for (uint256 i = 0; i < 3; i++) { + quoteCerts[i] = Base64.decode(string(quoteCerts[i])); + //console.log("Step 4.%s: Parse Quote parsedQuoteCerts", i); + //console.logBytes(quoteCerts[i]); + bool isPckCert = i == 0; // additional parsing for PCKCert + bool certDecodedSuccessfully; + (certDecodedSuccessfully, parsedQuoteCerts[i]) = pemCertLib + .decodeCert(quoteCerts[i], isPckCert); + if (!certDecodedSuccessfully) { + return (false, retData); + } + } + } + + // Step 5: basic PCK and TCB check = 381k gas + { + string memory parsedFmspc = parsedQuoteCerts[0] + .pck + .sgxExtension + .fmspc; + fetchedTcbInfo = tcbInfo[parsedFmspc]; + bool tcbConfigured = LibString.eq( + parsedFmspc, + fetchedTcbInfo.fmspc + ); + if (!tcbConfigured) { + return (false, retData); + } + + IPEMCertChainLib.ECSha256Certificate + memory pckCert = parsedQuoteCerts[0]; + bool pceidMatched = LibString.eq( + pckCert.pck.sgxExtension.pceid, + fetchedTcbInfo.pceid + ); + if (!pceidMatched) { + return (false, retData); + } + } + + // Step 6: Verify TCB Level + TCBInfoStruct.TCBStatus tcbStatus; + { + // 4k gas + bool tcbVerified; + (tcbVerified, tcbStatus) = _checkTcbLevels( + parsedQuoteCerts[0].pck, + fetchedTcbInfo + ); + if (!tcbVerified) { + return (false, retData); + } + } + + // Step 7: Verify cert chain for PCK + { + // 660k gas (rootCA pubkey is trusted) + bool pckCertChainVerified = _verifyCertChain(parsedQuoteCerts); + if (!pckCertChainVerified) { + return (false, retData); + } + } + + // Step 8: Verify the local attestation sig and qe report sig = 670k gas + { + bool enclaveReportSigsVerified = _enclaveReportSigVerification( + parsedQuoteCerts[0].pubKey, + signedQuoteData, + authDataV3, + qeEnclaveReport + ); + if (!enclaveReportSigsVerified) { + return (false, retData); + } + } + + retData = abi.encodePacked(sha256(quote), tcbStatus); + + return (_attestationTcbIsValid(tcbStatus), retData); + } + + function _verifyQEReportWithIdentity( + V3Struct.EnclaveReport memory quoteEnclaveReport + ) private view returns (bool, EnclaveIdStruct.EnclaveIdStatus status) { + EnclaveIdStruct.EnclaveId memory enclaveId = qeIdentity; + bool miscselectMatched = quoteEnclaveReport.miscSelect & + enclaveId.miscselectMask == + enclaveId.miscselect; + + bool attributesMatched = quoteEnclaveReport.attributes & + enclaveId.attributesMask == + enclaveId.attributes; + bool mrsignerMatched = quoteEnclaveReport.mrSigner == + enclaveId.mrsigner; + + bool isvprodidMatched = quoteEnclaveReport.isvProdId == + enclaveId.isvprodid; + + bool tcbFound; + for (uint256 i = 0; i < enclaveId.tcbLevels.length; i++) { + EnclaveIdStruct.TcbLevel memory tcb = enclaveId.tcbLevels[i]; + if (tcb.tcb.isvsvn <= quoteEnclaveReport.isvSvn) { + tcbFound = true; + status = tcb.tcbStatus; + break; + } + } + return ( + miscselectMatched && + attributesMatched && + mrsignerMatched && + isvprodidMatched && + tcbFound, + status + ); + } + + function _checkTcbLevels( + IPEMCertChainLib.PCKCertificateField memory pck, + TCBInfoStruct.TCBInfo memory tcb + ) private pure returns (bool, TCBInfoStruct.TCBStatus status) { + for (uint256 i = 0; i < tcb.tcbLevels.length; i++) { + TCBInfoStruct.TCBLevelObj memory current = tcb.tcbLevels[i]; + bool pceSvnIsHigherOrGreater = pck.sgxExtension.pcesvn >= + current.pcesvn; + bool cpuSvnsAreHigherOrGreater = _isCpuSvnHigherOrGreater( + pck.sgxExtension.sgxTcbCompSvnArr, + current.sgxTcbCompSvnArr + ); + if (pceSvnIsHigherOrGreater && cpuSvnsAreHigherOrGreater) { + status = current.status; + bool tcbIsRevoked = status == + TCBInfoStruct.TCBStatus.TCB_REVOKED; + return (!tcbIsRevoked, status); + } + } + return (true, TCBInfoStruct.TCBStatus.TCB_UNRECOGNIZED); + } + + function _isCpuSvnHigherOrGreater( + uint256[] memory pckCpuSvns, + uint8[] memory tcbCpuSvns + ) private pure returns (bool) { + if ( + pckCpuSvns.length != CPUSVN_LENGTH || + tcbCpuSvns.length != CPUSVN_LENGTH + ) { + return false; + } + for (uint256 i = 0; i < CPUSVN_LENGTH; i++) { + if (pckCpuSvns[i] < tcbCpuSvns[i]) { + return false; + } + } + return true; + } + + function _verifyCertChain( + IPEMCertChainLib.ECSha256Certificate[] memory certs + ) private view returns (bool) { + uint256 n = certs.length; + bool certRevoked; + bool certNotExpired; + bool verified; + bool certChainCanBeTrusted; + for (uint256 i = 0; i < n; i++) { + IPEMCertChainLib.ECSha256Certificate memory issuer; + if (i == n - 1) { + // rootCA + issuer = certs[i]; + } else { + issuer = certs[i + 1]; + if (i == n - 2) { + // this cert is expected to be signed by the root + certRevoked = serialNumIsRevoked[ + uint256(IPEMCertChainLib.CRL.ROOT) + ][certs[i].serialNumber]; + } else if (certs[i].isPck) { + certRevoked = serialNumIsRevoked[ + uint256(IPEMCertChainLib.CRL.PCK) + ][certs[i].serialNumber]; + } + if (certRevoked) { + break; + } + } + + certNotExpired = + block.timestamp > certs[i].notBefore && + block.timestamp < certs[i].notAfter; + if (!certNotExpired) { + break; + } + + verified = sigVerifyLib.verifyES256Signature( + certs[i].tbsCertificate, + certs[i].signature, + issuer.pubKey + ); + if (!verified) { + break; + } + + bytes32 issuerPubKeyHash = keccak256(issuer.pubKey); + + if (issuerPubKeyHash == ROOTCA_PUBKEY_HASH) { + certChainCanBeTrusted = true; + break; + } + } + return + !certRevoked && certNotExpired && verified && certChainCanBeTrusted; + } + + function _enclaveReportSigVerification( + bytes memory pckCertPubKey, + bytes memory signedQuoteData, + V3Struct.ECDSAQuoteV3AuthData memory authDataV3, + V3Struct.EnclaveReport memory qeEnclaveReport + ) private view returns (bool) { + bytes32 expectedAuthDataHash = bytes32( + qeEnclaveReport.reportData.substring(0, 32) + ); + bytes memory concatOfAttestKeyAndQeAuthData = abi.encodePacked( + authDataV3.ecdsaAttestationKey, + authDataV3.qeAuthData.data + ); + bytes32 computedAuthDataHash = sha256(concatOfAttestKeyAndQeAuthData); + + bool qeReportDataIsValid = expectedAuthDataHash == computedAuthDataHash; + if (qeReportDataIsValid) { + bool qeSigVerified = sigVerifyLib.verifyES256Signature( + authDataV3.rawQeReport, + authDataV3.qeReportSignature, + pckCertPubKey + ); + bool quoteSigVerified = sigVerifyLib.verifyES256Signature( + signedQuoteData, + authDataV3.ecdsa256BitSignature, + authDataV3.ecdsaAttestationKey + ); + return qeSigVerified && quoteSigVerified; + } else { + return false; + } + } + + function _enclaveParsedReportSigVerification( + bytes memory pckCertPubKey, + bytes memory signedQuoteData, + V3Struct.ParsedECDSAQuoteV3AuthData memory authDataV3, + V3Struct.EnclaveReport memory qeEnclaveReport + ) private view returns (bool) { + bytes32 expectedAuthDataHash = bytes32( + qeEnclaveReport.reportData.substring(0, 32) + ); + bytes memory concatOfAttestKeyAndQeAuthData = abi.encodePacked( + authDataV3.ecdsaAttestationKey, + authDataV3.qeAuthData.data + ); + bytes32 computedAuthDataHash = sha256(concatOfAttestKeyAndQeAuthData); + + bool qeReportDataIsValid = expectedAuthDataHash == computedAuthDataHash; + if (qeReportDataIsValid) { + bytes memory pckSignedQeReportBytes = V3Parser.packQEReport(authDataV3.pckSignedQeReport); + bool qeSigVerified = sigVerifyLib.verifyES256Signature( + pckSignedQeReportBytes, + authDataV3.qeReportSignature, + pckCertPubKey + ); + // console.log("qeSigVerified = %s", qeSigVerified); + bool quoteSigVerified = sigVerifyLib.verifyES256Signature( + signedQuoteData, + authDataV3.ecdsa256BitSignature, + authDataV3.ecdsaAttestationKey + ); + // console.log("quoteSigVerified = %s", quoteSigVerified); + // console.logBytes(signedQuoteData); + // console.logBytes(authDataV3.ecdsa256BitSignature); + // console.logBytes(authDataV3.ecdsaAttestationKey); + return qeSigVerified && quoteSigVerified; + } else { + return false; + } + } + + /// --------------- validate parsed quote --------------- + + /// @dev Provide the parsed quote binary as input + /// @dev The attestation data (or the returned data of this method) + /// is constructed depending on the validity of the quote verification. + /// @dev After confirming that a quote has been verified, the attestation's validity then depends on the + /// status of the associated TCB. + /// @dev Example scenarios as below: + /// -------------------------------- + /// @dev Invalid quote verification: returns (false, INVALID_EXIT_CODE) + /// + /// @dev For all valid quote verification, the validity of the attestation depends on the status of a + /// matching TCBInfo and this is defined in the _attestationTcbIsValid() method, which can be overwritten + /// in derived contracts. (Except for "Revoked" status, which also returns (false, INVALID_EXIT_CODE) value) + /// @dev For all valid quote verification, returns the following data: + /// (_attestationTcbIsValid()) + /// @dev exitCode is defined in the {{ TCBInfoStruct.TCBStatus }} enum + function verifyParsedQuote( + V3Struct.ParsedV3QuoteStruct calldata v3quote + ) external view returns (bool success, uint8 exitStep) { + success = false; + exitStep = 1; + + // Step 1: Parse the quote input = 152k gas + // console.log("Step 1: Parse the quote input = 152k gas"); + // todo: validate(v3quote) + ( + bool successful, + , + , + bytes memory signedQuoteData, + V3Struct.ParsedECDSAQuoteV3AuthData memory authDataV3 + ) = V3Parser.validateParsedInput(v3quote); + if (!successful) { + return (false, exitStep); + } + + exitStep += 1; + // Step 2: Verify application enclave report MRENCLAVE and MRSIGNER + // console.log( + // "Step 2: Verify application enclave report MRENCLAVE and MRSIGNER" + // ); + { + if (checkLocalEnclaveReport) { + // 4k gas + bool mrEnclaveIsTrusted = trustedUserMrEnclave[ + v3quote.localEnclaveReport.mrEnclave + ]; + bool mrSignerIsTrusted = trustedUserMrSigner[ + v3quote.localEnclaveReport.mrSigner + ]; + + if (!mrEnclaveIsTrusted || !mrSignerIsTrusted) { + return (false, exitStep); + } + } + } + + exitStep += 1; + // console.log("Step 3: Verify enclave identity = 43k gas"); + // Step 3: Verify enclave identity = 43k gas + EnclaveIdStruct.EnclaveIdStatus qeTcbStatus; + { + bool verifiedEnclaveIdSuccessfully; + ( + verifiedEnclaveIdSuccessfully, + qeTcbStatus + ) = _verifyQEReportWithIdentity( + v3quote.v3AuthData.pckSignedQeReport + ); + if (!verifiedEnclaveIdSuccessfully) { + return (false, exitStep); + } + if ( + !verifiedEnclaveIdSuccessfully || + qeTcbStatus == + EnclaveIdStruct + .EnclaveIdStatus + .SGX_ENCLAVE_REPORT_ISVSVN_REVOKED + ) { + return (false, exitStep); + } + } + + exitStep += 1; + // console.log("Step 4: Parse Quote CertChain"); + // Step 4: Parse Quote CertChain + IPEMCertChainLib.ECSha256Certificate[] memory parsedQuoteCerts; + TCBInfoStruct.TCBInfo memory fetchedTcbInfo; + { + // 536k gas + parsedQuoteCerts = new IPEMCertChainLib.ECSha256Certificate[](3); + for (uint256 i = 0; i < 3; i++) { + //console.log("Step 4.%s: Parse Quote parsedQuoteCerts", i); + // quoteCerts[i] = Base64.decode(string(authDataV3.certification.certArray[i])); + bool isPckCert = i == 0; // additional parsing for PCKCert + bool certDecodedSuccessfully; + // todo! move decodeCert offchain + (certDecodedSuccessfully, parsedQuoteCerts[i]) = pemCertLib + .decodeCert( + authDataV3.certification.decodedCertDataArray[i], + isPckCert + ); + if (!certDecodedSuccessfully) { + return (false, exitStep); + } + } + } + + exitStep += 1; + // console.log("Step 5: basic PCK and TCB check = 381k gas"); + // Step 5: basic PCK and TCB check = 381k gas + { + string memory parsedFmspc = parsedQuoteCerts[0] + .pck + .sgxExtension + .fmspc; + fetchedTcbInfo = tcbInfo[parsedFmspc]; + bool tcbConfigured = LibString.eq( + parsedFmspc, + fetchedTcbInfo.fmspc + ); + if (!tcbConfigured) { + return (false, exitStep); + } + + IPEMCertChainLib.ECSha256Certificate + memory pckCert = parsedQuoteCerts[0]; + bool pceidMatched = LibString.eq( + pckCert.pck.sgxExtension.pceid, + fetchedTcbInfo.pceid + ); + if (!pceidMatched) { + return (false, exitStep); + } + } + + exitStep += 1; + // console.log("Step 6: Verify TCB Level"); + // Step 6: Verify TCB Level + TCBInfoStruct.TCBStatus tcbStatus; + { + // 4k gas + bool tcbVerified; + (tcbVerified, tcbStatus) = _checkTcbLevels( + parsedQuoteCerts[0].pck, + fetchedTcbInfo + ); + if (!tcbVerified) { + return (false, exitStep); + } + } + + exitStep += 1; + // console.log("Step 7: Verify cert chain for PCK"); + // Step 7: Verify cert chain for PCK + { + // 660k gas (rootCA pubkey is trusted) + bool pckCertChainVerified = _verifyCertChain(parsedQuoteCerts); + if (!pckCertChainVerified) { + return (false, exitStep); + } + } + + exitStep += 1; + // console.log( + // "Step 8: Verify the local attestation sig and qe report sig = 670k gas" + // ); + // Step 8: Verify the local attestation sig and qe report sig + { + bool enclaveReportSigsVerified = _enclaveParsedReportSigVerification( + parsedQuoteCerts[0].pubKey, + signedQuoteData, + authDataV3, + v3quote.v3AuthData.pckSignedQeReport + ); + if (!enclaveReportSigsVerified) { + return (false, exitStep); + } + } + + // retData = abi.encodePacked( + // sha256(abi.encodePacked(v3quote)), + // tcbStatus + // ); + exitStep += 1; + success = _attestationTcbIsValid(tcbStatus); + // console.log("Step 9: return success = %s, tcbStatus = %s", success, uint256(tcbStatus)); + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json new file mode 100644 index 00000000000..3646327679f --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json @@ -0,0 +1,87 @@ +{ + "enclaveIdentity": { + "id": "QE", + "version": 2, + "issueDate": "2024-01-03T01:56:45Z", + "nextUpdate": "2024-02-02T01:56:45Z", + "tcbEvaluationDataNumber": 16, + "miscselect": "00000000", + "miscselectMask": "FFFFFFFF", + "attributes": "11000000000000000000000000000000", + "attributesMask": "FBFFFFFFFFFFFFFF0000000000000000", + "mrsigner": "8C4F5775D796503E96137F77C68A829A0056AC8DED70140B081B094490C57BFF", + "isvprodid": 1, + "tcbLevels": [ + { + "tcb": { + "isvsvn": 8 + }, + "tcbDate": "2023-08-09T00:00:00Z", + "tcbStatus": "UpToDate" + }, + { + "tcb": { + "isvsvn": 6 + }, + "tcbDate": "2021-11-10T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": [ + "INTEL-SA-00615" + ] + }, + { + "tcb": { + "isvsvn": 5 + }, + "tcbDate": "2020-11-11T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": [ + "INTEL-SA-00477", + "INTEL-SA-00615" + ] + }, + { + "tcb": { + "isvsvn": 4 + }, + "tcbDate": "2019-11-13T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": [ + "INTEL-SA-00334", + "INTEL-SA-00477", + "INTEL-SA-00615" + ] + }, + { + "tcb": { + "isvsvn": 2 + }, + "tcbDate": "2019-05-15T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": [ + "INTEL-SA-00219", + "INTEL-SA-00293", + "INTEL-SA-00334", + "INTEL-SA-00477", + "INTEL-SA-00615" + ] + }, + { + "tcb": { + "isvsvn": 1 + }, + "tcbDate": "2018-08-15T00: 00: 00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": [ + "INTEL-SA-00202", + "INTEL-SA-00219", + "INTEL-SA-00293", + "INTEL-SA-00334", + "INTEL-SA-00477", + "INTEL-SA-00615" + ] + } + ] + }, + "signature": "510deee07e2ca622264c87e8324351a3c3faf7679ee13efa2883d4cc30373c6f51e45f1fc95c983410bf66604f1ee218a3ee6c8e279367a1991f40cba53aff9b" +} \ No newline at end of file diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json new file mode 100644 index 00000000000..a3bf39eabaf --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json @@ -0,0 +1,221 @@ +{ + "tcbInfo": { + "version": 2, + "issueDate": "2024-01-10T02:32:48Z", + "nextUpdate": "2024-02-09T02:32:48Z", + "fmspc": "00606a000000", + "pceId": "0000", + "tcbType": 0, + "tcbEvaluationDataNumber": 16, + "tcbLevels": [ + { + "tcb": { + "sgxtcbcomp01svn": 12, + "sgxtcbcomp02svn": 12, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 1, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-08-09T00:00:00Z", + "tcbStatus": "SWHardeningNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 12, + "sgxtcbcomp02svn": 12, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-08-09T00:00:00Z", + "tcbStatus": "ConfigurationAndSWHardeningNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 11, + "sgxtcbcomp02svn": 11, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 1, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-02-15T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 11, + "sgxtcbcomp02svn": 11, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-02-15T00:00:00Z", + "tcbStatus": "OutOfDateConfigurationNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 7, + "sgxtcbcomp02svn": 9, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 1, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2022-08-10T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 7, + "sgxtcbcomp02svn": 9, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2022-08-10T00:00:00Z", + "tcbStatus": "OutOfDateConfigurationNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 4, + "sgxtcbcomp02svn": 4, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 11 + }, + "tcbDate": "2021-11-10T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 4, + "sgxtcbcomp02svn": 4, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 10 + }, + "tcbDate": "2020-11-11T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 4, + "sgxtcbcomp02svn": 4, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 5 + }, + "tcbDate": "2018-01-04T00:00:00Z", + "tcbStatus": "OutOfDate" + } + ] + }, + "signature": "82d69c3a986618c91ac973fc2c4ae1baf7ec0de1c1e2366a412dabc3198c507caafb6bce84c8ee3ca13091f442ae387688431ff2779257328b59bfd7cfd2772e" +} \ No newline at end of file diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json new file mode 100644 index 00000000000..c55ea89f652 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json @@ -0,0 +1,57 @@ +{ + "header": { + "version": "0x0300", + "attestationKeyType": "0x0200", + "teeType": "0x00000000", + "qeSvn": "0x0900", + "pceSvn": "0x0e00", + "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", + "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" + }, + "localEnclaveReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x0700000000000000e700000000000000", + "mrEnclave": "0x21c3fac1fee25b4f8a4f5764da7dc52ff9c3cf2aa5b6b68c5a19c4ec69c51421", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 0, + "isvSvn": 0, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + }, + "v3AuthData": { + "ecdsa256BitSignature": "0x0bab69c919b1247266c11b137097623aac4d3e4e36c9000f7c22ab7b767145bac9cd5f1ab1eae683ac85a53b4a0d0dbfe19055e5babe254451e1646a1be42c1b", + "ecdsaAttestationKey": "0x98dcbff3d66af81d0004ae624e8d922da31c4aefc2a85d0723f38997563ea5449dcbf7d4d351b171625415fde6f443ea3e56d099fa62cc77553f80f18a054ba7", + "pckSignedQeReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x1500000000000000e700000000000000", + "mrEnclave": "0x192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x8c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 1, + "isvSvn": 9, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x915aca8fa4e14365a753fc034261f5d8b2a4e75c83c6ffb90316a11ba6df1b550000000000000000000000000000000000000000000000000000000000000000" + }, + "qeReportSignature": "0xc5ce106db64b25bdd5c9f6c52bfb993cd231d73774a1e9532ed155b0ee43848ec2107e28f63313405a33c59b547f74099b673bc8ee101797ce9c6ba01fb399c5", + "qeAuthData": { + "parsedDataSize": 32, + "data": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + }, + "certification": { + "certType": 5, + "certDataSize": 3682, + "decodedCertDataArray": [ + "0x308204f330820499a003020102021500bcfe8d88f1717f9f26898051b089aa089f22897a300a06082a8648ce3d04030230703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3233303832383131313330355a170d3330303832383131313330355a30703122302006035504030c19496e74656c205347582050434b204365727469666963617465311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000432b004ab4baae47a3d781dfd494a9b8f3b5343515cb35c10afa75878d85d74514d001545a0d58e3ca1e060eedbcde57d884c6101e731c18f38eff64b96c948d4a382030e3082030a301f0603551d23041830168014956f5dcdbd1be1e94049c9d4f433ce01570bde54306b0603551d1f046430623060a05ea05c865a68747470733a2f2f6170692e7472757374656473657276696365732e696e74656c2e636f6d2f7367782f63657274696669636174696f6e2f76342f70636b63726c3f63613d706c6174666f726d26656e636f64696e673d646572301d0603551d0e041604145357a665cf5bc991849f9098fc3627f3aa06b058300e0603551d0f0101ff0404030206c0300c0603551d130101ff040230003082023b06092a864886f84d010d010482022c30820228301e060a2a864886f84d010d01010410fe46ae011cce8a4d6e8334b08d1bb40130820165060a2a864886f84d010d0102308201553010060b2a864886f84d010d01020102010b3010060b2a864886f84d010d01020202010b3010060b2a864886f84d010d0102030201033010060b2a864886f84d010d0102040201033011060b2a864886f84d010d010205020200ff3011060b2a864886f84d010d010206020200ff3010060b2a864886f84d010d0102070201003010060b2a864886f84d010d0102080201003010060b2a864886f84d010d0102090201003010060b2a864886f84d010d01020a0201003010060b2a864886f84d010d01020b0201003010060b2a864886f84d010d01020c0201003010060b2a864886f84d010d01020d0201003010060b2a864886f84d010d01020e0201003010060b2a864886f84d010d01020f0201003010060b2a864886f84d010d0102100201003010060b2a864886f84d010d01021102010d301f060b2a864886f84d010d01021204100b0b0303ffff000000000000000000003010060a2a864886f84d010d0103040200003014060a2a864886f84d010d0104040600606a000000300f060a2a864886f84d010d01050a0101301e060a2a864886f84d010d010604104589ccebf2644f0ade48ff1e15c46bfb3044060a2a864886f84d010d010730363010060b2a864886f84d010d0107010101ff3010060b2a864886f84d010d0107020101ff3010060b2a864886f84d010d0107030101ff300a06082a8648ce3d040302034800304502201ab7bf1d8335a99004599474c7be98f6040aef385e0a050a0230489578709693022100e37a7bb6bc01f34b3eda2c1a8660dd02708cc0954f2e2484bb00d017c544812c", + "0x308202963082023da003020102021500956f5dcdbd1be1e94049c9d4f433ce01570bde54300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130353031305a170d3333303532313130353031305a30703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000435207feeddb595748ed82bb3a71c3be1e241ef61320c6816e6b5c2b71dad5532eaea12a4eb3f948916429ea47ba6c3af82a15e4b19664e52657939a2d96633dea381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e04160414956f5dcdbd1be1e94049c9d4f433ce01570bde54300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100300a06082a8648ce3d040302034700304402205ec5648b4c3e8ba558196dd417fdb6b9a5ded182438f551e9c0f938c3d5a8b970220261bd520260f9c647d3569be8e14a32892631ac358b994478088f4d2b27cf37e", + "0x3082028f30820234a003020102021422650cd65a9d3489f383b49552bf501b392706ac300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130343531305a170d3439313233313233353935395a3068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d030107034200040ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394a381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e0416041422650cd65a9d3489f383b49552bf501b392706ac300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020101300a06082a8648ce3d0403020349003046022100e5bfe50911f92f428920dc368a302ee3d12ec5867ff622ec6497f78060c13c20022100e09d25ac7a0cb3e5e8e68fec5fa3bd416c47440bd950639d450edcbea4576aa2" + ] + } + } +} \ No newline at end of file diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json new file mode 100644 index 00000000000..c55ea89f652 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json @@ -0,0 +1,57 @@ +{ + "header": { + "version": "0x0300", + "attestationKeyType": "0x0200", + "teeType": "0x00000000", + "qeSvn": "0x0900", + "pceSvn": "0x0e00", + "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", + "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" + }, + "localEnclaveReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x0700000000000000e700000000000000", + "mrEnclave": "0x21c3fac1fee25b4f8a4f5764da7dc52ff9c3cf2aa5b6b68c5a19c4ec69c51421", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 0, + "isvSvn": 0, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + }, + "v3AuthData": { + "ecdsa256BitSignature": "0x0bab69c919b1247266c11b137097623aac4d3e4e36c9000f7c22ab7b767145bac9cd5f1ab1eae683ac85a53b4a0d0dbfe19055e5babe254451e1646a1be42c1b", + "ecdsaAttestationKey": "0x98dcbff3d66af81d0004ae624e8d922da31c4aefc2a85d0723f38997563ea5449dcbf7d4d351b171625415fde6f443ea3e56d099fa62cc77553f80f18a054ba7", + "pckSignedQeReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x1500000000000000e700000000000000", + "mrEnclave": "0x192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x8c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 1, + "isvSvn": 9, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x915aca8fa4e14365a753fc034261f5d8b2a4e75c83c6ffb90316a11ba6df1b550000000000000000000000000000000000000000000000000000000000000000" + }, + "qeReportSignature": "0xc5ce106db64b25bdd5c9f6c52bfb993cd231d73774a1e9532ed155b0ee43848ec2107e28f63313405a33c59b547f74099b673bc8ee101797ce9c6ba01fb399c5", + "qeAuthData": { + "parsedDataSize": 32, + "data": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + }, + "certification": { + "certType": 5, + "certDataSize": 3682, + "decodedCertDataArray": [ + "0x308204f330820499a003020102021500bcfe8d88f1717f9f26898051b089aa089f22897a300a06082a8648ce3d04030230703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3233303832383131313330355a170d3330303832383131313330355a30703122302006035504030c19496e74656c205347582050434b204365727469666963617465311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000432b004ab4baae47a3d781dfd494a9b8f3b5343515cb35c10afa75878d85d74514d001545a0d58e3ca1e060eedbcde57d884c6101e731c18f38eff64b96c948d4a382030e3082030a301f0603551d23041830168014956f5dcdbd1be1e94049c9d4f433ce01570bde54306b0603551d1f046430623060a05ea05c865a68747470733a2f2f6170692e7472757374656473657276696365732e696e74656c2e636f6d2f7367782f63657274696669636174696f6e2f76342f70636b63726c3f63613d706c6174666f726d26656e636f64696e673d646572301d0603551d0e041604145357a665cf5bc991849f9098fc3627f3aa06b058300e0603551d0f0101ff0404030206c0300c0603551d130101ff040230003082023b06092a864886f84d010d010482022c30820228301e060a2a864886f84d010d01010410fe46ae011cce8a4d6e8334b08d1bb40130820165060a2a864886f84d010d0102308201553010060b2a864886f84d010d01020102010b3010060b2a864886f84d010d01020202010b3010060b2a864886f84d010d0102030201033010060b2a864886f84d010d0102040201033011060b2a864886f84d010d010205020200ff3011060b2a864886f84d010d010206020200ff3010060b2a864886f84d010d0102070201003010060b2a864886f84d010d0102080201003010060b2a864886f84d010d0102090201003010060b2a864886f84d010d01020a0201003010060b2a864886f84d010d01020b0201003010060b2a864886f84d010d01020c0201003010060b2a864886f84d010d01020d0201003010060b2a864886f84d010d01020e0201003010060b2a864886f84d010d01020f0201003010060b2a864886f84d010d0102100201003010060b2a864886f84d010d01021102010d301f060b2a864886f84d010d01021204100b0b0303ffff000000000000000000003010060a2a864886f84d010d0103040200003014060a2a864886f84d010d0104040600606a000000300f060a2a864886f84d010d01050a0101301e060a2a864886f84d010d010604104589ccebf2644f0ade48ff1e15c46bfb3044060a2a864886f84d010d010730363010060b2a864886f84d010d0107010101ff3010060b2a864886f84d010d0107020101ff3010060b2a864886f84d010d0107030101ff300a06082a8648ce3d040302034800304502201ab7bf1d8335a99004599474c7be98f6040aef385e0a050a0230489578709693022100e37a7bb6bc01f34b3eda2c1a8660dd02708cc0954f2e2484bb00d017c544812c", + "0x308202963082023da003020102021500956f5dcdbd1be1e94049c9d4f433ce01570bde54300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130353031305a170d3333303532313130353031305a30703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000435207feeddb595748ed82bb3a71c3be1e241ef61320c6816e6b5c2b71dad5532eaea12a4eb3f948916429ea47ba6c3af82a15e4b19664e52657939a2d96633dea381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e04160414956f5dcdbd1be1e94049c9d4f433ce01570bde54300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100300a06082a8648ce3d040302034700304402205ec5648b4c3e8ba558196dd417fdb6b9a5ded182438f551e9c0f938c3d5a8b970220261bd520260f9c647d3569be8e14a32892631ac358b994478088f4d2b27cf37e", + "0x3082028f30820234a003020102021422650cd65a9d3489f383b49552bf501b392706ac300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130343531305a170d3439313233313233353935395a3068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d030107034200040ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394a381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e0416041422650cd65a9d3489f383b49552bf501b392706ac300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020101300a06082a8648ce3d0403020349003046022100e5bfe50911f92f428920dc368a302ee3d12ec5867ff622ec6497f78060c13c20022100e09d25ac7a0cb3e5e8e68fec5fa3bd416c47440bd950639d450edcbea4576aa2" + ] + } + } +} \ No newline at end of file diff --git a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol new file mode 100644 index 00000000000..7a8a9d74ea2 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol @@ -0,0 +1,6 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +interface IAttestation { + function verifyAttestation(bytes calldata data) external returns (bool); +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol new file mode 100644 index 00000000000..8ff441a236c --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol @@ -0,0 +1,62 @@ +//SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +interface ISigVerifyLib { + enum KeyType { + RSA, + ECDSA + } + + struct PublicKey { + KeyType keyType; + // If RSA, pubKey = abi.encodePacked(exponent, modulus) + // If ECDSA, pubKey = abi.encodePacked(gx, gy) + bytes pubKey; + } + + enum CertSigAlgorithm { + Sha256WithRSAEncryption, + Sha1WithRSAEncryption + } + + struct Certificate { + // Asn.1 DER encoding of the to-be-signed certificate + bytes tbsCertificate; + PublicKey publicKey; + bytes signature; + CertSigAlgorithm sigAlg; + } + + enum Algorithm { + RS256, + ES256, + RS1 + } + + function verifyAttStmtSignature(bytes memory tbs, bytes memory signature, PublicKey memory publicKey, Algorithm alg) + external + view + returns (bool); + + function verifyCertificateSignature( + bytes memory tbs, + bytes memory signature, + PublicKey memory publicKey, + CertSigAlgorithm alg + ) external view returns (bool); + + function verifyRS256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + external + view + returns (bool sigValid); + + function verifyRS1Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + external + view + returns (bool sigValid); + + function verifyES256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + external + view + returns (bool sigValid); +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol new file mode 100644 index 00000000000..47d3c7d2d22 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol @@ -0,0 +1,28 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +library EnclaveIdStruct { + struct EnclaveId { + bytes4 miscselect; + bytes4 miscselectMask; + uint16 isvprodid; + bytes16 attributes; + bytes16 attributesMask; + bytes32 mrsigner; + TcbLevel[] tcbLevels; + } + + struct TcbLevel { + TcbObj tcb; + EnclaveIdStatus tcbStatus; + } + + struct TcbObj { + uint16 isvsvn; + } + + enum EnclaveIdStatus { + OK, + SGX_ENCLAVE_REPORT_ISVSVN_REVOKED + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol new file mode 100644 index 00000000000..b47eb04d798 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol @@ -0,0 +1,347 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {LibString} from "solady/src/Milady.sol"; +import {Asn1Decode, NodePtr} from "../utils/Asn1Decode.sol"; +import {BytesUtils} from "../utils/BytesUtils.sol"; +import {X509DateUtils} from "../utils/X509DateUtils.sol"; +import {IPEMCertChainLib} from "./interfaces/IPEMCertChainLib.sol"; + +contract PEMCertChainLib is IPEMCertChainLib { + using Asn1Decode for bytes; + using NodePtr for uint256; + using BytesUtils for bytes; + + string constant HEADER = "-----BEGIN CERTIFICATE-----"; + string constant FOOTER = "-----END CERTIFICATE-----"; + uint256 internal constant HEADER_LENGTH = 27; + uint256 internal constant FOOTER_LENGTH = 25; + + string constant PCK_COMMON_NAME = "Intel SGX PCK Certificate"; + string constant PLATFORM_ISSUER_NAME = "Intel SGX PCK Platform CA"; + string constant PROCESSOR_ISSUER_NAME = "Intel SGX PCK Processor CA"; + bytes constant SGX_EXTENSION_OID = hex"2A864886F84D010D01"; + bytes constant TCB_OID = hex"2A864886F84D010D0102"; + bytes constant PCESVN_OID = hex"2A864886F84D010D010211"; + bytes constant PCEID_OID = hex"2A864886F84D010D0103"; + bytes constant FMSPC_OID = hex"2A864886F84D010D0104"; + + // https://github.com/intel/SGXDataCenterAttestationPrimitives/blob/e7604e02331b3377f3766ed3653250e03af72d45/QuoteVerification/QVL/Src/AttestationLibrary/src/CertVerification/X509Constants.h#L64 + uint256 constant SGX_TCB_CPUSVN_SIZE = 16; + + struct PCKTCBFlags { + bool fmspcFound; + bool pceidFound; + bool tcbFound; + } + + function splitCertificateChain(bytes memory pemChain, uint256 size) + external + pure + returns (bool success, bytes[] memory certs) + { + certs = new bytes[](size); + string memory pemChainStr = string(pemChain); + + uint256 index = 0; + uint256 len = pemChain.length; + + for (uint256 i = 0; i < size; i++) { + string memory input; + if (i > 0) { + input = LibString.slice(pemChainStr, index, index + len); + } else { + input = pemChainStr; + } + uint256 increment; + (success, certs[i], increment) = _removeHeadersAndFooters(input); + + if (!success) { + return (false, certs); + } + + index += increment; + } + + success = true; + } + + function decodeCert(bytes memory der, bool isPckCert) + external + pure + returns (bool success, ECSha256Certificate memory cert) + { + uint256 root = der.root(); + + // Entering tbsCertificate sequence + uint256 tbsParentPtr = der.firstChildOf(root); + + // Begin iterating through the descendants of tbsCertificate + uint256 tbsPtr = der.firstChildOf(tbsParentPtr); + + // The Serial Number is located one element below Version + + // The issuer commonName value is contained in the Issuer sequence + // which is 3 elements below the first element of the tbsCertificate sequence + + // The Validity sequence is located 4 elements below the first element of the tbsCertificate sequence + + // The subject commanName value is contained in the Subject sequence + // which is 5 elements below the first element of the tbsCertificate sequence + + // The PublicKey is located in the second element of subjectPublicKeyInfo sequence + // which is 6 elements below the first element of the tbsCertificate sequence + + tbsPtr = der.nextSiblingOf(tbsPtr); + + { + bytes memory serialNumBytes = der.bytesAt(tbsPtr); + cert.serialNumber = serialNumBytes; + } + + tbsPtr = der.nextSiblingOf(tbsPtr); + tbsPtr = der.nextSiblingOf(tbsPtr); + + if (isPckCert) { + uint256 issuerPtr = der.firstChildOf(tbsPtr); + issuerPtr = der.firstChildOf(issuerPtr); + issuerPtr = der.firstChildOf(issuerPtr); + issuerPtr = der.nextSiblingOf(issuerPtr); + cert.pck.issuerName = string(der.bytesAt(issuerPtr)); + bool issuerNameIsValid = LibString.eq(cert.pck.issuerName, PLATFORM_ISSUER_NAME) + || LibString.eq(cert.pck.issuerName, PROCESSOR_ISSUER_NAME); + if (!issuerNameIsValid) { + return (false, cert); + } + } + + tbsPtr = der.nextSiblingOf(tbsPtr); + + { + uint256 notBeforePtr = der.firstChildOf(tbsPtr); + uint256 notAfterPtr = der.nextSiblingOf(notBeforePtr); + bytes1 notBeforeTag = der[notBeforePtr.ixs()]; + bytes1 notAfterTag = der[notAfterPtr.ixs()]; + if ((notBeforeTag != 0x17 && notBeforeTag == 0x18) || (notAfterTag != 0x17 && notAfterTag != 0x18)) { + return (false, cert); + } + cert.notBefore = X509DateUtils.toTimestamp(der.bytesAt(notBeforePtr)); + cert.notAfter = X509DateUtils.toTimestamp(der.bytesAt(notAfterPtr)); + } + + tbsPtr = der.nextSiblingOf(tbsPtr); + + if (isPckCert) { + uint256 subjectPtr = der.firstChildOf(tbsPtr); + subjectPtr = der.firstChildOf(subjectPtr); + subjectPtr = der.firstChildOf(subjectPtr); + subjectPtr = der.nextSiblingOf(subjectPtr); + cert.pck.commonName = string(der.bytesAt(subjectPtr)); + if (!LibString.eq(cert.pck.commonName, PCK_COMMON_NAME)) { + return (false, cert); + } + } + + tbsPtr = der.nextSiblingOf(tbsPtr); + + { + // Entering subjectPublicKeyInfo sequence + uint256 subjectPublicKeyInfoPtr = der.firstChildOf(tbsPtr); + subjectPublicKeyInfoPtr = der.nextSiblingOf(subjectPublicKeyInfoPtr); + + // The Signature sequence is located two sibling elements below the tbsCertificate element + uint256 sigPtr = der.nextSiblingOf(tbsParentPtr); + sigPtr = der.nextSiblingOf(sigPtr); + + // Skip three bytes to the right, TODO: why is it tagged with 0x03? + // the three bytes in question: 0x034700 or 0x034800 or 0x034900 + sigPtr = NodePtr.getPtr(sigPtr.ixs() + 3, sigPtr.ixf() + 3, sigPtr.ixl()); + + sigPtr = der.firstChildOf(sigPtr); + bytes memory sigX = _trimBytes(der.bytesAt(sigPtr), 32); + + sigPtr = der.nextSiblingOf(sigPtr); + bytes memory sigY = _trimBytes(der.bytesAt(sigPtr), 32); + + cert.tbsCertificate = der.allBytesAt(tbsParentPtr); + cert.pubKey = _trimBytes(der.bytesAt(subjectPublicKeyInfoPtr), 64); + cert.signature = abi.encodePacked(sigX, sigY); + } + + if (isPckCert) { + // entering Extension sequence + tbsPtr = der.nextSiblingOf(tbsPtr); + + // check for the extension tag + if (der[tbsPtr.ixs()] != 0xA3) { + return (false, cert); + } + + tbsPtr = der.firstChildOf(tbsPtr); + tbsPtr = der.firstChildOf(tbsPtr); + + bool sgxExtnTraversedSuccessfully; + uint256 pcesvn; + uint256[] memory cpuSvns; + bytes memory fmspcBytes; + bytes memory pceidBytes; + (sgxExtnTraversedSuccessfully, pcesvn, cpuSvns, fmspcBytes, pceidBytes) = + _findPckTcbInfo(der, tbsPtr, tbsParentPtr); + if (!sgxExtnTraversedSuccessfully) { + return (false, cert); + } + cert.pck.sgxExtension.pcesvn = pcesvn; + cert.pck.sgxExtension.sgxTcbCompSvnArr = cpuSvns; + cert.pck.sgxExtension.pceid = LibString.toHexStringNoPrefix(pceidBytes); + cert.pck.sgxExtension.fmspc = LibString.toHexStringNoPrefix(fmspcBytes); + cert.isPck = true; + } + + success = true; + } + + function _removeHeadersAndFooters(string memory pemData) + private + pure + returns (bool success, bytes memory extracted, uint256 endIndex) + { + // Check if the input contains the "BEGIN" and "END" headers + uint256 beginPos = LibString.indexOf(pemData, HEADER); + uint256 endPos = LibString.indexOf(pemData, FOOTER); + + bool headerFound = beginPos != LibString.NOT_FOUND; + bool footerFound = endPos != LibString.NOT_FOUND; + + if (!headerFound || !footerFound) { + return (false, extracted, endIndex); + } + + // Extract the content between the headers + uint256 contentStart = beginPos + HEADER_LENGTH; + + // Extract and return the content + bytes memory contentBytes; + + // do not include newline + bytes memory delimiter = hex"0a"; + string memory contentSlice = LibString.slice(pemData, contentStart, endPos); + string[] memory split = LibString.split(contentSlice, string(delimiter)); + string memory contentStr; + + for (uint256 i = 0; i < split.length; i++) { + contentStr = LibString.concat(contentStr, split[i]); + } + + contentBytes = bytes(contentStr); + return (true, contentBytes, endPos + FOOTER_LENGTH); + } + + function _trimBytes(bytes memory input, uint256 expectedLength) private pure returns (bytes memory output) { + uint256 n = input.length; + + if (n <= expectedLength) { + return input; + } + uint256 lengthDiff = n - expectedLength; + output = input.substring(lengthDiff, expectedLength); + } + + function _findPckTcbInfo(bytes memory der, uint256 tbsPtr, uint256 tbsParentPtr) + private + pure + returns ( + bool success, + uint256 pcesvn, + uint256[] memory cpusvns, + bytes memory fmspcBytes, + bytes memory pceidBytes + ) + { + // iterate through the elements in the Extension sequence + // until we locate the SGX Extension OID + while (tbsPtr != 0) { + uint256 internalPtr = der.firstChildOf(tbsPtr); + if (der[internalPtr.ixs()] != 0x06) { + return (false, pcesvn, cpusvns, fmspcBytes, pceidBytes); + } + + if (BytesUtils.compareBytes(der.bytesAt(internalPtr), SGX_EXTENSION_OID)) { + // 1.2.840.113741.1.13.1 + internalPtr = der.nextSiblingOf(internalPtr); + uint256 extnValueParentPtr = der.rootOfOctetStringAt(internalPtr); + uint256 extnValuePtr = der.firstChildOf(extnValueParentPtr); + + // Copy flags to memory to avoid stack too deep + PCKTCBFlags memory flags; + + while (!(flags.fmspcFound && flags.pceidFound && flags.tcbFound)) { + uint256 extnValueOidPtr = der.firstChildOf(extnValuePtr); + if (der[extnValueOidPtr.ixs()] != 0x06) { + return (false, pcesvn, cpusvns, fmspcBytes, pceidBytes); + } + if (BytesUtils.compareBytes(der.bytesAt(extnValueOidPtr), TCB_OID)) { + // 1.2.840.113741.1.13.1.2 + (flags.tcbFound, pcesvn, cpusvns) = _findTcb(der, extnValueOidPtr); + } + if (BytesUtils.compareBytes(der.bytesAt(extnValueOidPtr), PCEID_OID)) { + // 1.2.840.113741.1.13.1.3 + uint256 pceidPtr = der.nextSiblingOf(extnValueOidPtr); + pceidBytes = der.bytesAt(pceidPtr); + flags.pceidFound = true; + } + if (BytesUtils.compareBytes(der.bytesAt(extnValueOidPtr), FMSPC_OID)) { + // 1.2.840.113741.1.13.1.4 + uint256 fmspcPtr = der.nextSiblingOf(extnValueOidPtr); + fmspcBytes = der.bytesAt(fmspcPtr); + flags.fmspcFound = true; + } + + if (extnValuePtr.ixl() < extnValueParentPtr.ixl()) { + extnValuePtr = der.nextSiblingOf(extnValuePtr); + } else { + break; + } + } + success = flags.fmspcFound && flags.pceidFound && flags.tcbFound; + break; + } + + if (tbsPtr.ixl() < tbsParentPtr.ixl()) { + tbsPtr = der.nextSiblingOf(tbsPtr); + } else { + tbsPtr = 0; // exit + } + } + } + + function _findTcb(bytes memory der, uint256 oidPtr) + private + pure + returns (bool success, uint256 pcesvn, uint256[] memory cpusvns) + { + // sibiling of tcbOid + uint256 tcbPtr = der.nextSiblingOf(oidPtr); + // get the first svn object in the sequence + uint256 svnParentPtr = der.firstChildOf(tcbPtr); + cpusvns = new uint256[](SGX_TCB_CPUSVN_SIZE); + for (uint256 i = 0; i < SGX_TCB_CPUSVN_SIZE + 1; i++) { + uint256 svnPtr = der.firstChildOf(svnParentPtr); // OID + uint256 svnValuePtr = der.nextSiblingOf(svnPtr); // value + bytes memory svnValueBytes = der.bytesAt(svnValuePtr); + uint16 svnValue = + svnValueBytes.length < 2 ? uint16(bytes2(svnValueBytes)) / 256 : uint16(bytes2(svnValueBytes)); + if (BytesUtils.compareBytes(der.bytesAt(svnPtr), PCESVN_OID)) { + // pcesvn is 4 bytes in size + pcesvn = uint256(svnValue); + } else { + // each cpusvn is at maximum two bytes in size + uint256 cpusvn = uint256(svnValue); + cpusvns[i] = cpusvn; + } + + // iterate to the next svn object in the sequence + svnParentPtr = der.nextSiblingOf(svnParentPtr); + } + success = true; + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol new file mode 100644 index 00000000000..6582976ba11 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol @@ -0,0 +1,335 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +import {BytesUtils} from "../../utils/BytesUtils.sol"; +import {V3Struct} from "./V3Struct.sol"; +// import {PEMCertChainLib} from "../PEMCertChainLib.sol"; + +// import "hardhat/console.sol"; + +library V3Parser { + using BytesUtils for bytes; + + uint256 constant MINIMUM_QUOTE_LENGTH = 1020; + bytes2 constant SUPPORTED_QUOTE_VERSION = 0x0300; + bytes2 constant SUPPORTED_ATTESTATION_KEY_TYPE = 0x0200; + // SGX only + bytes4 constant SUPPORTED_TEE_TYPE = 0; + bytes16 constant VALID_QE_VENDOR_ID = 0x939a7233f79c4ca9940a0db3957f0607; + + // todo! import HEADER & FOOTER from PEMCertChainLib + string constant HEADER = "-----BEGIN CERTIFICATE-----"; + string constant FOOTER = "-----END CERTIFICATE-----"; + uint256 constant HEADER_LENGTH = 27; + uint256 constant FOOTER_LENGTH = 25; + + function parseInput( + bytes memory quote + ) + internal + pure + returns ( + bool success, + V3Struct.Header memory header, + V3Struct.EnclaveReport memory localEnclaveReport, + bytes memory signedQuoteData, // concatenation of header and local enclave report bytes + V3Struct.ECDSAQuoteV3AuthData memory authDataV3 + ) + { + if (quote.length <= MINIMUM_QUOTE_LENGTH) { + return ( + false, + header, + localEnclaveReport, + signedQuoteData, + authDataV3 + ); + } + + uint256 localAuthDataSize = littleEndianDecode(quote.substring(432, 4)); + if (quote.length - 436 != localAuthDataSize) { + return ( + false, + header, + localEnclaveReport, + signedQuoteData, + authDataV3 + ); + } + + bytes memory rawHeader = quote.substring(0, 48); + bool headerVerifiedSuccessfully; + (headerVerifiedSuccessfully, header) = parseAndVerifyHeader(rawHeader); + if (!headerVerifiedSuccessfully) { + return ( + false, + header, + localEnclaveReport, + signedQuoteData, + authDataV3 + ); + } + + bool authDataVerifiedSuccessfully; + ( + authDataVerifiedSuccessfully, + authDataV3 + ) = parseAuthDataAndVerifyCertType( + quote.substring(436, localAuthDataSize) + ); + if (!authDataVerifiedSuccessfully) { + return ( + false, + header, + localEnclaveReport, + signedQuoteData, + authDataV3 + ); + } + + bytes memory rawLocalEnclaveReport = quote.substring(48, 384); + localEnclaveReport = parseEnclaveReport(rawLocalEnclaveReport); + signedQuoteData = abi.encodePacked(rawHeader, rawLocalEnclaveReport); + + success = true; + } + + function validateParsedInput( + V3Struct.ParsedV3QuoteStruct calldata v3Quote + ) + internal + pure + returns ( + bool success, + V3Struct.Header memory header, + V3Struct.EnclaveReport memory localEnclaveReport, + bytes memory signedQuoteData, // concatenation of header and local enclave report bytes + V3Struct.ParsedECDSAQuoteV3AuthData memory authDataV3 + ) + { + success = true; + localEnclaveReport = v3Quote.localEnclaveReport; + V3Struct.EnclaveReport memory pckSignedQeReport = v3Quote + .v3AuthData + .pckSignedQeReport; + + require( + localEnclaveReport.reserved3.length == 96 && + localEnclaveReport.reserved4.length == 60 && + localEnclaveReport.reportData.length == 64, + "local QE report has wrong length" + ); + require( + pckSignedQeReport.reserved3.length == 96 && + pckSignedQeReport.reserved4.length == 60 && + pckSignedQeReport.reportData.length == 64, + "QE report has wrong length" + ); + require( + v3Quote.v3AuthData.certification.certType == 5, + "certType must be 5: Concatenated PCK Cert Chain (PEM formatted)" + ); + require( + v3Quote.v3AuthData.certification.decodedCertDataArray.length == 3, + "3 certs in chain" + ); + require( + v3Quote.v3AuthData.ecdsa256BitSignature.length == 64 && + v3Quote.v3AuthData.ecdsaAttestationKey.length == 64 && + v3Quote.v3AuthData.qeReportSignature.length == 64, + "Invalid ECDSA signature format" + ); + require( + v3Quote.v3AuthData.qeAuthData.parsedDataSize == + v3Quote.v3AuthData.qeAuthData.data.length, + "Invalid QEAuthData size" + ); + + // todo! + // v3Quote.v3AuthData.certification.certDataSize == + // len(join((BEGIN_CERT, base64.encode(certArray[i]), END_CERT) for i in 0..3)) + // This check need b64 encoding, skip it now. + // require( + // base64.encode(v3Quote.v3AuthData.certification.decodedCertDataArray[0]).length + + // base64.encode(v3Quote + // .v3AuthData + // .certification + // .decodedCertDataArray[1]) + // .length + + // base64.encode(v3Quote + // .v3AuthData + // .certification + // .decodedCertDataArray[2]) + // .length + + // 3 * + // (HEADER_LENGTH + FOOTER_LENGTH) == + // v3Quote.v3AuthData.certification.certDataSize, + // "Invalid certData size" + // ); + + uint32 totalQuoteSize = 48 + // header + 384 + // local QE report + 64 + // ecdsa256BitSignature + 64 + // ecdsaAttestationKey + 384 + // QE report + 64 + // qeReportSignature + v3Quote.v3AuthData.qeAuthData.parsedDataSize + + v3Quote.v3AuthData.certification.certDataSize; + require(totalQuoteSize >= MINIMUM_QUOTE_LENGTH, "Invalid quote size"); + + header = v3Quote.header; + bytes memory headerBytes = abi.encodePacked( + header.version, + header.attestationKeyType, + header.teeType, + header.qeSvn, + header.pceSvn, + header.qeVendorId, + header.userData + ); + + signedQuoteData = abi.encodePacked( + headerBytes, + V3Parser.packQEReport(localEnclaveReport) + ); + authDataV3 = v3Quote.v3AuthData; + } + + function parseEnclaveReport( + bytes memory rawEnclaveReport + ) internal pure returns (V3Struct.EnclaveReport memory enclaveReport) { + enclaveReport.cpuSvn = bytes16(rawEnclaveReport.substring(0, 16)); + enclaveReport.miscSelect = bytes4(rawEnclaveReport.substring(16, 4)); + enclaveReport.reserved1 = bytes28(rawEnclaveReport.substring(20, 28)); + enclaveReport.attributes = bytes16(rawEnclaveReport.substring(48, 16)); + enclaveReport.mrEnclave = bytes32(rawEnclaveReport.substring(64, 32)); + enclaveReport.reserved2 = bytes32(rawEnclaveReport.substring(96, 32)); + enclaveReport.mrSigner = bytes32(rawEnclaveReport.substring(128, 32)); + enclaveReport.reserved3 = rawEnclaveReport.substring(160, 96); + enclaveReport.isvProdId = uint16( + littleEndianDecode(rawEnclaveReport.substring(256, 2)) + ); + enclaveReport.isvSvn = uint16( + littleEndianDecode(rawEnclaveReport.substring(258, 2)) + ); + enclaveReport.reserved4 = rawEnclaveReport.substring(260, 60); + enclaveReport.reportData = rawEnclaveReport.substring(320, 64); + } + + function littleEndianDecode( + bytes memory encoded + ) private pure returns (uint256 decoded) { + for (uint256 i = 0; i < encoded.length; i++) { + uint256 digits = uint256(uint8(bytes1(encoded[i]))); + uint256 upperDigit = digits / 16; + uint256 lowerDigit = digits % 16; + + uint256 acc = lowerDigit * (16 ** (2 * i)); + acc += upperDigit * (16 ** ((2 * i) + 1)); + + decoded += acc; + } + } + + function parseAndVerifyHeader( + bytes memory rawHeader + ) private pure returns (bool success, V3Struct.Header memory header) { + bytes2 version = bytes2(rawHeader.substring(0, 2)); + if (version != SUPPORTED_QUOTE_VERSION) { + return (false, header); + } + + bytes2 attestationKeyType = bytes2(rawHeader.substring(2, 2)); + if (attestationKeyType != SUPPORTED_ATTESTATION_KEY_TYPE) { + return (false, header); + } + + bytes4 teeType = bytes4(rawHeader.substring(4, 4)); + if (teeType != SUPPORTED_TEE_TYPE) { + return (false, header); + } + + bytes16 qeVendorId = bytes16(rawHeader.substring(12, 16)); + if (qeVendorId != VALID_QE_VENDOR_ID) { + return (false, header); + } + + header = V3Struct.Header({ + version: version, + attestationKeyType: attestationKeyType, + teeType: teeType, + qeSvn: bytes2(rawHeader.substring(8, 2)), + pceSvn: bytes2(rawHeader.substring(10, 2)), + qeVendorId: qeVendorId, + userData: bytes20(rawHeader.substring(28, 20)) + }); + + success = true; + } + + function parseAuthDataAndVerifyCertType( + bytes memory rawAuthData + ) + private + pure + returns (bool success, V3Struct.ECDSAQuoteV3AuthData memory authDataV3) + { + V3Struct.QEAuthData memory qeAuthData; + qeAuthData.parsedDataSize = littleEndianDecode( + rawAuthData.substring(576, 2) + ); + qeAuthData.data = rawAuthData.substring(578, qeAuthData.parsedDataSize); + + uint256 offset = 578 + qeAuthData.parsedDataSize; + V3Struct.CertificationData memory cert; + cert.certType = littleEndianDecode(rawAuthData.substring(offset, 2)); + if (cert.certType < 1 || cert.certType > 5) { + return (false, authDataV3); + } + offset += 2; + cert.certDataSize = littleEndianDecode( + rawAuthData.substring(offset, 4) + ); + offset += 4; + cert.certData = rawAuthData.substring(offset, cert.certDataSize); + + authDataV3.ecdsa256BitSignature = rawAuthData.substring(0, 64); + authDataV3.ecdsaAttestationKey = rawAuthData.substring(64, 64); + authDataV3.rawQeReport = rawAuthData.substring(128, 384); + // console.logBytes(authDataV3.rawQeReport); + authDataV3.qeReportSignature = rawAuthData.substring(512, 64); + authDataV3.qeAuthData = qeAuthData; + authDataV3.certification = cert; + + success = true; + } + + /// enclaveReport to bytes for hash calculation. + /// the only difference between enclaveReport and packedQEReport is the + /// order of isvProdId and isvSvn. enclaveReport is in little endian, while + /// in bytes should be in big endian according to Intel spec. + /// @param enclaveReport enclave report + /// @return packedQEReport enclave report in bytes + function packQEReport( + V3Struct.EnclaveReport memory enclaveReport + ) internal pure returns (bytes memory packedQEReport) { + uint16 isvProdIdPackBE = (enclaveReport.isvProdId >> 8) | + (enclaveReport.isvProdId << 8); + uint16 isvSvnPackBE = (enclaveReport.isvSvn >> 8) | + (enclaveReport.isvSvn << 8); + packedQEReport = abi.encodePacked( + enclaveReport.cpuSvn, + enclaveReport.miscSelect, + enclaveReport.reserved1, + enclaveReport.attributes, + enclaveReport.mrEnclave, + enclaveReport.reserved2, + enclaveReport.mrSigner, + enclaveReport.reserved3, + isvProdIdPackBE, + isvSvnPackBE, + enclaveReport.reserved4, + enclaveReport.reportData + ); + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol new file mode 100644 index 00000000000..2e9767833ea --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol @@ -0,0 +1,79 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +library V3Struct { + struct Header { + bytes2 version; + bytes2 attestationKeyType; + bytes4 teeType; + bytes2 qeSvn; + bytes2 pceSvn; + bytes16 qeVendorId; + bytes20 userData; + } + + struct EnclaveReport { + bytes16 cpuSvn; + bytes4 miscSelect; + bytes28 reserved1; + bytes16 attributes; + bytes32 mrEnclave; + bytes32 reserved2; + bytes32 mrSigner; + bytes reserved3; // 96 bytes + uint16 isvProdId; + uint16 isvSvn; + bytes reserved4; // 60 bytes + bytes reportData; // 64 bytes - For QEReports, this contains the hash of the concatenation of attestation key and QEAuthData + } + + struct QEAuthData { + // avoid uint256 -> uint16 conversion to save gas + uint256 parsedDataSize; + bytes data; + } + + struct ParsedQEAuthData { + uint16 parsedDataSize; + bytes data; // todo! data.length = parsedDataSize + } + + struct CertificationData { + // avoid uint256 -> uint16 conversion to save gas + uint256 certType; + // avoid uint256 -> uint32 conversion to save gas + uint256 certDataSize; + bytes certData; + } + + struct ParsedCertificationData { + uint16 certType; + // avoid uint256 -> uint32 conversion to save gas + uint32 certDataSize; // todo! certDataSize = len(join((BEGIN_CERT, certArray[i], END_CERT) for i in 0..3)) + bytes[3] decodedCertDataArray; // base64 decoded cert bytes array + } + + struct ECDSAQuoteV3AuthData { + bytes ecdsa256BitSignature; // 64 bytes + bytes ecdsaAttestationKey; // 64 bytes + bytes rawQeReport; // 384 bytes + bytes qeReportSignature; // 64 bytes + QEAuthData qeAuthData; + CertificationData certification; + } + + struct ParsedECDSAQuoteV3AuthData { + bytes ecdsa256BitSignature; // 64 bytes + bytes ecdsaAttestationKey; // 64 bytes + EnclaveReport pckSignedQeReport; // 384 bytes + bytes qeReportSignature; // 64 bytes + ParsedQEAuthData qeAuthData; + ParsedCertificationData certification; + } + + struct ParsedV3QuoteStruct { + Header header; + EnclaveReport localEnclaveReport; + ParsedECDSAQuoteV3AuthData v3AuthData; + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol new file mode 100644 index 00000000000..bb79029a2d5 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol @@ -0,0 +1,27 @@ +//SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +library TCBInfoStruct { + struct TCBInfo { + string pceid; + string fmspc; + TCBLevelObj[] tcbLevels; + } + + struct TCBLevelObj { + uint256 pcesvn; + uint8[] sgxTcbCompSvnArr; + TCBStatus status; + } + + enum TCBStatus { + OK, + TCB_SW_HARDENING_NEEDED, + TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED, + TCB_CONFIGURATION_NEEDED, + TCB_OUT_OF_DATE, + TCB_OUT_OF_DATE_CONFIGURATION_NEEDED, + TCB_REVOKED, + TCB_UNRECOGNIZED + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol new file mode 100644 index 00000000000..5b0d9531ce0 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol @@ -0,0 +1,43 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +interface IPEMCertChainLib { + struct ECSha256Certificate { + uint256 notBefore; + uint256 notAfter; + bytes serialNumber; + bytes tbsCertificate; + bytes pubKey; + bytes signature; + bool isPck; + PCKCertificateField pck; + } + + struct PCKCertificateField { + string commonName; + string issuerName; + PCKTCBInfo sgxExtension; + } + + struct PCKTCBInfo { + string pceid; + string fmspc; + uint256 pcesvn; + uint256[] sgxTcbCompSvnArr; + } + + enum CRL { + PCK, + ROOT + } + + function splitCertificateChain(bytes memory pemChain, uint256 size) + external + pure + returns (bool success, bytes[] memory certs); + + function decodeCert(bytes memory der, bool isPckCert) + external + pure + returns (bool success, ECSha256Certificate memory cert); +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol new file mode 100644 index 00000000000..30f6947f675 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol @@ -0,0 +1,202 @@ +// SPDX-License-Identifier: MIT +// Original source: https://github.com/JonahGroendal/asn1-decode +pragma solidity ^0.8.0; + +// Inspired by PufferFinance/rave - Apache-2.0 license +// https://github.com/JonahGroendal/asn1-decode/blob/5c2d1469fc678513753786acb441e597969192ec/contracts/Asn1Decode.sol + +import "./BytesUtils.sol"; + +library NodePtr { + // Unpack first byte index + function ixs(uint256 self) internal pure returns (uint256) { + return uint80(self); + } + // Unpack first content byte index + + function ixf(uint256 self) internal pure returns (uint256) { + return uint80(self >> 80); + } + // Unpack last content byte index + + function ixl(uint256 self) internal pure returns (uint256) { + return uint80(self >> 160); + } + // Pack 3 uint80s into a uint256 + + function getPtr(uint256 _ixs, uint256 _ixf, uint256 _ixl) internal pure returns (uint256) { + _ixs |= _ixf << 80; + _ixs |= _ixl << 160; + return _ixs; + } +} + +library Asn1Decode { + using NodePtr for uint256; + using BytesUtils for bytes; + + /* + * @dev Get the root node. First step in traversing an ASN1 structure + * @param der The DER-encoded ASN1 structure + * @return A pointer to the outermost node + */ + function root(bytes memory der) internal pure returns (uint256) { + return readNodeLength(der, 0); + } + + /* + * @dev Get the root node of an ASN1 structure that's within a bit string value + * @param der The DER-encoded ASN1 structure + * @return A pointer to the outermost node + */ + function rootOfBitStringAt(bytes memory der, uint256 ptr) internal pure returns (uint256) { + require(der[ptr.ixs()] == 0x03, "Not type BIT STRING"); + return readNodeLength(der, ptr.ixf() + 1); + } + + /* + * @dev Get the root node of an ASN1 structure that's within an octet string value + * @param der The DER-encoded ASN1 structure + * @return A pointer to the outermost node + */ + function rootOfOctetStringAt(bytes memory der, uint256 ptr) internal pure returns (uint256) { + require(der[ptr.ixs()] == 0x04, "Not type OCTET STRING"); + return readNodeLength(der, ptr.ixf()); + } + + /* + * @dev Get the next sibling node + * @param der The DER-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return A pointer to the next sibling node + */ + function nextSiblingOf(bytes memory der, uint256 ptr) internal pure returns (uint256) { + return readNodeLength(der, ptr.ixl() + 1); + } + + /* + * @dev Get the first child node of the current node + * @param der The DER-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return A pointer to the first child node + */ + function firstChildOf(bytes memory der, uint256 ptr) internal pure returns (uint256) { + require(der[ptr.ixs()] & 0x20 == 0x20, "Not a constructed type"); + return readNodeLength(der, ptr.ixf()); + } + + /* + * @dev Use for looping through children of a node (either i or j). + * @param i Pointer to an ASN1 node + * @param j Pointer to another ASN1 node of the same ASN1 structure + * @return True iff j is child of i or i is child of j. + */ + function isChildOf(uint256 i, uint256 j) internal pure returns (bool) { + return (((i.ixf() <= j.ixs()) && (j.ixl() <= i.ixl())) || ((j.ixf() <= i.ixs()) && (i.ixl() <= j.ixl()))); + } + + /* + * @dev Extract value of node from DER-encoded structure + * @param der The der-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return Value bytes of node + */ + function bytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { + return der.substring(ptr.ixf(), ptr.ixl() + 1 - ptr.ixf()); + } + + /* + * @dev Extract entire node from DER-encoded structure + * @param der The DER-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return All bytes of node + */ + function allBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { + return der.substring(ptr.ixs(), ptr.ixl() + 1 - ptr.ixs()); + } + + /* + * @dev Extract value of node from DER-encoded structure + * @param der The DER-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return Value bytes of node as bytes32 + */ + function bytes32At(bytes memory der, uint256 ptr) internal pure returns (bytes32) { + return der.readBytesN(ptr.ixf(), ptr.ixl() + 1 - ptr.ixf()); + } + + /* + * @dev Extract value of node from DER-encoded structure + * @param der The der-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return Uint value of node + */ + function uintAt(bytes memory der, uint256 ptr) internal pure returns (uint256) { + require(der[ptr.ixs()] == 0x02, "Not type INTEGER"); + require(der[ptr.ixf()] & 0x80 == 0, "Not positive"); + uint256 len = ptr.ixl() + 1 - ptr.ixf(); + return uint256(der.readBytesN(ptr.ixf(), len) >> (32 - len) * 8); + } + + /* + * @dev Extract value of a positive integer node from DER-encoded structure + * @param der The DER-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return Value bytes of a positive integer node + */ + function uintBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { + require(der[ptr.ixs()] == 0x02, "Not type INTEGER"); + require(der[ptr.ixf()] & 0x80 == 0, "Not positive"); + uint256 valueLength = ptr.ixl() + 1 - ptr.ixf(); + if (der[ptr.ixf()] == 0) { + return der.substring(ptr.ixf() + 1, valueLength - 1); + } else { + return der.substring(ptr.ixf(), valueLength); + } + } + + function keccakOfBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes32) { + return der.keccak(ptr.ixf(), ptr.ixl() + 1 - ptr.ixf()); + } + + function keccakOfAllBytesAt(bytes memory der, uint256 ptr) internal pure returns (bytes32) { + return der.keccak(ptr.ixs(), ptr.ixl() + 1 - ptr.ixs()); + } + + /* + * @dev Extract value of bitstring node from DER-encoded structure + * @param der The DER-encoded ASN1 structure + * @param ptr Points to the indices of the current node + * @return Value of bitstring converted to bytes + */ + function bitstringAt(bytes memory der, uint256 ptr) internal pure returns (bytes memory) { + require(der[ptr.ixs()] == 0x03, "Not type BIT STRING"); + // Only 00 padded bitstr can be converted to bytestr! + require(der[ptr.ixf()] == 0x00); + uint256 valueLength = ptr.ixl() + 1 - ptr.ixf(); + return der.substring(ptr.ixf() + 1, valueLength - 1); + } + + function readNodeLength(bytes memory der, uint256 ix) private pure returns (uint256) { + uint256 length; + uint80 ixFirstContentByte; + uint80 ixLastContentByte; + if ((der[ix + 1] & 0x80) == 0) { + length = uint8(der[ix + 1]); + ixFirstContentByte = uint80(ix + 2); + ixLastContentByte = uint80(ixFirstContentByte + length - 1); + } else { + uint8 lengthbytesLength = uint8(der[ix + 1] & 0x7F); + if (lengthbytesLength == 1) { + length = der.readUint8(ix + 2); + } else if (lengthbytesLength == 2) { + length = der.readUint16(ix + 2); + } else { + length = uint256(der.readBytesN(ix + 2, lengthbytesLength) >> (32 - lengthbytesLength) * 8); + } + ixFirstContentByte = uint80(ix + 2 + lengthbytesLength); + ixLastContentByte = uint80(ixFirstContentByte + length - 1); + } + return NodePtr.getPtr(ix, ixFirstContentByte, ixLastContentByte); + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol new file mode 100644 index 00000000000..8d03feff88a --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol @@ -0,0 +1,341 @@ +// SPDX-License-Identifier: BSD 2-Clause License +pragma solidity ^0.8.0; + +// Inspired by ensdomains/dnssec-oracle - BSD-2-Clause license +// https://github.com/ensdomains/dnssec-oracle/blob/master/contracts/BytesUtils.sol + +library BytesUtils { + /* + * @dev Returns the keccak-256 hash of a byte range. + * @param self The byte string to hash. + * @param offset The position to start hashing at. + * @param len The number of bytes to hash. + * @return The hash of the byte range. + */ + function keccak(bytes memory self, uint256 offset, uint256 len) internal pure returns (bytes32 ret) { + require(offset + len <= self.length); + assembly { + ret := keccak256(add(add(self, 32), offset), len) + } + } + + /* + * @dev Returns a positive number if `other` comes lexicographically after + * `self`, a negative number if it comes before, or zero if the + * contents of the two bytes are equal. + * @param self The first bytes to compare. + * @param other The second bytes to compare. + * @return The result of the comparison. + */ + function compare(bytes memory self, bytes memory other) internal pure returns (int256) { + return compare(self, 0, self.length, other, 0, other.length); + } + + /* + * @dev Returns a positive number if `other` comes lexicographically after + * `self`, a negative number if it comes before, or zero if the + * contents of the two bytes are equal. Comparison is done per-rune, + * on unicode codepoints. + * @param self The first bytes to compare. + * @param offset The offset of self. + * @param len The length of self. + * @param other The second bytes to compare. + * @param otheroffset The offset of the other string. + * @param otherlen The length of the other string. + * @return The result of the comparison. + */ + function compare( + bytes memory self, + uint256 offset, + uint256 len, + bytes memory other, + uint256 otheroffset, + uint256 otherlen + ) internal pure returns (int256) { + uint256 shortest = len; + if (otherlen < len) { + shortest = otherlen; + } + + uint256 selfptr; + uint256 otherptr; + + assembly { + selfptr := add(self, add(offset, 32)) + otherptr := add(other, add(otheroffset, 32)) + } + for (uint256 idx = 0; idx < shortest; idx += 32) { + uint256 a; + uint256 b; + assembly { + a := mload(selfptr) + b := mload(otherptr) + } + if (a != b) { + // Mask out irrelevant bytes and check again + uint256 mask; + if (shortest > 32) { + mask = type(uint256).max; // aka 0xffffff.... + } else { + mask = ~(2 ** (8 * (32 - shortest + idx)) - 1); + } + uint256 diff = (a & mask) - (b & mask); + if (diff != 0) { + return int256(diff); + } + } + selfptr += 32; + otherptr += 32; + } + + return int256(len) - int256(otherlen); + } + + /* + * @dev Returns true if the two byte ranges are equal. + * @param self The first byte range to compare. + * @param offset The offset into the first byte range. + * @param other The second byte range to compare. + * @param otherOffset The offset into the second byte range. + * @param len The number of bytes to compare + * @return True if the byte ranges are equal, false otherwise. + */ + function equals(bytes memory self, uint256 offset, bytes memory other, uint256 otherOffset, uint256 len) + internal + pure + returns (bool) + { + return keccak(self, offset, len) == keccak(other, otherOffset, len); + } + + /* + * @dev Returns true if the two byte ranges are equal with offsets. + * @param self The first byte range to compare. + * @param offset The offset into the first byte range. + * @param other The second byte range to compare. + * @param otherOffset The offset into the second byte range. + * @return True if the byte ranges are equal, false otherwise. + */ + function equals(bytes memory self, uint256 offset, bytes memory other, uint256 otherOffset) + internal + pure + returns (bool) + { + return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset); + } + + /* + * @dev Compares a range of 'self' to all of 'other' and returns True iff + * they are equal. + * @param self The first byte range to compare. + * @param offset The offset into the first byte range. + * @param other The second byte range to compare. + * @return True if the byte ranges are equal, false otherwise. + */ + function equals(bytes memory self, uint256 offset, bytes memory other) internal pure returns (bool) { + return self.length >= offset + other.length && equals(self, offset, other, 0, other.length); + } + + /* + * @dev Returns true if the two byte ranges are equal. + * @param self The first byte range to compare. + * @param other The second byte range to compare. + * @return True if the byte ranges are equal, false otherwise. + */ + function equals(bytes memory self, bytes memory other) internal pure returns (bool) { + return self.length == other.length && equals(self, 0, other, 0, self.length); + } + + /* + * @dev Returns the 8-bit number at the specified index of self. + * @param self The byte string. + * @param idx The index into the bytes + * @return The specified 8 bits of the string, interpreted as an integer. + */ + function readUint8(bytes memory self, uint256 idx) internal pure returns (uint8 ret) { + return uint8(self[idx]); + } + + /* + * @dev Returns the 16-bit number at the specified index of self. + * @param self The byte string. + * @param idx The index into the bytes + * @return The specified 16 bits of the string, interpreted as an integer. + */ + function readUint16(bytes memory self, uint256 idx) internal pure returns (uint16 ret) { + require(idx + 2 <= self.length); + assembly { + ret := and(mload(add(add(self, 2), idx)), 0xFFFF) + } + } + + /* + * @dev Returns the 32-bit number at the specified index of self. + * @param self The byte string. + * @param idx The index into the bytes + * @return The specified 32 bits of the string, interpreted as an integer. + */ + function readUint32(bytes memory self, uint256 idx) internal pure returns (uint32 ret) { + require(idx + 4 <= self.length); + assembly { + ret := and(mload(add(add(self, 4), idx)), 0xFFFFFFFF) + } + } + + /* + * @dev Returns the 32 byte value at the specified index of self. + * @param self The byte string. + * @param idx The index into the bytes + * @return The specified 32 bytes of the string. + */ + function readBytes32(bytes memory self, uint256 idx) internal pure returns (bytes32 ret) { + require(idx + 32 <= self.length); + assembly { + ret := mload(add(add(self, 32), idx)) + } + } + + /* + * @dev Returns the 32 byte value at the specified index of self. + * @param self The byte string. + * @param idx The index into the bytes + * @return The specified 32 bytes of the string. + */ + function readBytes20(bytes memory self, uint256 idx) internal pure returns (bytes20 ret) { + require(idx + 20 <= self.length); + assembly { + ret := + and(mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000) + } + } + + /* + * @dev Returns the n byte value at the specified index of self. + * @param self The byte string. + * @param idx The index into the bytes. + * @param len The number of bytes. + * @return The specified 32 bytes of the string. + */ + function readBytesN(bytes memory self, uint256 idx, uint256 len) internal pure returns (bytes32 ret) { + require(len <= 32); + require(idx + len <= self.length); + assembly { + let mask := not(sub(exp(256, sub(32, len)), 1)) + ret := and(mload(add(add(self, 32), idx)), mask) + } + } + + function memcpy(uint256 dest, uint256 src, uint256 len) private pure { + // Copy word-length chunks while possible + for (; len >= 32; len -= 32) { + assembly { + mstore(dest, mload(src)) + } + dest += 32; + src += 32; + } + + // Copy remaining bytes + uint256 mask; + if (len == 0) { + mask = type(uint256).max; // Set to maximum value of uint256 + } else { + mask = 256 ** (32 - len) - 1; + } + + assembly { + let srcpart := and(mload(src), not(mask)) + let destpart := and(mload(dest), mask) + mstore(dest, or(destpart, srcpart)) + } + } + + /* + * @dev Copies a substring into a new byte string. + * @param self The byte string to copy from. + * @param offset The offset to start copying at. + * @param len The number of bytes to copy. + */ + function substring(bytes memory self, uint256 offset, uint256 len) internal pure returns (bytes memory) { + require(offset + len <= self.length); + + bytes memory ret = new bytes(len); + uint256 dest; + uint256 src; + + assembly { + dest := add(ret, 32) + src := add(add(self, 32), offset) + } + memcpy(dest, src, len); + + return ret; + } + + // Maps characters from 0x30 to 0x7A to their base32 values. + // 0xFF represents invalid characters in that range. + bytes constant base32HexTable = + hex"00010203040506070809FFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1FFFFFFFFFFFFFFFFFFFFF0A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"; + + /** + * @dev Decodes unpadded base32 data of up to one word in length. + * @param self The data to decode. + * @param off Offset into the string to start at. + * @param len Number of characters to decode. + * @return The decoded data, left aligned. + */ + function base32HexDecodeWord(bytes memory self, uint256 off, uint256 len) internal pure returns (bytes32) { + require(len <= 52); + + uint256 ret = 0; + uint8 decoded; + for (uint256 i = 0; i < len; i++) { + bytes1 char = self[off + i]; + require(char >= 0x30 && char <= 0x7A); + decoded = uint8(base32HexTable[uint256(uint8(char)) - 0x30]); + require(decoded <= 0x20); + if (i == len - 1) { + break; + } + ret = (ret << 5) | decoded; + } + + uint256 bitlen = len * 5; + if (len % 8 == 0) { + // Multiple of 8 characters, no padding + ret = (ret << 5) | decoded; + } else if (len % 8 == 2) { + // Two extra characters - 1 byte + ret = (ret << 3) | (decoded >> 2); + bitlen -= 2; + } else if (len % 8 == 4) { + // Four extra characters - 2 bytes + ret = (ret << 1) | (decoded >> 4); + bitlen -= 4; + } else if (len % 8 == 5) { + // Five extra characters - 3 bytes + ret = (ret << 4) | (decoded >> 1); + bitlen -= 1; + } else if (len % 8 == 7) { + // Seven extra characters - 4 bytes + ret = (ret << 2) | (decoded >> 3); + bitlen -= 3; + } else { + revert(); + } + + return bytes32(ret << (256 - bitlen)); + } + + function compareBytes(bytes memory a, bytes memory b) internal pure returns (bool) { + if (a.length != b.length) { + return false; + } + for (uint256 i = 0; i < a.length; i++) { + if (a[i] != b[i]) { + return false; + } + } + return true; + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol new file mode 100644 index 00000000000..cafb4fa7b9d --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol @@ -0,0 +1,226 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity ^0.8.0; + +import "./SHA1.sol"; + +// Inspired by adria0/SolRsaVerify - GPL-3.0 license +// https://github.com/adria0/SolRsaVerify/blob/master/src/RsaVerify.sol + +/* + Copyright 2016, Adrià Massanet + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + Checked results with FIPS test vectors + https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss/186-2rsatestvectors.zip + file SigVer15_186-3.rsp + + */ + +library RsaVerify { + /** + * @dev Verifies a PKCSv1.5 SHA256 signature + * @param _sha256 is the sha256 of the data + * @param _s is the signature + * @param _e is the exponent + * @param _m is the modulus + * @return true if success, false otherwise + */ + function pkcs1Sha256(bytes32 _sha256, bytes memory _s, bytes memory _e, bytes memory _m) + internal + view + returns (bool) + { + uint8[17] memory sha256ExplicitNullParam = + [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00]; + + uint8[15] memory sha256ImplicitNullParam = + [0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01]; + + // decipher + + bytes memory input = bytes.concat(bytes32(_s.length), bytes32(_e.length), bytes32(_m.length), _s, _e, _m); + uint256 inputlen = input.length; + + uint256 decipherlen = _m.length; + bytes memory decipher = new bytes(decipherlen); + assembly { + pop(staticcall(sub(gas(), 2000), 5, add(input, 0x20), inputlen, add(decipher, 0x20), decipherlen)) + } + + // Check that is well encoded: + // + // 0x00 || 0x01 || PS || 0x00 || DigestInfo + // PS is padding filled with 0xff + // DigestInfo ::= SEQUENCE { + // digestAlgorithm AlgorithmIdentifier, + // [optional algorithm parameters] + // digest OCTET STRING + // } + + bool hasNullParam; + uint256 digestAlgoWithParamLen; + + if (uint8(decipher[decipherlen - 50]) == 0x31) { + hasNullParam = true; + digestAlgoWithParamLen = sha256ExplicitNullParam.length; + } else if (uint8(decipher[decipherlen - 48]) == 0x2f) { + hasNullParam = false; + digestAlgoWithParamLen = sha256ImplicitNullParam.length; + } else { + return false; + } + + uint256 paddingLen = decipherlen - 5 - digestAlgoWithParamLen - 32; + + if (decipher[0] != 0 || decipher[1] != 0x01) { + return false; + } + for (uint256 i = 2; i < 2 + paddingLen; i++) { + if (decipher[i] != 0xff) { + return false; + } + } + if (decipher[2 + paddingLen] != 0) { + return false; + } + + // check digest algorithm + + if (digestAlgoWithParamLen == sha256ExplicitNullParam.length) { + for (uint256 i = 0; i < digestAlgoWithParamLen; i++) { + if (decipher[3 + paddingLen + i] != bytes1(sha256ExplicitNullParam[i])) { + return false; + } + } + } else { + for (uint256 i = 0; i < digestAlgoWithParamLen; i++) { + if (decipher[3 + paddingLen + i] != bytes1(sha256ImplicitNullParam[i])) { + return false; + } + } + } + + // check digest + + if ( + decipher[3 + paddingLen + digestAlgoWithParamLen] != 0x04 + || decipher[4 + paddingLen + digestAlgoWithParamLen] != 0x20 + ) { + return false; + } + + for (uint256 i = 0; i < _sha256.length; i++) { + if (decipher[5 + paddingLen + digestAlgoWithParamLen + i] != _sha256[i]) { + return false; + } + } + + return true; + } + + /** + * @dev Verifies a PKCSv1.5 SHA256 signature + * @param _data to verify + * @param _s is the signature + * @param _e is the exponent + * @param _m is the modulus + * @return 0 if success, >0 otherwise + */ + function pkcs1Sha256Raw(bytes memory _data, bytes memory _s, bytes memory _e, bytes memory _m) + internal + view + returns (bool) + { + return pkcs1Sha256(sha256(_data), _s, _e, _m); + } + + /** + * @dev Verifies a PKCSv1.5 SHA1 signature + * @param _sha1 is the sha1 of the data + * @param _s is the signature + * @param _e is the exponent + * @param _m is the modulus + * @return true if success, false otherwise + */ + function pkcs1Sha1(bytes20 _sha1, bytes memory _s, bytes memory _e, bytes memory _m) internal view returns (bool) { + uint8[15] memory sha1Prefix = + [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14]; + + // decipher + bytes memory input = bytes.concat(bytes32(_s.length), bytes32(_e.length), bytes32(_m.length), _s, _e, _m); + uint256 inputlen = input.length; + + uint256 decipherlen = _m.length; + bytes memory decipher = new bytes(decipherlen); + assembly { + pop(staticcall(sub(gas(), 2000), 5, add(input, 0x20), inputlen, add(decipher, 0x20), decipherlen)) + } + + // Check that is well encoded: + // 0x00 || 0x01 || PS || 0x00 || DigestInfo + // PS is padding filled with 0xff + // DigestInfo ::= SEQUENCE { + // digestAlgorithm AlgorithmIdentifier, + // digest OCTET STRING + // } + + uint256 paddingLen = decipherlen - 3 - sha1Prefix.length - 20; + + if (decipher[0] != 0 || decipher[1] != 0x01) { + return false; + } + for (uint256 i = 2; i < 2 + paddingLen; i++) { + if (decipher[i] != 0xff) { + return false; + } + } + if (decipher[2 + paddingLen] != 0) { + return false; + } + + // check digest algorithm + for (uint256 i = 0; i < sha1Prefix.length; i++) { + if (decipher[3 + paddingLen + i] != bytes1(sha1Prefix[i])) { + return false; + } + } + + // check digest + for (uint256 i = 0; i < _sha1.length; i++) { + if (decipher[3 + paddingLen + sha1Prefix.length + i] != _sha1[i]) { + return false; + } + } + + return true; + } + + /** + * @dev Verifies a PKCSv1.5 SHA1 signature + * @param _data to verify + * @param _s is the signature + * @param _e is the exponent + * @param _m is the modulus + * @return 0 if success, >0 otherwise + */ + function pkcs1Sha1Raw(bytes memory _data, bytes memory _s, bytes memory _e, bytes memory _m) + internal + view + returns (bool) + { + return pkcs1Sha1(SHA1.sha1(_data), _s, _e, _m); + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol new file mode 100644 index 00000000000..cac01764a64 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: BSD 2-Clause License + +pragma solidity ^0.8.0; + +// Inspired by ensdomains/solsha1 - BSD 2-Clause License +// https://github.com/ensdomains/solsha1/blob/master/contracts/SHA1.sol + +library SHA1 { + event Debug(bytes32 x); + + function sha1(bytes memory data) internal pure returns (bytes20 ret) { + assembly { + // Get a safe scratch location + let scratch := mload(0x40) + + // Get the data length, and point data at the first byte + let len := mload(data) + data := add(data, 32) + + // Find the length after padding + let totallen := add(and(add(len, 1), 0xFFFFFFFFFFFFFFC0), 64) + switch lt(sub(totallen, len), 9) + case 1 { totallen := add(totallen, 64) } + + let h := 0x6745230100EFCDAB890098BADCFE001032547600C3D2E1F0 + + function readword(ptr, off, count) -> result { + result := 0 + if lt(off, count) { + result := mload(add(ptr, off)) + count := sub(count, off) + if lt(count, 32) { + let mask := not(sub(exp(256, sub(32, count)), 1)) + result := and(result, mask) + } + } + } + + for { let i := 0 } lt(i, totallen) { i := add(i, 64) } { + mstore(scratch, readword(data, i, len)) + mstore(add(scratch, 32), readword(data, add(i, 32), len)) + + // If we loaded the last byte, store the terminator byte + switch lt(sub(len, i), 64) + case 1 { mstore8(add(scratch, sub(len, i)), 0x80) } + + // If this is the last block, store the length + switch eq(i, sub(totallen, 64)) + case 1 { mstore(add(scratch, 32), or(mload(add(scratch, 32)), mul(len, 8))) } + + // Expand the 16 32-bit words into 80 + for { let j := 64 } lt(j, 128) { j := add(j, 12) } { + let temp := + xor( + xor(mload(add(scratch, sub(j, 12))), mload(add(scratch, sub(j, 32)))), + xor(mload(add(scratch, sub(j, 56))), mload(add(scratch, sub(j, 64)))) + ) + temp := + or( + and(mul(temp, 2), 0xFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFE), + and(div(temp, 0x80000000), 0x0000000100000001000000010000000100000001000000010000000100000001) + ) + mstore(add(scratch, j), temp) + } + for { let j := 128 } lt(j, 320) { j := add(j, 24) } { + let temp := + xor( + xor(mload(add(scratch, sub(j, 24))), mload(add(scratch, sub(j, 64)))), + xor(mload(add(scratch, sub(j, 112))), mload(add(scratch, sub(j, 128)))) + ) + temp := + or( + and(mul(temp, 4), 0xFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFC), + and(div(temp, 0x40000000), 0x0000000300000003000000030000000300000003000000030000000300000003) + ) + mstore(add(scratch, j), temp) + } + + let x := h + let f := 0 + let k := 0 + for { let j := 0 } lt(j, 80) { j := add(j, 1) } { + switch div(j, 20) + case 0 { + // f = d xor (b and (c xor d)) + f := xor(div(x, 0x100000000000000000000), div(x, 0x10000000000)) + f := and(div(x, 0x1000000000000000000000000000000), f) + f := xor(div(x, 0x10000000000), f) + k := 0x5A827999 + } + case 1 { + // f = b xor c xor d + f := xor(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)) + f := xor(div(x, 0x10000000000), f) + k := 0x6ED9EBA1 + } + case 2 { + // f = (b and c) or (d and (b or c)) + f := or(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)) + f := and(div(x, 0x10000000000), f) + f := or(and(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)), f) + k := 0x8F1BBCDC + } + case 3 { + // f = b xor c xor d + f := xor(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)) + f := xor(div(x, 0x10000000000), f) + k := 0xCA62C1D6 + } + // temp = (a leftrotate 5) + f + e + k + w[i] + let temp := and(div(x, 0x80000000000000000000000000000000000000000000000), 0x1F) + temp := or(and(div(x, 0x800000000000000000000000000000000000000), 0xFFFFFFE0), temp) + temp := add(f, temp) + temp := add(and(x, 0xFFFFFFFF), temp) + temp := add(k, temp) + temp := + add( + div(mload(add(scratch, mul(j, 4))), 0x100000000000000000000000000000000000000000000000000000000), + temp + ) + x := or(div(x, 0x10000000000), mul(temp, 0x10000000000000000000000000000000000000000)) + x := + or( + and(x, 0xFFFFFFFF00FFFFFFFF000000000000FFFFFFFF00FFFFFFFF), + mul( + or( + and(div(x, 0x4000000000000), 0xC0000000), + and(div(x, 0x400000000000000000000), 0x3FFFFFFF) + ), + 0x100000000000000000000 + ) + ) + } + + h := and(add(h, x), 0xFFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFF00FFFFFFFF) + } + ret := + mul( + or( + or( + or( + or( + and(div(h, 0x100000000), 0xFFFFFFFF00000000000000000000000000000000), + and(div(h, 0x1000000), 0xFFFFFFFF000000000000000000000000) + ), + and(div(h, 0x10000), 0xFFFFFFFF0000000000000000) + ), + and(div(h, 0x100), 0xFFFFFFFF00000000) + ), + and(h, 0xFFFFFFFF) + ), + 0x1000000000000000000000000 + ) + } + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol new file mode 100644 index 00000000000..11814ae18bf --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity ^0.8.0; + +import "../interfaces/ISigVerifyLib.sol"; +import "./RsaVerify.sol"; +import "./BytesUtils.sol"; + +// Library for verifying signatures +// Supports verifying signatures with the following algorithms: +// - RS256 +// - ES256 +// - RS1 + +contract SigVerifyLib is ISigVerifyLib { + using BytesUtils for bytes; + address private ES256VERIFIER; + + constructor(address es256Verifier) { + ES256VERIFIER = es256Verifier; + } + + function verifyAttStmtSignature(bytes memory tbs, bytes memory signature, PublicKey memory publicKey, Algorithm alg) + public + view + returns (bool) + { + if (alg == Algorithm.RS256) { + if (publicKey.keyType != KeyType.RSA) { + return false; + } + return verifyRS256Signature(tbs, signature, publicKey.pubKey); + } else if (alg == Algorithm.ES256) { + if (publicKey.keyType != KeyType.ECDSA) { + return false; + } + return verifyES256Signature(tbs, signature, publicKey.pubKey); + } else if (alg == Algorithm.RS1) { + if (publicKey.keyType != KeyType.RSA) { + return false; + } + return verifyRS1Signature(tbs, signature, publicKey.pubKey); + } else { + revert("Unsupported algorithm"); + } + } + + function verifyCertificateSignature( + bytes memory tbs, + bytes memory signature, + PublicKey memory publicKey, + CertSigAlgorithm alg + ) public view returns (bool) { + if (alg == CertSigAlgorithm.Sha256WithRSAEncryption) { + if (publicKey.keyType != KeyType.RSA) { + return false; + } + return verifyRS256Signature(tbs, signature, publicKey.pubKey); + } else if (alg == CertSigAlgorithm.Sha1WithRSAEncryption) { + if (publicKey.keyType != KeyType.RSA) { + return false; + } + return verifyRS1Signature(tbs, signature, publicKey.pubKey); + } else { + revert("Unsupported algorithm"); + } + } + + function verifyRS256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + public + view + returns (bool sigValid) + { + // Parse public key + bytes memory exponent = publicKey.substring(0, 3); + bytes memory modulus = publicKey.substring(3, publicKey.length - 3); + + // Verify signature + sigValid = RsaVerify.pkcs1Sha256Raw(tbs, signature, exponent, modulus); + } + + function verifyRS1Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + public + view + returns (bool sigValid) + { + // Parse public key + bytes memory exponent = publicKey.substring(0, 3); + bytes memory modulus = publicKey.substring(3, publicKey.length - 3); + + // Verify signature + sigValid = RsaVerify.pkcs1Sha1Raw(tbs, signature, exponent, modulus); + } + + function verifyES256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + public + view + returns (bool sigValid) + { + // Parse signature + if (signature.length != 64) { + return false; + } + uint256 r = uint256(bytes32(signature.substring(0, 32))); + uint256 s = uint256(bytes32(signature.substring(32, 32))); + // Parse public key + if (publicKey.length != 64) { + return false; + } + uint256 gx = uint256(bytes32(publicKey.substring(0, 32))); + uint256 gy = uint256(bytes32(publicKey.substring(32, 32))); + + // Verify signature + bytes memory args = abi.encode(sha256(tbs), r, s, gx, gy); + (bool success, bytes memory ret) = ES256VERIFIER.staticcall(args); + assert(success); // never reverts, always returns 0 or 1 + + return abi.decode(ret, (uint256)) == 1; + } +} diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol new file mode 100644 index 00000000000..26f53ee4239 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT + +pragma solidity ^0.8.0; + +library X509DateUtils { + function toTimestamp(bytes memory x509Time) internal pure returns (uint256) { + uint16 yrs; + uint8 mnths; + uint8 dys; + uint8 hrs; + uint8 mins; + uint8 secs; + uint8 offset; + + if (x509Time.length == 13) { + if (uint8(x509Time[0]) - 48 < 5) yrs += 2000; + else yrs += 1900; + } else { + yrs += (uint8(x509Time[0]) - 48) * 1000 + (uint8(x509Time[1]) - 48) * 100; + offset = 2; + } + yrs += (uint8(x509Time[offset + 0]) - 48) * 10 + uint8(x509Time[offset + 1]) - 48; + mnths = (uint8(x509Time[offset + 2]) - 48) * 10 + uint8(x509Time[offset + 3]) - 48; + dys += (uint8(x509Time[offset + 4]) - 48) * 10 + uint8(x509Time[offset + 5]) - 48; + hrs += (uint8(x509Time[offset + 6]) - 48) * 10 + uint8(x509Time[offset + 7]) - 48; + mins += (uint8(x509Time[offset + 8]) - 48) * 10 + uint8(x509Time[offset + 9]) - 48; + secs += (uint8(x509Time[offset + 10]) - 48) * 10 + uint8(x509Time[offset + 11]) - 48; + + return toUnixTimestamp(yrs, mnths, dys, hrs, mins, secs); + } + + function toUnixTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) + internal + pure + returns (uint256) + { + uint256 timestamp = 0; + + for (uint16 i = 1970; i < year; i++) { + if (isLeapYear(i)) { + timestamp += 31622400; // Leap year in seconds + } else { + timestamp += 31536000; // Normal year in seconds + } + } + + uint8[12] memory monthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; + if (isLeapYear(year)) monthDays[1] = 29; + + for (uint8 i = 1; i < month; i++) { + timestamp += uint256(monthDays[i - 1]) * 86400; // Days in seconds + } + + timestamp += uint256(day - 1) * 86400; // Days in seconds + timestamp += uint256(hour) * 3600; // Hours in seconds + timestamp += uint256(minute) * 60; // Minutes in seconds + timestamp += second; + + return timestamp; + } + + function isLeapYear(uint16 year) internal pure returns (bool) { + if (year % 4 != 0) return false; + if (year % 100 != 0) return true; + if (year % 400 != 0) return false; + return true; + } +} diff --git a/packages/protocol/lib/solady b/packages/protocol/lib/solady new file mode 160000 index 00000000000..dcdddfd2b1b --- /dev/null +++ b/packages/protocol/lib/solady @@ -0,0 +1 @@ +Subproject commit dcdddfd2b1b26353e96dbd75ec81db88f352384c diff --git a/packages/protocol/packages/protocol/lib/p256-verifier b/packages/protocol/packages/protocol/lib/p256-verifier new file mode 160000 index 00000000000..29475ae300e --- /dev/null +++ b/packages/protocol/packages/protocol/lib/p256-verifier @@ -0,0 +1 @@ +Subproject commit 29475ae300ec95d98d5c7cc34c094846f0aa2dcd diff --git a/packages/protocol/packages/protocol/lib/solady b/packages/protocol/packages/protocol/lib/solady new file mode 160000 index 00000000000..fb11b3e9ea6 --- /dev/null +++ b/packages/protocol/packages/protocol/lib/solady @@ -0,0 +1 @@ +Subproject commit fb11b3e9ea6c1aafdbd0a1515ff440509d60bff9 From 476f10772d5c1c18528a634a1c25284998858ad8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 15:18:05 +0530 Subject: [PATCH 02/44] remove submodules --- .gitmodules | 8 +------- packages/protocol/packages/protocol/lib/p256-verifier | 1 - packages/protocol/packages/protocol/lib/solady | 1 - 3 files changed, 1 insertion(+), 9 deletions(-) delete mode 160000 packages/protocol/packages/protocol/lib/p256-verifier delete mode 160000 packages/protocol/packages/protocol/lib/solady diff --git a/.gitmodules b/.gitmodules index ab5962bbf53..18d9ac79dfb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,10 +13,4 @@ [submodule "packages/protocol/lib/forge-std"] path = packages/protocol/lib/forge-std url = https://github.com/foundry-rs/forge-std - branch = chore/v1.5.1 -[submodule "packages/protocol/lib/solady"] - path = packages/protocol/lib/solady - url = https://github.com/Vectorized/solady -[submodule "packages/protocol/lib/p256-verifier"] - path = packages/protocol/lib/p256-verifier - url = https://github.com/daimo-eth/p256-verifier + branch = chore/v1.5.1 \ No newline at end of file diff --git a/packages/protocol/packages/protocol/lib/p256-verifier b/packages/protocol/packages/protocol/lib/p256-verifier deleted file mode 160000 index 29475ae300e..00000000000 --- a/packages/protocol/packages/protocol/lib/p256-verifier +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 29475ae300ec95d98d5c7cc34c094846f0aa2dcd diff --git a/packages/protocol/packages/protocol/lib/solady b/packages/protocol/packages/protocol/lib/solady deleted file mode 160000 index fb11b3e9ea6..00000000000 --- a/packages/protocol/packages/protocol/lib/solady +++ /dev/null @@ -1 +0,0 @@ -Subproject commit fb11b3e9ea6c1aafdbd0a1515ff440509d60bff9 From 9a7bf55e6e6b3c35a89e5ed3bde778e6792ca897 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 15:27:37 +0530 Subject: [PATCH 03/44] delete subm --- packages/protocol/lib/solady | 1 - 1 file changed, 1 deletion(-) delete mode 160000 packages/protocol/lib/solady diff --git a/packages/protocol/lib/solady b/packages/protocol/lib/solady deleted file mode 160000 index dcdddfd2b1b..00000000000 --- a/packages/protocol/lib/solady +++ /dev/null @@ -1 +0,0 @@ -Subproject commit dcdddfd2b1b26353e96dbd75ec81db88f352384c From 9d9dc771466e589154cf43ce95d4cf617e671c31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 15:47:39 +0530 Subject: [PATCH 04/44] add test files --- .gitmodules | 8 +- .../onchainRA/AutomataDcapV3Attestation.sol | 374 ++++++++---------- .../onchainRA/lib/PEMCertChainLib.sol | 56 ++- packages/protocol/lib/p256-verifier | 1 + packages/protocol/lib/solady | 1 + .../AutomataDcapV3AttestationTest.t.sol | 154 ++++++++ .../test/onchainRA/assets/complex.json | 25 ++ .../test/onchainRA/utils/DcapTestUtils.t.sol | 262 ++++++++++++ .../test/onchainRA/utils/V3JsonUtils.t.sol | 143 +++++++ 9 files changed, 792 insertions(+), 232 deletions(-) create mode 160000 packages/protocol/lib/p256-verifier create mode 160000 packages/protocol/lib/solady create mode 100644 packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol create mode 100644 packages/protocol/test/onchainRA/assets/complex.json create mode 100644 packages/protocol/test/onchainRA/utils/DcapTestUtils.t.sol create mode 100644 packages/protocol/test/onchainRA/utils/V3JsonUtils.t.sol diff --git a/.gitmodules b/.gitmodules index 18d9ac79dfb..763cb19c183 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,4 +13,10 @@ [submodule "packages/protocol/lib/forge-std"] path = packages/protocol/lib/forge-std url = https://github.com/foundry-rs/forge-std - branch = chore/v1.5.1 \ No newline at end of file + branch = chore/v1.5.1 +[submodule "packages/protocol/lib/p256-verifier"] + path = packages/protocol/lib/p256-verifier + url = https://github.com/daimo-eth/p256-verifier +[submodule "packages/protocol/lib/solady"] + path = packages/protocol/lib/solady + url = https://github.com/Vectorized/solady diff --git a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol index b05eeb52a3e..9890562aa2e 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol @@ -1,21 +1,21 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {V3Struct} from "./lib/QuoteV3Auth/V3Struct.sol"; -import {V3Parser} from "./lib/QuoteV3Auth/V3Parser.sol"; -import {IPEMCertChainLib} from "./lib/interfaces/IPEMCertChainLib.sol"; -import {PEMCertChainLib} from "./lib/PEMCertChainLib.sol"; -import {TCBInfoStruct} from "./lib/TCBInfoStruct.sol"; -import {EnclaveIdStruct} from "./lib/EnclaveIdStruct.sol"; -import {IAttestation} from "./interfaces/IAttestation.sol"; +import { V3Struct } from "./lib/QuoteV3Auth/V3Struct.sol"; +import { V3Parser } from "./lib/QuoteV3Auth/V3Parser.sol"; +import { IPEMCertChainLib } from "./lib/interfaces/IPEMCertChainLib.sol"; +import { PEMCertChainLib } from "./lib/PEMCertChainLib.sol"; +import { TCBInfoStruct } from "./lib/TCBInfoStruct.sol"; +import { EnclaveIdStruct } from "./lib/EnclaveIdStruct.sol"; +import { IAttestation } from "./interfaces/IAttestation.sol"; // Internal Libraries -import {Base64} from "solady/src/utils/Base64.sol"; -import {LibString} from "solady/src/utils/LibString.sol"; -import {BytesUtils} from "./utils/BytesUtils.sol"; +import { Base64 } from "../../../lib/solady/src/utils/Base64.sol"; +import { LibString } from "../../../lib/solady/src/utils/LibString.sol"; +import { BytesUtils } from "./utils/BytesUtils.sol"; // External Libraries -import {ISigVerifyLib} from "./interfaces/ISigVerifyLib.sol"; +import { ISigVerifyLib } from "./interfaces/ISigVerifyLib.sol"; // import "hardhat/console.sol"; // import "forge-std/console.sol"; @@ -67,17 +67,17 @@ contract AutomataDcapV3Attestation is IAttestation { trustedUserMrSigner[_mrSigner] = _trusted; } - function setMrEnclave( - bytes32 _mrEnclave, - bool _trusted - ) external onlyOwner { + function setMrEnclave(bytes32 _mrEnclave, bool _trusted) external onlyOwner { trustedUserMrEnclave[_mrEnclave] = _trusted; } function addRevokedCertSerialNum( uint256 index, bytes[] calldata serialNumBatch - ) external onlyOwner { + ) + external + onlyOwner + { for (uint256 i = 0; i < serialNumBatch.length; i++) { if (serialNumIsRevoked[index][serialNumBatch[i]]) { continue; @@ -89,7 +89,10 @@ contract AutomataDcapV3Attestation is IAttestation { function removeRevokedCertSerialNum( uint256 index, bytes[] calldata serialNumBatch - ) external onlyOwner { + ) + external + onlyOwner + { for (uint256 i = 0; i < serialNumBatch.length; i++) { if (!serialNumIsRevoked[index][serialNumBatch[i]]) { continue; @@ -101,14 +104,18 @@ contract AutomataDcapV3Attestation is IAttestation { function configureTcbInfoJson( string calldata fmspc, TCBInfoStruct.TCBInfo calldata tcbInfoInput - ) public onlyOwner { + ) + public + onlyOwner + { // 2.2M gas tcbInfo[fmspc] = tcbInfoInput; } - function configureQeIdentityJson( - EnclaveIdStruct.EnclaveId calldata qeIdentityInput - ) external onlyOwner { + function configureQeIdentityJson(EnclaveIdStruct.EnclaveId calldata qeIdentityInput) + external + onlyOwner + { // 250k gas qeIdentity = qeIdentityInput; } @@ -117,41 +124,42 @@ contract AutomataDcapV3Attestation is IAttestation { checkLocalEnclaveReport = !checkLocalEnclaveReport; } - function _attestationTcbIsValid( - TCBInfoStruct.TCBStatus status - ) internal pure virtual returns (bool valid) { - return - status == TCBInfoStruct.TCBStatus.OK || - status == TCBInfoStruct.TCBStatus.TCB_SW_HARDENING_NEEDED || - status == - TCBInfoStruct.TCBStatus.TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED; + function _attestationTcbIsValid(TCBInfoStruct.TCBStatus status) + internal + pure + virtual + returns (bool valid) + { + return status == TCBInfoStruct.TCBStatus.OK + || status == TCBInfoStruct.TCBStatus.TCB_SW_HARDENING_NEEDED + || status == TCBInfoStruct.TCBStatus.TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED; } - function verifyAttestation( - bytes calldata data - ) external view returns (bool) { - (bool success, ) = _verify(data); + function verifyAttestation(bytes calldata data) external view returns (bool) { + (bool success,) = _verify(data); return success; } /// @dev Provide the raw quote binary as input /// @dev The attestation data (or the returned data of this method) /// is constructed depending on the validity of the quote verification. - /// @dev After confirming that a quote has been verified, the attestation's validity then depends on the + /// @dev After confirming that a quote has been verified, the attestation's validity then + /// depends on the /// status of the associated TCB. /// @dev Example scenarios as below: /// -------------------------------- /// @dev Invalid quote verification: returns (false, INVALID_EXIT_CODE) /// - /// @dev For all valid quote verification, the validity of the attestation depends on the status of a - /// matching TCBInfo and this is defined in the _attestationTcbIsValid() method, which can be overwritten - /// in derived contracts. (Except for "Revoked" status, which also returns (false, INVALID_EXIT_CODE) value) + /// @dev For all valid quote verification, the validity of the attestation depends on the status + /// of a + /// matching TCBInfo and this is defined in the _attestationTcbIsValid() method, which can be + /// overwritten + /// in derived contracts. (Except for "Revoked" status, which also returns (false, + /// INVALID_EXIT_CODE) value) /// @dev For all valid quote verification, returns the following data: /// (_attestationTcbIsValid(), abi.encodePacked(sha256(quote), uint8 exitCode)) /// @dev exitCode is defined in the {{ TCBInfoStruct.TCBStatus }} enum - function _verify( - bytes calldata quote - ) private view returns (bool, bytes memory) { + function _verify(bytes calldata quote) private view returns (bool, bytes memory) { bytes memory retData = abi.encodePacked(INVALID_EXIT_CODE); // Step 1: Parse the quote input = 152k gas @@ -172,12 +180,8 @@ contract AutomataDcapV3Attestation is IAttestation { { if (checkLocalEnclaveReport) { // 4k gas - bool mrEnclaveIsTrusted = trustedUserMrEnclave[ - localEnclaveReport.mrEnclave - ]; - bool mrSignerIsTrusted = trustedUserMrSigner[ - localEnclaveReport.mrSigner - ]; + bool mrEnclaveIsTrusted = trustedUserMrEnclave[localEnclaveReport.mrEnclave]; + bool mrSignerIsTrusted = trustedUserMrSigner[localEnclaveReport.mrSigner]; if (!mrEnclaveIsTrusted || !mrSignerIsTrusted) { return (false, retData); @@ -189,23 +193,16 @@ contract AutomataDcapV3Attestation is IAttestation { V3Struct.EnclaveReport memory qeEnclaveReport; EnclaveIdStruct.EnclaveIdStatus qeTcbStatus; { - qeEnclaveReport = V3Parser.parseEnclaveReport( - authDataV3.rawQeReport - ); + qeEnclaveReport = V3Parser.parseEnclaveReport(authDataV3.rawQeReport); bool verifiedEnclaveIdSuccessfully; - ( - verifiedEnclaveIdSuccessfully, - qeTcbStatus - ) = _verifyQEReportWithIdentity(qeEnclaveReport); + (verifiedEnclaveIdSuccessfully, qeTcbStatus) = + _verifyQEReportWithIdentity(qeEnclaveReport); if (!verifiedEnclaveIdSuccessfully) { return (false, retData); } if ( - !verifiedEnclaveIdSuccessfully || - qeTcbStatus == - EnclaveIdStruct - .EnclaveIdStatus - .SGX_ENCLAVE_REPORT_ISVSVN_REVOKED + !verifiedEnclaveIdSuccessfully + || qeTcbStatus == EnclaveIdStruct.EnclaveIdStatus.SGX_ENCLAVE_REPORT_ISVSVN_REVOKED ) { return (false, retData); } @@ -216,13 +213,8 @@ contract AutomataDcapV3Attestation is IAttestation { TCBInfoStruct.TCBInfo memory fetchedTcbInfo; { // 660k gas - ( - bool certParsedSuccessfully, - bytes[] memory quoteCerts - ) = pemCertLib.splitCertificateChain( - authDataV3.certification.certData, - 3 - ); + (bool certParsedSuccessfully, bytes[] memory quoteCerts) = + pemCertLib.splitCertificateChain(authDataV3.certification.certData, 3); if (!certParsedSuccessfully) { return (false, retData); } @@ -235,8 +227,8 @@ contract AutomataDcapV3Attestation is IAttestation { //console.logBytes(quoteCerts[i]); bool isPckCert = i == 0; // additional parsing for PCKCert bool certDecodedSuccessfully; - (certDecodedSuccessfully, parsedQuoteCerts[i]) = pemCertLib - .decodeCert(quoteCerts[i], isPckCert); + (certDecodedSuccessfully, parsedQuoteCerts[i]) = + pemCertLib.decodeCert(quoteCerts[i], isPckCert); if (!certDecodedSuccessfully) { return (false, retData); } @@ -245,25 +237,15 @@ contract AutomataDcapV3Attestation is IAttestation { // Step 5: basic PCK and TCB check = 381k gas { - string memory parsedFmspc = parsedQuoteCerts[0] - .pck - .sgxExtension - .fmspc; + string memory parsedFmspc = parsedQuoteCerts[0].pck.sgxExtension.fmspc; fetchedTcbInfo = tcbInfo[parsedFmspc]; - bool tcbConfigured = LibString.eq( - parsedFmspc, - fetchedTcbInfo.fmspc - ); + bool tcbConfigured = LibString.eq(parsedFmspc, fetchedTcbInfo.fmspc); if (!tcbConfigured) { return (false, retData); } - IPEMCertChainLib.ECSha256Certificate - memory pckCert = parsedQuoteCerts[0]; - bool pceidMatched = LibString.eq( - pckCert.pck.sgxExtension.pceid, - fetchedTcbInfo.pceid - ); + IPEMCertChainLib.ECSha256Certificate memory pckCert = parsedQuoteCerts[0]; + bool pceidMatched = LibString.eq(pckCert.pck.sgxExtension.pceid, fetchedTcbInfo.pceid); if (!pceidMatched) { return (false, retData); } @@ -274,10 +256,7 @@ contract AutomataDcapV3Attestation is IAttestation { { // 4k gas bool tcbVerified; - (tcbVerified, tcbStatus) = _checkTcbLevels( - parsedQuoteCerts[0].pck, - fetchedTcbInfo - ); + (tcbVerified, tcbStatus) = _checkTcbLevels(parsedQuoteCerts[0].pck, fetchedTcbInfo); if (!tcbVerified) { return (false, retData); } @@ -295,10 +274,7 @@ contract AutomataDcapV3Attestation is IAttestation { // Step 8: Verify the local attestation sig and qe report sig = 670k gas { bool enclaveReportSigsVerified = _enclaveReportSigVerification( - parsedQuoteCerts[0].pubKey, - signedQuoteData, - authDataV3, - qeEnclaveReport + parsedQuoteCerts[0].pubKey, signedQuoteData, authDataV3, qeEnclaveReport ); if (!enclaveReportSigsVerified) { return (false, retData); @@ -310,22 +286,20 @@ contract AutomataDcapV3Attestation is IAttestation { return (_attestationTcbIsValid(tcbStatus), retData); } - function _verifyQEReportWithIdentity( - V3Struct.EnclaveReport memory quoteEnclaveReport - ) private view returns (bool, EnclaveIdStruct.EnclaveIdStatus status) { + function _verifyQEReportWithIdentity(V3Struct.EnclaveReport memory quoteEnclaveReport) + private + view + returns (bool, EnclaveIdStruct.EnclaveIdStatus status) + { EnclaveIdStruct.EnclaveId memory enclaveId = qeIdentity; - bool miscselectMatched = quoteEnclaveReport.miscSelect & - enclaveId.miscselectMask == - enclaveId.miscselect; + bool miscselectMatched = + quoteEnclaveReport.miscSelect & enclaveId.miscselectMask == enclaveId.miscselect; - bool attributesMatched = quoteEnclaveReport.attributes & - enclaveId.attributesMask == - enclaveId.attributes; - bool mrsignerMatched = quoteEnclaveReport.mrSigner == - enclaveId.mrsigner; + bool attributesMatched = + quoteEnclaveReport.attributes & enclaveId.attributesMask == enclaveId.attributes; + bool mrsignerMatched = quoteEnclaveReport.mrSigner == enclaveId.mrsigner; - bool isvprodidMatched = quoteEnclaveReport.isvProdId == - enclaveId.isvprodid; + bool isvprodidMatched = quoteEnclaveReport.isvProdId == enclaveId.isvprodid; bool tcbFound; for (uint256 i = 0; i < enclaveId.tcbLevels.length; i++) { @@ -337,11 +311,8 @@ contract AutomataDcapV3Attestation is IAttestation { } } return ( - miscselectMatched && - attributesMatched && - mrsignerMatched && - isvprodidMatched && - tcbFound, + miscselectMatched && attributesMatched && mrsignerMatched && isvprodidMatched + && tcbFound, status ); } @@ -349,19 +320,20 @@ contract AutomataDcapV3Attestation is IAttestation { function _checkTcbLevels( IPEMCertChainLib.PCKCertificateField memory pck, TCBInfoStruct.TCBInfo memory tcb - ) private pure returns (bool, TCBInfoStruct.TCBStatus status) { + ) + private + pure + returns (bool, TCBInfoStruct.TCBStatus status) + { for (uint256 i = 0; i < tcb.tcbLevels.length; i++) { TCBInfoStruct.TCBLevelObj memory current = tcb.tcbLevels[i]; - bool pceSvnIsHigherOrGreater = pck.sgxExtension.pcesvn >= - current.pcesvn; + bool pceSvnIsHigherOrGreater = pck.sgxExtension.pcesvn >= current.pcesvn; bool cpuSvnsAreHigherOrGreater = _isCpuSvnHigherOrGreater( - pck.sgxExtension.sgxTcbCompSvnArr, - current.sgxTcbCompSvnArr + pck.sgxExtension.sgxTcbCompSvnArr, current.sgxTcbCompSvnArr ); if (pceSvnIsHigherOrGreater && cpuSvnsAreHigherOrGreater) { status = current.status; - bool tcbIsRevoked = status == - TCBInfoStruct.TCBStatus.TCB_REVOKED; + bool tcbIsRevoked = status == TCBInfoStruct.TCBStatus.TCB_REVOKED; return (!tcbIsRevoked, status); } } @@ -371,11 +343,12 @@ contract AutomataDcapV3Attestation is IAttestation { function _isCpuSvnHigherOrGreater( uint256[] memory pckCpuSvns, uint8[] memory tcbCpuSvns - ) private pure returns (bool) { - if ( - pckCpuSvns.length != CPUSVN_LENGTH || - tcbCpuSvns.length != CPUSVN_LENGTH - ) { + ) + private + pure + returns (bool) + { + if (pckCpuSvns.length != CPUSVN_LENGTH || tcbCpuSvns.length != CPUSVN_LENGTH) { return false; } for (uint256 i = 0; i < CPUSVN_LENGTH; i++) { @@ -386,9 +359,11 @@ contract AutomataDcapV3Attestation is IAttestation { return true; } - function _verifyCertChain( - IPEMCertChainLib.ECSha256Certificate[] memory certs - ) private view returns (bool) { + function _verifyCertChain(IPEMCertChainLib.ECSha256Certificate[] memory certs) + private + view + returns (bool) + { uint256 n = certs.length; bool certRevoked; bool certNotExpired; @@ -403,13 +378,11 @@ contract AutomataDcapV3Attestation is IAttestation { issuer = certs[i + 1]; if (i == n - 2) { // this cert is expected to be signed by the root - certRevoked = serialNumIsRevoked[ - uint256(IPEMCertChainLib.CRL.ROOT) - ][certs[i].serialNumber]; + certRevoked = serialNumIsRevoked[uint256(IPEMCertChainLib.CRL.ROOT)][certs[i] + .serialNumber]; } else if (certs[i].isPck) { - certRevoked = serialNumIsRevoked[ - uint256(IPEMCertChainLib.CRL.PCK) - ][certs[i].serialNumber]; + certRevoked = + serialNumIsRevoked[uint256(IPEMCertChainLib.CRL.PCK)][certs[i].serialNumber]; } if (certRevoked) { break; @@ -417,16 +390,13 @@ contract AutomataDcapV3Attestation is IAttestation { } certNotExpired = - block.timestamp > certs[i].notBefore && - block.timestamp < certs[i].notAfter; + block.timestamp > certs[i].notBefore && block.timestamp < certs[i].notAfter; if (!certNotExpired) { break; } verified = sigVerifyLib.verifyES256Signature( - certs[i].tbsCertificate, - certs[i].signature, - issuer.pubKey + certs[i].tbsCertificate, certs[i].signature, issuer.pubKey ); if (!verified) { break; @@ -439,8 +409,7 @@ contract AutomataDcapV3Attestation is IAttestation { break; } } - return - !certRevoked && certNotExpired && verified && certChainCanBeTrusted; + return !certRevoked && certNotExpired && verified && certChainCanBeTrusted; } function _enclaveReportSigVerification( @@ -448,27 +417,23 @@ contract AutomataDcapV3Attestation is IAttestation { bytes memory signedQuoteData, V3Struct.ECDSAQuoteV3AuthData memory authDataV3, V3Struct.EnclaveReport memory qeEnclaveReport - ) private view returns (bool) { - bytes32 expectedAuthDataHash = bytes32( - qeEnclaveReport.reportData.substring(0, 32) - ); - bytes memory concatOfAttestKeyAndQeAuthData = abi.encodePacked( - authDataV3.ecdsaAttestationKey, - authDataV3.qeAuthData.data - ); + ) + private + view + returns (bool) + { + bytes32 expectedAuthDataHash = bytes32(qeEnclaveReport.reportData.substring(0, 32)); + bytes memory concatOfAttestKeyAndQeAuthData = + abi.encodePacked(authDataV3.ecdsaAttestationKey, authDataV3.qeAuthData.data); bytes32 computedAuthDataHash = sha256(concatOfAttestKeyAndQeAuthData); bool qeReportDataIsValid = expectedAuthDataHash == computedAuthDataHash; if (qeReportDataIsValid) { bool qeSigVerified = sigVerifyLib.verifyES256Signature( - authDataV3.rawQeReport, - authDataV3.qeReportSignature, - pckCertPubKey + authDataV3.rawQeReport, authDataV3.qeReportSignature, pckCertPubKey ); bool quoteSigVerified = sigVerifyLib.verifyES256Signature( - signedQuoteData, - authDataV3.ecdsa256BitSignature, - authDataV3.ecdsaAttestationKey + signedQuoteData, authDataV3.ecdsa256BitSignature, authDataV3.ecdsaAttestationKey ); return qeSigVerified && quoteSigVerified; } else { @@ -481,29 +446,26 @@ contract AutomataDcapV3Attestation is IAttestation { bytes memory signedQuoteData, V3Struct.ParsedECDSAQuoteV3AuthData memory authDataV3, V3Struct.EnclaveReport memory qeEnclaveReport - ) private view returns (bool) { - bytes32 expectedAuthDataHash = bytes32( - qeEnclaveReport.reportData.substring(0, 32) - ); - bytes memory concatOfAttestKeyAndQeAuthData = abi.encodePacked( - authDataV3.ecdsaAttestationKey, - authDataV3.qeAuthData.data - ); + ) + private + view + returns (bool) + { + bytes32 expectedAuthDataHash = bytes32(qeEnclaveReport.reportData.substring(0, 32)); + bytes memory concatOfAttestKeyAndQeAuthData = + abi.encodePacked(authDataV3.ecdsaAttestationKey, authDataV3.qeAuthData.data); bytes32 computedAuthDataHash = sha256(concatOfAttestKeyAndQeAuthData); bool qeReportDataIsValid = expectedAuthDataHash == computedAuthDataHash; if (qeReportDataIsValid) { - bytes memory pckSignedQeReportBytes = V3Parser.packQEReport(authDataV3.pckSignedQeReport); + bytes memory pckSignedQeReportBytes = + V3Parser.packQEReport(authDataV3.pckSignedQeReport); bool qeSigVerified = sigVerifyLib.verifyES256Signature( - pckSignedQeReportBytes, - authDataV3.qeReportSignature, - pckCertPubKey + pckSignedQeReportBytes, authDataV3.qeReportSignature, pckCertPubKey ); // console.log("qeSigVerified = %s", qeSigVerified); bool quoteSigVerified = sigVerifyLib.verifyES256Signature( - signedQuoteData, - authDataV3.ecdsa256BitSignature, - authDataV3.ecdsaAttestationKey + signedQuoteData, authDataV3.ecdsa256BitSignature, authDataV3.ecdsaAttestationKey ); // console.log("quoteSigVerified = %s", quoteSigVerified); // console.logBytes(signedQuoteData); @@ -520,21 +482,27 @@ contract AutomataDcapV3Attestation is IAttestation { /// @dev Provide the parsed quote binary as input /// @dev The attestation data (or the returned data of this method) /// is constructed depending on the validity of the quote verification. - /// @dev After confirming that a quote has been verified, the attestation's validity then depends on the + /// @dev After confirming that a quote has been verified, the attestation's validity then + /// depends on the /// status of the associated TCB. /// @dev Example scenarios as below: /// -------------------------------- /// @dev Invalid quote verification: returns (false, INVALID_EXIT_CODE) /// - /// @dev For all valid quote verification, the validity of the attestation depends on the status of a - /// matching TCBInfo and this is defined in the _attestationTcbIsValid() method, which can be overwritten - /// in derived contracts. (Except for "Revoked" status, which also returns (false, INVALID_EXIT_CODE) value) + /// @dev For all valid quote verification, the validity of the attestation depends on the status + /// of a + /// matching TCBInfo and this is defined in the _attestationTcbIsValid() method, which can be + /// overwritten + /// in derived contracts. (Except for "Revoked" status, which also returns (false, + /// INVALID_EXIT_CODE) value) /// @dev For all valid quote verification, returns the following data: /// (_attestationTcbIsValid()) /// @dev exitCode is defined in the {{ TCBInfoStruct.TCBStatus }} enum - function verifyParsedQuote( - V3Struct.ParsedV3QuoteStruct calldata v3quote - ) external view returns (bool success, uint8 exitStep) { + function verifyParsedQuote(V3Struct.ParsedV3QuoteStruct calldata v3quote) + external + view + returns (bool success, uint8 exitStep) + { success = false; exitStep = 1; @@ -560,12 +528,8 @@ contract AutomataDcapV3Attestation is IAttestation { { if (checkLocalEnclaveReport) { // 4k gas - bool mrEnclaveIsTrusted = trustedUserMrEnclave[ - v3quote.localEnclaveReport.mrEnclave - ]; - bool mrSignerIsTrusted = trustedUserMrSigner[ - v3quote.localEnclaveReport.mrSigner - ]; + bool mrEnclaveIsTrusted = trustedUserMrEnclave[v3quote.localEnclaveReport.mrEnclave]; + bool mrSignerIsTrusted = trustedUserMrSigner[v3quote.localEnclaveReport.mrSigner]; if (!mrEnclaveIsTrusted || !mrSignerIsTrusted) { return (false, exitStep); @@ -579,21 +543,14 @@ contract AutomataDcapV3Attestation is IAttestation { EnclaveIdStruct.EnclaveIdStatus qeTcbStatus; { bool verifiedEnclaveIdSuccessfully; - ( - verifiedEnclaveIdSuccessfully, - qeTcbStatus - ) = _verifyQEReportWithIdentity( - v3quote.v3AuthData.pckSignedQeReport - ); + (verifiedEnclaveIdSuccessfully, qeTcbStatus) = + _verifyQEReportWithIdentity(v3quote.v3AuthData.pckSignedQeReport); if (!verifiedEnclaveIdSuccessfully) { return (false, exitStep); } if ( - !verifiedEnclaveIdSuccessfully || - qeTcbStatus == - EnclaveIdStruct - .EnclaveIdStatus - .SGX_ENCLAVE_REPORT_ISVSVN_REVOKED + !verifiedEnclaveIdSuccessfully + || qeTcbStatus == EnclaveIdStruct.EnclaveIdStatus.SGX_ENCLAVE_REPORT_ISVSVN_REVOKED ) { return (false, exitStep); } @@ -613,11 +570,9 @@ contract AutomataDcapV3Attestation is IAttestation { bool isPckCert = i == 0; // additional parsing for PCKCert bool certDecodedSuccessfully; // todo! move decodeCert offchain - (certDecodedSuccessfully, parsedQuoteCerts[i]) = pemCertLib - .decodeCert( - authDataV3.certification.decodedCertDataArray[i], - isPckCert - ); + (certDecodedSuccessfully, parsedQuoteCerts[i]) = pemCertLib.decodeCert( + authDataV3.certification.decodedCertDataArray[i], isPckCert + ); if (!certDecodedSuccessfully) { return (false, exitStep); } @@ -628,25 +583,15 @@ contract AutomataDcapV3Attestation is IAttestation { // console.log("Step 5: basic PCK and TCB check = 381k gas"); // Step 5: basic PCK and TCB check = 381k gas { - string memory parsedFmspc = parsedQuoteCerts[0] - .pck - .sgxExtension - .fmspc; + string memory parsedFmspc = parsedQuoteCerts[0].pck.sgxExtension.fmspc; fetchedTcbInfo = tcbInfo[parsedFmspc]; - bool tcbConfigured = LibString.eq( - parsedFmspc, - fetchedTcbInfo.fmspc - ); + bool tcbConfigured = LibString.eq(parsedFmspc, fetchedTcbInfo.fmspc); if (!tcbConfigured) { return (false, exitStep); } - IPEMCertChainLib.ECSha256Certificate - memory pckCert = parsedQuoteCerts[0]; - bool pceidMatched = LibString.eq( - pckCert.pck.sgxExtension.pceid, - fetchedTcbInfo.pceid - ); + IPEMCertChainLib.ECSha256Certificate memory pckCert = parsedQuoteCerts[0]; + bool pceidMatched = LibString.eq(pckCert.pck.sgxExtension.pceid, fetchedTcbInfo.pceid); if (!pceidMatched) { return (false, exitStep); } @@ -659,10 +604,7 @@ contract AutomataDcapV3Attestation is IAttestation { { // 4k gas bool tcbVerified; - (tcbVerified, tcbStatus) = _checkTcbLevels( - parsedQuoteCerts[0].pck, - fetchedTcbInfo - ); + (tcbVerified, tcbStatus) = _checkTcbLevels(parsedQuoteCerts[0].pck, fetchedTcbInfo); if (!tcbVerified) { return (false, exitStep); } @@ -686,11 +628,11 @@ contract AutomataDcapV3Attestation is IAttestation { // Step 8: Verify the local attestation sig and qe report sig { bool enclaveReportSigsVerified = _enclaveParsedReportSigVerification( - parsedQuoteCerts[0].pubKey, - signedQuoteData, - authDataV3, - v3quote.v3AuthData.pckSignedQeReport - ); + parsedQuoteCerts[0].pubKey, + signedQuoteData, + authDataV3, + v3quote.v3AuthData.pckSignedQeReport + ); if (!enclaveReportSigsVerified) { return (false, exitStep); } diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol index b47eb04d798..7baebcaf06d 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {LibString} from "solady/src/Milady.sol"; -import {Asn1Decode, NodePtr} from "../utils/Asn1Decode.sol"; -import {BytesUtils} from "../utils/BytesUtils.sol"; -import {X509DateUtils} from "../utils/X509DateUtils.sol"; -import {IPEMCertChainLib} from "./interfaces/IPEMCertChainLib.sol"; +import { LibString } from "../../../../lib/solady/src/utils/LibString.sol"; +import { Asn1Decode, NodePtr } from "../utils/Asn1Decode.sol"; +import { BytesUtils } from "../utils/BytesUtils.sol"; +import { X509DateUtils } from "../utils/X509DateUtils.sol"; +import { IPEMCertChainLib } from "./interfaces/IPEMCertChainLib.sol"; contract PEMCertChainLib is IPEMCertChainLib { using Asn1Decode for bytes; @@ -35,7 +35,10 @@ contract PEMCertChainLib is IPEMCertChainLib { bool tcbFound; } - function splitCertificateChain(bytes memory pemChain, uint256 size) + function splitCertificateChain( + bytes memory pemChain, + uint256 size + ) external pure returns (bool success, bytes[] memory certs) @@ -66,7 +69,10 @@ contract PEMCertChainLib is IPEMCertChainLib { success = true; } - function decodeCert(bytes memory der, bool isPckCert) + function decodeCert( + bytes memory der, + bool isPckCert + ) external pure returns (bool success, ECSha256Certificate memory cert) @@ -84,7 +90,8 @@ contract PEMCertChainLib is IPEMCertChainLib { // The issuer commonName value is contained in the Issuer sequence // which is 3 elements below the first element of the tbsCertificate sequence - // The Validity sequence is located 4 elements below the first element of the tbsCertificate sequence + // The Validity sequence is located 4 elements below the first element of the tbsCertificate + // sequence // The subject commanName value is contained in the Subject sequence // which is 5 elements below the first element of the tbsCertificate sequence @@ -122,7 +129,10 @@ contract PEMCertChainLib is IPEMCertChainLib { uint256 notAfterPtr = der.nextSiblingOf(notBeforePtr); bytes1 notBeforeTag = der[notBeforePtr.ixs()]; bytes1 notAfterTag = der[notAfterPtr.ixs()]; - if ((notBeforeTag != 0x17 && notBeforeTag == 0x18) || (notAfterTag != 0x17 && notAfterTag != 0x18)) { + if ( + (notBeforeTag != 0x17 && notBeforeTag == 0x18) + || (notAfterTag != 0x17 && notAfterTag != 0x18) + ) { return (false, cert); } cert.notBefore = X509DateUtils.toTimestamp(der.bytesAt(notBeforePtr)); @@ -149,7 +159,8 @@ contract PEMCertChainLib is IPEMCertChainLib { uint256 subjectPublicKeyInfoPtr = der.firstChildOf(tbsPtr); subjectPublicKeyInfoPtr = der.nextSiblingOf(subjectPublicKeyInfoPtr); - // The Signature sequence is located two sibling elements below the tbsCertificate element + // The Signature sequence is located two sibling elements below the tbsCertificate + // element uint256 sigPtr = der.nextSiblingOf(tbsParentPtr); sigPtr = der.nextSiblingOf(sigPtr); @@ -236,7 +247,14 @@ contract PEMCertChainLib is IPEMCertChainLib { return (true, contentBytes, endPos + FOOTER_LENGTH); } - function _trimBytes(bytes memory input, uint256 expectedLength) private pure returns (bytes memory output) { + function _trimBytes( + bytes memory input, + uint256 expectedLength + ) + private + pure + returns (bytes memory output) + { uint256 n = input.length; if (n <= expectedLength) { @@ -246,7 +264,11 @@ contract PEMCertChainLib is IPEMCertChainLib { output = input.substring(lengthDiff, expectedLength); } - function _findPckTcbInfo(bytes memory der, uint256 tbsPtr, uint256 tbsParentPtr) + function _findPckTcbInfo( + bytes memory der, + uint256 tbsPtr, + uint256 tbsParentPtr + ) private pure returns ( @@ -314,7 +336,10 @@ contract PEMCertChainLib is IPEMCertChainLib { } } - function _findTcb(bytes memory der, uint256 oidPtr) + function _findTcb( + bytes memory der, + uint256 oidPtr + ) private pure returns (bool success, uint256 pcesvn, uint256[] memory cpusvns) @@ -328,8 +353,9 @@ contract PEMCertChainLib is IPEMCertChainLib { uint256 svnPtr = der.firstChildOf(svnParentPtr); // OID uint256 svnValuePtr = der.nextSiblingOf(svnPtr); // value bytes memory svnValueBytes = der.bytesAt(svnValuePtr); - uint16 svnValue = - svnValueBytes.length < 2 ? uint16(bytes2(svnValueBytes)) / 256 : uint16(bytes2(svnValueBytes)); + uint16 svnValue = svnValueBytes.length < 2 + ? uint16(bytes2(svnValueBytes)) / 256 + : uint16(bytes2(svnValueBytes)); if (BytesUtils.compareBytes(der.bytesAt(svnPtr), PCESVN_OID)) { // pcesvn is 4 bytes in size pcesvn = uint256(svnValue); diff --git a/packages/protocol/lib/p256-verifier b/packages/protocol/lib/p256-verifier new file mode 160000 index 00000000000..29475ae300e --- /dev/null +++ b/packages/protocol/lib/p256-verifier @@ -0,0 +1 @@ +Subproject commit 29475ae300ec95d98d5c7cc34c094846f0aa2dcd diff --git a/packages/protocol/lib/solady b/packages/protocol/lib/solady new file mode 160000 index 00000000000..fb11b3e9ea6 --- /dev/null +++ b/packages/protocol/lib/solady @@ -0,0 +1 @@ +Subproject commit fb11b3e9ea6c1aafdbd0a1515ff440509d60bff9 diff --git a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol new file mode 100644 index 00000000000..bf8cd7cc4f1 --- /dev/null +++ b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import "forge-std/StdJson.sol"; +import { AutomataDcapV3Attestation } from + "../../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; +import { P256Verifier } from "../../lib/p256-verifier/src/P256Verifier.sol"; +import { SigVerifyLib } from "../../contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from "../../contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol"; +import { V3Struct } from "../../contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; +import { BytesUtils } from "../../contracts/thirdparty/onchainRA/utils/BytesUtils.sol"; +import { Base64 } from "../../lib/solady/src/utils/Base64.sol"; +import "./utils/DcapTestUtils.t.sol"; +import "./utils/V3JsonUtils.t.sol"; + +contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { + using BytesUtils for bytes; + using stdJson for string; + + AutomataDcapV3Attestation attestation; + SigVerifyLib sigVerifyLib; + P256Verifier p256Verifier; + PEMCertChainLib pemCertChainLib; + // use a network that where the P256Verifier contract exists + // ref: https://github.com/daimo-eth/p256-verifier + //string internal rpcUrl = vm.envString("RPC_URL"); + string internal constant tcbInfoPath = "contracts/assets/0923/tcbInfo.json"; + string internal constant idPath = "contracts/assets/0923/identity.json"; + string internal constant v3QuotePath = "contracts/assets/0923/v3quote.json"; + address constant admin = address(1); + address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; + bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; + bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; + + bytes sampleQuote = + hex"030002000000000009000e00939a7233f79c4ca9940a0db3957f0607ccb12a326354d33986ff47365f17ad4c000000000c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000e70000000000000046049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a00000000000000000000000000000000000000000000000000000000000000000ef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca10000084af1f392be216944059f3fa05bf91e1b4e9b513c67493521eb4488af35f49c8f300d57955afc1df97d423c8718ed5b0af82f71047a229df221faa6817ad5daa44131b5c2ed877295959f7333543ba3f17994d767da194a27ba7a4e8a71940118a138dce8499572433c2cc4e4312f92e7144b26f84c59022bfc9aea59967f00d0c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf00000000000000000000000000000000000000000000000000000000000000008c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a654bcd78ffaa5cfc888fc90cbc24fb7f6e19bc8661671f1e3b2cc947db3b6340000000000000000000000000000000000000000000000000000000000000000839adce904d2aec1fc021ad0ec370c7176942d4b64939b95a2e1e1d3e09bf2e57093231f4308b64e8f53b81cd6ae36fc52f202e66ac77b93b13307ee577be36b2000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0500620e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494945386a4343424a696741774942416749554b6e314f2b2b58517264456161433535634a4c307470464867336b77436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a4d774f4449304d6a45304d444d775768634e4d7a41774f4449304d6a45304d444d770a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d34394177454841304941424e47520a727a716c416d4a66617756324b67656a39576e774a736666457868445631756847396e6d57377430505a646e6276732f6c677872584255625657436d5043456f0a4f49587768563673736d6e6b6b48462b576d536a67674d4f4d494944436a416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c33597a4c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f424259454641337234524b62476e54316e584c775a5a7272515559410a4a6b776c4d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f77594a4b6f5a496876684e415130420a424949434c444343416967774867594b4b6f5a496876684e415130424151515179753373424e6d7632566643337932772f445344627a434341575547436971470a534962345451454e41514977676746564d42414743797147534962345451454e415149424167454d4d42414743797147534962345451454e415149434167454d0a4d42414743797147534962345451454e41514944416745444d42414743797147534962345451454e41514945416745444d42454743797147534962345451454e0a41514946416749412f7a415242677371686b69472b4530424451454342674943415038774541594c4b6f5a496876684e4151304241676343415145774541594c0a4b6f5a496876684e4151304241676743415141774541594c4b6f5a496876684e4151304241676b43415141774541594c4b6f5a496876684e4151304241676f430a415141774541594c4b6f5a496876684e4151304241677343415141774541594c4b6f5a496876684e4151304241677743415141774541594c4b6f5a496876684e0a4151304241673043415141774541594c4b6f5a496876684e4151304241673443415141774541594c4b6f5a496876684e4151304241673843415141774541594c0a4b6f5a496876684e4151304241684143415141774541594c4b6f5a496876684e4151304241684543415130774877594c4b6f5a496876684e41513042416849450a4541774d4177502f2f7745414141414141414141414141774541594b4b6f5a496876684e4151304241775143414141774641594b4b6f5a496876684e415130420a4241514741474271414141414d41384743697147534962345451454e4151554b415145774867594b4b6f5a496876684e415130424267515136657645326f42790a6f684e362f30727741346d642b6a424542676f71686b69472b453042445145484d4459774541594c4b6f5a496876684e4151304242774542416638774541594c0a4b6f5a496876684e4151304242774942415141774541594c4b6f5a496876684e4151304242774d4241514177436759494b6f5a497a6a304541774944534141770a52514967522b344377346437476a73684848436c7a394c6269785a4a45632f31666c7a734449504d5451437a2b43304349514430516e6d514c2b4e6b4e374a7a0a655a666c5078644734687a374b652b3443595366744b416a48545a7539413d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a00"; + + function setUp() public { + // uint256 fork = vm.createFork(rpcUrl); + // vm.selectFork(fork); + + // pinned September 23rd, 2023, 0221 UTC + // comment this line out if you are replacing sampleQuote with your own + // this line is needed to bypass expiry reverts for stale quotes + vm.warp(1_695_435_682); + + vm.deal(admin, 100 ether); + + vm.startPrank(admin); + p256Verifier = new P256Verifier(); + sigVerifyLib = new SigVerifyLib(address(p256Verifier)); + pemCertChainLib = new PEMCertChainLib(); + attestation = new AutomataDcapV3Attestation( + address(sigVerifyLib), + address(pemCertChainLib) + ); + attestation.setMrEnclave(mrEnclave, true); + attestation.setMrSigner(mrSigner, true); + + string memory tcbInfoJson = vm.readFile(tcbInfoPath); + string memory enclaveIdJson = vm.readFile(idPath); + + string memory fmspc = "00606a000000"; + (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = + parseTcbInfoJson(tcbInfoJson); + require(tcbParsedSuccess, "tcb parsed failed"); + attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); + + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + require(qeIdParsedSuccess, "qeid parsed failed"); + attestation.configureQeIdentityJson(parsedEnclaveId); + + vm.stopPrank(); + } + + function testAttestation() public { + vm.prank(user); + bool verified = attestation.verifyAttestation(sampleQuote); + assertTrue(verified); + } + + function testParsedQuoteAttestation() public { + vm.prank(user); + string memory v3QuoteJsonStr = vm.readFile(v3QuotePath); + console.log("[LOG] v3QuoteJsonStr: %s", v3QuoteJsonStr); + bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); + console.logBytes(v3QuotePacked); + + (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); + console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); + console.logBytes(v3quote.localEnclaveReport.reportData); + (bool verified,) = attestation.verifyParsedQuote(v3quote); + + // assertTrue(verified); + console.log("[LOG] verified: %s", verified); + } + + function testCRL() public { + bytes[] memory serial = new bytes[](1); + serial[0] = hex"2a7d4efbe5d0add11a682e797092f4b691478379"; + vm.prank(admin); + attestation.addRevokedCertSerialNum(uint256(0), serial); + + vm.prank(user); + bool verified = attestation.verifyAttestation(sampleQuote); + assertTrue(!verified); + } + + struct JsonComplexTest { + JsonTest1 cpuSvn; + JsonTest2 subJson; + } + + struct JsonTest1 { + bytes attestationKeyType; + bytes pceSvn; + bytes qeSvn; + bytes qeVendorId; + bytes teeType; + address userData; + bytes version; + } + + struct JsonTest2 { + bytes attributes; + bytes cpuSvn; + uint256 isvProdId; + uint256 isvSvn; + bytes miscSelect; + bytes32 mrEnclave; + bytes32 mrSigner; + bytes reportData; + bytes reserved1; + bytes32 reserved2; + bytes reserved3; + bytes reserved4; + } + + function testComplexJson() public { + vm.prank(user); + string memory simpleStr = vm.readFile("forge-test/assets/complex.json"); + console.log("[LOG] simpleStr: %s", simpleStr); + bytes memory jsonPacked = vm.parseJson(simpleStr); + console.logBytes(jsonPacked); + + JsonComplexTest memory jt = abi.decode(jsonPacked, (JsonComplexTest)); + console.logAddress(jt.cpuSvn.userData); + console.logBytes32(jt.subJson.mrSigner); + console.logBytes(jt.subJson.reportData); + } +} diff --git a/packages/protocol/test/onchainRA/assets/complex.json b/packages/protocol/test/onchainRA/assets/complex.json new file mode 100644 index 00000000000..4f0a0be7e13 --- /dev/null +++ b/packages/protocol/test/onchainRA/assets/complex.json @@ -0,0 +1,25 @@ +{ + "a_header": { + "version": "0xCDCD", + "attestationKeyType": "0x0200", + "teeType": "0x00000000", + "qeSvn": "0x0900", + "pceSvn": "0x0e00", + "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", + "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" + }, + "b_miscSelect": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x0700000000000000e700000000000000", + "mrEnclave": "0x21c3fac1fee25b4f8a4f5764da7dc52ff9c3cf2aa5b6b68c5a19c4ec69c51421", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 0, + "isvSvn": 0, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + } +} diff --git a/packages/protocol/test/onchainRA/utils/DcapTestUtils.t.sol b/packages/protocol/test/onchainRA/utils/DcapTestUtils.t.sol new file mode 100644 index 00000000000..b45f7520385 --- /dev/null +++ b/packages/protocol/test/onchainRA/utils/DcapTestUtils.t.sol @@ -0,0 +1,262 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import { TCBInfoStruct } from "../../../contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol"; +import { EnclaveIdStruct } from "../../../contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol"; +import { V3Struct } from "../../../contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; +import { JSONParserLib } from "../../../lib/solady/src/utils/JSONParserLib.sol"; +import { LibString } from "../../../lib/solady/src/utils/LibString.sol"; + +contract DcapTestUtils { + using JSONParserLib for JSONParserLib.Item; + using LibString for string; + + uint256 constant INDEX_ERROR = type(uint256).max; + + function parseTcbInfoJson(string memory tcbInfoJsonStr) + internal + pure + returns (bool success, TCBInfoStruct.TCBInfo memory tcbInfo) + { + JSONParserLib.Item memory root = JSONParserLib.parse(tcbInfoJsonStr); + JSONParserLib.Item[] memory children = root.children(); + JSONParserLib.Item[] memory tcbInfoObj; + + uint256 tcbInfoIndex = INDEX_ERROR; + + for (uint256 x = 0; x < root.size(); x++) { + string memory decodedKey = JSONParserLib.decodeString(children[x].key()); + if (decodedKey.eq("tcbInfo")) { + tcbInfoObj = children[x].children(); + tcbInfoIndex = x; + } + } + + if (tcbInfoIndex == INDEX_ERROR) { + return (false, tcbInfo); + } + + JSONParserLib.Item[] memory tcbLevels; + + bool pceIdFound; + bool fmspcFound; + bool tcbLevelsFound; + + for (uint256 i = 0; i < children[tcbInfoIndex].size(); i++) { + JSONParserLib.Item memory current = tcbInfoObj[i]; + string memory decodedKey = JSONParserLib.decodeString(current.key()); + + if (decodedKey.eq("pceId")) { + tcbInfo.pceid = JSONParserLib.decodeString(current.value()); + pceIdFound = true; + } + + if (decodedKey.eq("fmspc")) { + tcbInfo.fmspc = JSONParserLib.decodeString(current.value()); + fmspcFound = true; + } + + if (decodedKey.eq("tcbLevels")) { + tcbLevels = current.children(); + uint256 tcbLevelsSize = current.size(); + tcbInfo.tcbLevels = new TCBInfoStruct.TCBLevelObj[](tcbLevelsSize); + _parsev2TcbLevels(tcbInfo, tcbLevels, tcbLevelsSize); + tcbLevelsFound = true; + } + } + + success = pceIdFound && fmspcFound && tcbLevelsFound; + } + + struct EnclaveIdFlag { + bool miscselectFound; + bool miscselectMaskFound; + bool attributesFound; + bool attributesMaskFound; + bool mrsignerFound; + bool isvprodidFound; + bool tcbLevelsFound; + } + + function parseEnclaveIdentityJson(string memory enclaveIdJsonStr) + internal + pure + returns (bool success, EnclaveIdStruct.EnclaveId memory enclaveId) + { + JSONParserLib.Item memory root = JSONParserLib.parse(enclaveIdJsonStr); + JSONParserLib.Item[] memory children = root.children(); + JSONParserLib.Item[] memory qeIdObj; + + EnclaveIdFlag memory flag; + + for (uint256 i = 0; i < root.size(); i++) { + string memory decodedKey = JSONParserLib.decodeString(children[i].key()); + if (decodedKey.eq("enclaveIdentity")) { + qeIdObj = children[i].children(); + for (uint256 j = 0; j < children[i].size(); j++) { + decodedKey = JSONParserLib.decodeString(qeIdObj[j].key()); + string memory decodedValue; + if (qeIdObj[j].isString()) { + decodedValue = JSONParserLib.decodeString(qeIdObj[j].value()); + } + if (decodedKey.eq("miscselect")) { + bytes memory hexString = _fromHex(decodedValue); + enclaveId.miscselect = bytes4(hexString); + flag.miscselectFound = true; + } + if (decodedKey.eq("miscselectMask")) { + bytes memory hexString = _fromHex(decodedValue); + enclaveId.miscselectMask = bytes4(hexString); + flag.miscselectMaskFound = true; + } + if (decodedKey.eq("attributes")) { + bytes memory hexString = _fromHex(decodedValue); + enclaveId.attributes = bytes16(hexString); + flag.attributesFound = true; + } + if (decodedKey.eq("attributesMask")) { + bytes memory hexString = _fromHex(decodedValue); + enclaveId.attributesMask = bytes16(hexString); + flag.attributesMaskFound = true; + } + if (decodedKey.eq("mrsigner")) { + bytes memory hexString = _fromHex(decodedValue); + enclaveId.mrsigner = bytes32(hexString); + flag.mrsignerFound = true; + } + if (decodedKey.eq("isvprodid")) { + enclaveId.isvprodid = uint16(JSONParserLib.parseUint(qeIdObj[j].value())); + flag.isvprodidFound = true; + } + if (decodedKey.eq("tcbLevels")) { + JSONParserLib.Item memory current = qeIdObj[j]; + JSONParserLib.Item[] memory tcbLevels = current.children(); + uint256 tcbLevelsSize = current.size(); + enclaveId.tcbLevels = new EnclaveIdStruct.TcbLevel[](tcbLevelsSize); + bool parsedSuccessfully = + _parseQuoteIdentityTcbLevels(enclaveId, tcbLevels, tcbLevelsSize); + flag.tcbLevelsFound = parsedSuccessfully; + } + } + } + } + + success = flag.miscselectFound && flag.miscselectMaskFound && flag.attributesFound + && flag.attributesMaskFound && flag.mrsignerFound && flag.isvprodidFound + && flag.tcbLevelsFound; + } + + function _parseQuoteIdentityTcbLevels( + EnclaveIdStruct.EnclaveId memory enclaveId, + JSONParserLib.Item[] memory tcbLevels, + uint256 tcbLevelsSize + ) + private + pure + returns (bool) + { + for (uint256 j = 0; j < tcbLevelsSize; j++) { + JSONParserLib.Item[] memory tcbObjValue = tcbLevels[j].children(); + for (uint256 k = 0; k < tcbLevels[j].size(); k++) { + string memory decodedKey = JSONParserLib.decodeString(tcbObjValue[k].key()); + if (decodedKey.eq("tcb")) { + JSONParserLib.Item memory isvsvn = (tcbObjValue[k].children())[0]; + decodedKey = JSONParserLib.decodeString(isvsvn.key()); + if (decodedKey.eq("isvsvn")) { + enclaveId.tcbLevels[j].tcb.isvsvn = + uint16(JSONParserLib.parseUint(isvsvn.value())); + } else { + return false; + } + } else if (decodedKey.eq("tcbStatus")) { + string memory decodedValue = JSONParserLib.decodeString(tcbObjValue[k].value()); + if (decodedValue.eq("UpToDate")) { + enclaveId.tcbLevels[j].tcbStatus = EnclaveIdStruct.EnclaveIdStatus.OK; + } else if (decodedValue.eq("Revoked")) { + enclaveId.tcbLevels[j].tcbStatus = + EnclaveIdStruct.EnclaveIdStatus.SGX_ENCLAVE_REPORT_ISVSVN_REVOKED; + } + } + } + } + return true; + } + + function _parsev2TcbLevels( + TCBInfoStruct.TCBInfo memory tcbInfo, + JSONParserLib.Item[] memory tcbLevels, + uint256 tcbLevelsSize + ) + private + pure + { + for (uint256 j = 0; j < tcbLevelsSize; j++) { + JSONParserLib.Item[] memory tcbObjValue = tcbLevels[j].children(); + for (uint256 k = 0; k < tcbLevels[j].size(); k++) { + string memory decodedKey = JSONParserLib.decodeString(tcbObjValue[k].key()); + if (decodedKey.eq("tcb")) { + JSONParserLib.Item[] memory tcb = tcbObjValue[k].children(); + tcbInfo.tcbLevels[j].sgxTcbCompSvnArr = new uint8[](tcbObjValue[k].size() - 1); + for (uint256 l = 0; l < tcbObjValue[k].size(); l++) { + decodedKey = JSONParserLib.decodeString(tcb[l].key()); + if (decodedKey.eq("pcesvn")) { + tcbInfo.tcbLevels[j].pcesvn = JSONParserLib.parseUint(tcb[l].value()); + } else { + tcbInfo.tcbLevels[j].sgxTcbCompSvnArr[l] = + uint8(JSONParserLib.parseUint(tcb[l].value())); + } + } + } else if (decodedKey.eq("tcbStatus")) { + string memory decodedValue = JSONParserLib.decodeString(tcbObjValue[k].value()); + if (decodedValue.eq("UpToDate")) { + tcbInfo.tcbLevels[j].status = TCBInfoStruct.TCBStatus.OK; + } else if (decodedValue.eq("OutOfDate")) { + tcbInfo.tcbLevels[j].status = TCBInfoStruct.TCBStatus.TCB_OUT_OF_DATE; + } else if (decodedValue.eq("OutOfDateConfigurationNeeded")) { + tcbInfo.tcbLevels[j].status = + TCBInfoStruct.TCBStatus.TCB_OUT_OF_DATE_CONFIGURATION_NEEDED; + } else if (decodedValue.eq("ConfigurationNeeded")) { + tcbInfo.tcbLevels[j].status = + TCBInfoStruct.TCBStatus.TCB_CONFIGURATION_NEEDED; + } else if (decodedValue.eq("ConfigurationAndSWHardeningNeeded")) { + tcbInfo.tcbLevels[j].status = + TCBInfoStruct.TCBStatus.TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED; + } else if (decodedValue.eq("SWHardeningNeeded")) { + tcbInfo.tcbLevels[j].status = + TCBInfoStruct.TCBStatus.TCB_SW_HARDENING_NEEDED; + } else if (decodedValue.eq("Revoked")) { + tcbInfo.tcbLevels[j].status = TCBInfoStruct.TCBStatus.TCB_REVOKED; + } + } + } + } + } + + // Converts a string to a hexstring (of bytes type) + // https://ethereum.stackexchange.com/questions/39989/solidity-convert-hex-string-to-bytes + + // Convert an hexadecimal character to their value + function _fromHexChar(uint8 c) private pure returns (uint8) { + if (bytes1(c) >= bytes1("0") && bytes1(c) <= bytes1("9")) { + return c - uint8(bytes1("0")); + } + if (bytes1(c) >= bytes1("a") && bytes1(c) <= bytes1("f")) { + return 10 + c - uint8(bytes1("a")); + } + if (bytes1(c) >= bytes1("A") && bytes1(c) <= bytes1("F")) { + return 10 + c - uint8(bytes1("A")); + } + revert("failed to convert hex value"); + } + + // Convert an hexadecimal string to raw bytes + function _fromHex(string memory s) private pure returns (bytes memory) { + bytes memory ss = bytes(s); + require(ss.length % 2 == 0); // length must be even + bytes memory r = new bytes(ss.length / 2); + for (uint256 i = 0; i < ss.length / 2; ++i) { + r[i] = bytes1(_fromHexChar(uint8(ss[2 * i])) * 16 + _fromHexChar(uint8(ss[2 * i + 1]))); + } + return r; + } +} diff --git a/packages/protocol/test/onchainRA/utils/V3JsonUtils.t.sol b/packages/protocol/test/onchainRA/utils/V3JsonUtils.t.sol new file mode 100644 index 00000000000..4861679af52 --- /dev/null +++ b/packages/protocol/test/onchainRA/utils/V3JsonUtils.t.sol @@ -0,0 +1,143 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import { V3Struct } from "../../../contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; +import { JSONParserLib } from "../../../lib/solady/src/utils/JSONParserLib.sol"; +import { LibString } from "../../../lib/solady/src/utils/LibString.sol"; + +contract V3JsonUtils { + using JSONParserLib for JSONParserLib.Item; + using LibString for string; + + // all helper structure are ordered by alphabetical order of their field names + // because the foundry Json decoder will decode the json string in alphabetical order + struct HeaderHelper { + bytes attestationKeyType; + bytes pceSvn; + bytes qeSvn; + bytes qeVendorId; + bytes teeType; + address userData; + bytes version; + } + + struct EnclaveReportHelper { + bytes attributes; + bytes cpuSvn; + uint256 isvProdId; + uint256 isvSvn; + bytes miscSelect; + bytes32 mrEnclave; + bytes32 mrSigner; + bytes reportData; // 64 bytes - For QEReports, this contains the hash of the concatenation + // of attestation key and QEAuthData + bytes reserved1; + bytes32 reserved2; + bytes reserved3; // 96 bytes + bytes reserved4; // 60 bytes + } + + struct QEAuthDataHelper { + bytes32 data; + uint256 parsedDataSize; + } + + // in case data length is 20 + struct QEAuthDataHelperAddress { + address data; + uint256 parsedDataSize; + } + + // in case data length is neither 20 nor 32 + struct QEAuthDataHelperBytes { + bytes data; + uint256 parsedDataSize; + } + + struct CertificationDataHelper { + uint256 certDataSize; + uint256 certType; + bytes[] decodedCertDataArray; + } + + struct ECDSAQuoteV3AuthDataHelper { + CertificationDataHelper certification; + bytes ecdsa256BitSignature; + bytes ecdsaAttestationKey; + EnclaveReportHelper pckSignedQeReport; + QEAuthDataHelper qeAuthData; + bytes qeReportSignature; + } + + struct ParsedV3QuoteStructHelper { + HeaderHelper header; + EnclaveReportHelper localEnclaveReport; + ECDSAQuoteV3AuthDataHelper v3AuthData; + } + + function parseV3QuoteJson(bytes memory v3QuotePacked) + internal + pure + returns (bool success, V3Struct.ParsedV3QuoteStruct memory v3quote) + { + success = true; + ParsedV3QuoteStructHelper memory v3quoteHelper = + abi.decode(v3QuotePacked, (ParsedV3QuoteStructHelper)); + + // setup header + v3quote.header.version = bytes2(v3quoteHelper.header.version); + v3quote.header.attestationKeyType = bytes2(v3quoteHelper.header.attestationKeyType); + v3quote.header.teeType = bytes4(v3quoteHelper.header.teeType); + v3quote.header.qeSvn = bytes2(v3quoteHelper.header.qeSvn); + v3quote.header.pceSvn = bytes2(v3quoteHelper.header.pceSvn); + v3quote.header.qeVendorId = bytes16(v3quoteHelper.header.qeVendorId); + v3quote.header.userData = bytes20(v3quoteHelper.header.userData); + + // setup localEnclaveReport + v3quote.localEnclaveReport.cpuSvn = bytes16(v3quoteHelper.localEnclaveReport.cpuSvn); + v3quote.localEnclaveReport.miscSelect = bytes4(v3quoteHelper.localEnclaveReport.miscSelect); + v3quote.localEnclaveReport.reserved1 = bytes28(v3quoteHelper.localEnclaveReport.reserved1); + v3quote.localEnclaveReport.attributes = bytes16(v3quoteHelper.localEnclaveReport.attributes); + v3quote.localEnclaveReport.mrEnclave = v3quoteHelper.localEnclaveReport.mrEnclave; + v3quote.localEnclaveReport.reserved2 = v3quoteHelper.localEnclaveReport.reserved2; + v3quote.localEnclaveReport.mrSigner = v3quoteHelper.localEnclaveReport.mrSigner; + v3quote.localEnclaveReport.reserved3 = bytes(v3quoteHelper.localEnclaveReport.reserved3); + v3quote.localEnclaveReport.isvProdId = uint16(v3quoteHelper.localEnclaveReport.isvProdId); + v3quote.localEnclaveReport.isvSvn = uint16(v3quoteHelper.localEnclaveReport.isvSvn); + v3quote.localEnclaveReport.reserved4 = bytes(v3quoteHelper.localEnclaveReport.reserved4); + v3quote.localEnclaveReport.reportData = bytes(v3quoteHelper.localEnclaveReport.reportData); + + // setup v3AuthData + v3quote.v3AuthData.ecdsa256BitSignature = + bytes(v3quoteHelper.v3AuthData.ecdsa256BitSignature); + v3quote.v3AuthData.ecdsaAttestationKey = bytes(v3quoteHelper.v3AuthData.ecdsaAttestationKey); + v3quote.v3AuthData.pckSignedQeReport = V3Struct.EnclaveReport({ + cpuSvn: bytes16(v3quoteHelper.v3AuthData.pckSignedQeReport.cpuSvn), + miscSelect: bytes4(v3quoteHelper.v3AuthData.pckSignedQeReport.miscSelect), + reserved1: bytes28(v3quoteHelper.v3AuthData.pckSignedQeReport.reserved1), + attributes: bytes16(v3quoteHelper.v3AuthData.pckSignedQeReport.attributes), + mrEnclave: v3quoteHelper.v3AuthData.pckSignedQeReport.mrEnclave, + reserved2: v3quoteHelper.v3AuthData.pckSignedQeReport.reserved2, + mrSigner: v3quoteHelper.v3AuthData.pckSignedQeReport.mrSigner, + reserved3: bytes(v3quoteHelper.v3AuthData.pckSignedQeReport.reserved3), + isvProdId: uint16(v3quoteHelper.v3AuthData.pckSignedQeReport.isvProdId), + isvSvn: uint16(v3quoteHelper.v3AuthData.pckSignedQeReport.isvSvn), + reserved4: bytes(v3quoteHelper.v3AuthData.pckSignedQeReport.reserved4), + reportData: bytes(v3quoteHelper.v3AuthData.pckSignedQeReport.reportData) + }); + v3quote.v3AuthData.qeReportSignature = bytes(v3quoteHelper.v3AuthData.qeReportSignature); + v3quote.v3AuthData.qeAuthData = V3Struct.ParsedQEAuthData({ + parsedDataSize: uint16(v3quoteHelper.v3AuthData.qeAuthData.parsedDataSize), + data: bytes.concat(v3quoteHelper.v3AuthData.qeAuthData.data) + }); + v3quote.v3AuthData.certification = V3Struct.ParsedCertificationData({ + certType: uint16(v3quoteHelper.v3AuthData.certification.certType), + certDataSize: uint32(v3quoteHelper.v3AuthData.certification.certDataSize), + decodedCertDataArray: [ + v3quoteHelper.v3AuthData.certification.decodedCertDataArray[0], + v3quoteHelper.v3AuthData.certification.decodedCertDataArray[1], + v3quoteHelper.v3AuthData.certification.decodedCertDataArray[2] + ] + }); + } +} From 33ab224485d1eaba1a364cb968841e6ffe48a706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 21:17:46 +0530 Subject: [PATCH 05/44] remove p256 --- .gitmodules | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitmodules b/.gitmodules index 763cb19c183..88b307ed84c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,9 +14,6 @@ path = packages/protocol/lib/forge-std url = https://github.com/foundry-rs/forge-std branch = chore/v1.5.1 -[submodule "packages/protocol/lib/p256-verifier"] - path = packages/protocol/lib/p256-verifier - url = https://github.com/daimo-eth/p256-verifier [submodule "packages/protocol/lib/solady"] path = packages/protocol/lib/solady url = https://github.com/Vectorized/solady From a8efc3fee1fe739ec0000209b0bf35d2f2901b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 21:18:55 +0530 Subject: [PATCH 06/44] remove files --- packages/protocol/lib/p256-verifier | 1 - 1 file changed, 1 deletion(-) delete mode 160000 packages/protocol/lib/p256-verifier diff --git a/packages/protocol/lib/p256-verifier b/packages/protocol/lib/p256-verifier deleted file mode 160000 index 29475ae300e..00000000000 --- a/packages/protocol/lib/p256-verifier +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 29475ae300ec95d98d5c7cc34c094846f0aa2dcd From 8c5e3d31bd39b325e04e9b65728b08f8e3788c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 21:30:12 +0530 Subject: [PATCH 07/44] own dit submodule --- .gitmodules | 3 +++ packages/protocol/lib/p256-verifier | 1 + 2 files changed, 4 insertions(+) create mode 160000 packages/protocol/lib/p256-verifier diff --git a/.gitmodules b/.gitmodules index 88b307ed84c..13907426c32 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,6 @@ [submodule "packages/protocol/lib/solady"] path = packages/protocol/lib/solady url = https://github.com/Vectorized/solady +[submodule "packages/protocol/lib/p256-verifier"] + path = packages/protocol/lib/p256-verifier + url = https://github.com/taikoxyz/p256-verifier diff --git a/packages/protocol/lib/p256-verifier b/packages/protocol/lib/p256-verifier new file mode 160000 index 00000000000..c8210cd99f9 --- /dev/null +++ b/packages/protocol/lib/p256-verifier @@ -0,0 +1 @@ +Subproject commit c8210cd99f9f81a58e25a6a8afdb992fefbd9748 From a6070237e52fbaa39f4402f2204171022477f263 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 24 Jan 2024 21:54:34 +0530 Subject: [PATCH 08/44] fix failing tests --- .../onchainRA/assets/0923/identity.json | 87 ------- .../onchainRA/assets/0923/tcbInfo.json | 221 ------------------ .../onchainRA/assets/0923/v3quote.json | 57 ----- .../thirdparty/onchainRA/assets/v3quote.json | 57 ----- packages/protocol/foundry.toml | 1 + .../AutomataDcapV3AttestationTest.t.sol | 20 +- .../test/onchainRA/assets/0923/identity.json | 78 +++++++ .../test/onchainRA/assets/0923/tcbInfo.json | 221 ++++++++++++++++++ .../test/onchainRA/assets/0923/v3quote.json | 57 +++++ 9 files changed, 366 insertions(+), 433 deletions(-) delete mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json delete mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json delete mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json delete mode 100644 packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json create mode 100644 packages/protocol/test/onchainRA/assets/0923/identity.json create mode 100644 packages/protocol/test/onchainRA/assets/0923/tcbInfo.json create mode 100644 packages/protocol/test/onchainRA/assets/0923/v3quote.json diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json deleted file mode 100644 index 3646327679f..00000000000 --- a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/identity.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "enclaveIdentity": { - "id": "QE", - "version": 2, - "issueDate": "2024-01-03T01:56:45Z", - "nextUpdate": "2024-02-02T01:56:45Z", - "tcbEvaluationDataNumber": 16, - "miscselect": "00000000", - "miscselectMask": "FFFFFFFF", - "attributes": "11000000000000000000000000000000", - "attributesMask": "FBFFFFFFFFFFFFFF0000000000000000", - "mrsigner": "8C4F5775D796503E96137F77C68A829A0056AC8DED70140B081B094490C57BFF", - "isvprodid": 1, - "tcbLevels": [ - { - "tcb": { - "isvsvn": 8 - }, - "tcbDate": "2023-08-09T00:00:00Z", - "tcbStatus": "UpToDate" - }, - { - "tcb": { - "isvsvn": 6 - }, - "tcbDate": "2021-11-10T00:00:00Z", - "tcbStatus": "OutOfDate", - "advisoryIDs": [ - "INTEL-SA-00615" - ] - }, - { - "tcb": { - "isvsvn": 5 - }, - "tcbDate": "2020-11-11T00:00:00Z", - "tcbStatus": "OutOfDate", - "advisoryIDs": [ - "INTEL-SA-00477", - "INTEL-SA-00615" - ] - }, - { - "tcb": { - "isvsvn": 4 - }, - "tcbDate": "2019-11-13T00:00:00Z", - "tcbStatus": "OutOfDate", - "advisoryIDs": [ - "INTEL-SA-00334", - "INTEL-SA-00477", - "INTEL-SA-00615" - ] - }, - { - "tcb": { - "isvsvn": 2 - }, - "tcbDate": "2019-05-15T00:00:00Z", - "tcbStatus": "OutOfDate", - "advisoryIDs": [ - "INTEL-SA-00219", - "INTEL-SA-00293", - "INTEL-SA-00334", - "INTEL-SA-00477", - "INTEL-SA-00615" - ] - }, - { - "tcb": { - "isvsvn": 1 - }, - "tcbDate": "2018-08-15T00: 00: 00Z", - "tcbStatus": "OutOfDate", - "advisoryIDs": [ - "INTEL-SA-00202", - "INTEL-SA-00219", - "INTEL-SA-00293", - "INTEL-SA-00334", - "INTEL-SA-00477", - "INTEL-SA-00615" - ] - } - ] - }, - "signature": "510deee07e2ca622264c87e8324351a3c3faf7679ee13efa2883d4cc30373c6f51e45f1fc95c983410bf66604f1ee218a3ee6c8e279367a1991f40cba53aff9b" -} \ No newline at end of file diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json deleted file mode 100644 index a3bf39eabaf..00000000000 --- a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/tcbInfo.json +++ /dev/null @@ -1,221 +0,0 @@ -{ - "tcbInfo": { - "version": 2, - "issueDate": "2024-01-10T02:32:48Z", - "nextUpdate": "2024-02-09T02:32:48Z", - "fmspc": "00606a000000", - "pceId": "0000", - "tcbType": 0, - "tcbEvaluationDataNumber": 16, - "tcbLevels": [ - { - "tcb": { - "sgxtcbcomp01svn": 12, - "sgxtcbcomp02svn": 12, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 1, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 13 - }, - "tcbDate": "2023-08-09T00:00:00Z", - "tcbStatus": "SWHardeningNeeded" - }, - { - "tcb": { - "sgxtcbcomp01svn": 12, - "sgxtcbcomp02svn": 12, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 13 - }, - "tcbDate": "2023-08-09T00:00:00Z", - "tcbStatus": "ConfigurationAndSWHardeningNeeded" - }, - { - "tcb": { - "sgxtcbcomp01svn": 11, - "sgxtcbcomp02svn": 11, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 1, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 13 - }, - "tcbDate": "2023-02-15T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "sgxtcbcomp01svn": 11, - "sgxtcbcomp02svn": 11, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 13 - }, - "tcbDate": "2023-02-15T00:00:00Z", - "tcbStatus": "OutOfDateConfigurationNeeded" - }, - { - "tcb": { - "sgxtcbcomp01svn": 7, - "sgxtcbcomp02svn": 9, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 1, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 13 - }, - "tcbDate": "2022-08-10T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "sgxtcbcomp01svn": 7, - "sgxtcbcomp02svn": 9, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 13 - }, - "tcbDate": "2022-08-10T00:00:00Z", - "tcbStatus": "OutOfDateConfigurationNeeded" - }, - { - "tcb": { - "sgxtcbcomp01svn": 4, - "sgxtcbcomp02svn": 4, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 11 - }, - "tcbDate": "2021-11-10T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "sgxtcbcomp01svn": 4, - "sgxtcbcomp02svn": 4, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 10 - }, - "tcbDate": "2020-11-11T00:00:00Z", - "tcbStatus": "OutOfDate" - }, - { - "tcb": { - "sgxtcbcomp01svn": 4, - "sgxtcbcomp02svn": 4, - "sgxtcbcomp03svn": 3, - "sgxtcbcomp04svn": 3, - "sgxtcbcomp05svn": 255, - "sgxtcbcomp06svn": 255, - "sgxtcbcomp07svn": 0, - "sgxtcbcomp08svn": 0, - "sgxtcbcomp09svn": 0, - "sgxtcbcomp10svn": 0, - "sgxtcbcomp11svn": 0, - "sgxtcbcomp12svn": 0, - "sgxtcbcomp13svn": 0, - "sgxtcbcomp14svn": 0, - "sgxtcbcomp15svn": 0, - "sgxtcbcomp16svn": 0, - "pcesvn": 5 - }, - "tcbDate": "2018-01-04T00:00:00Z", - "tcbStatus": "OutOfDate" - } - ] - }, - "signature": "82d69c3a986618c91ac973fc2c4ae1baf7ec0de1c1e2366a412dabc3198c507caafb6bce84c8ee3ca13091f442ae387688431ff2779257328b59bfd7cfd2772e" -} \ No newline at end of file diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json deleted file mode 100644 index c55ea89f652..00000000000 --- a/packages/protocol/contracts/thirdparty/onchainRA/assets/0923/v3quote.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "header": { - "version": "0x0300", - "attestationKeyType": "0x0200", - "teeType": "0x00000000", - "qeSvn": "0x0900", - "pceSvn": "0x0e00", - "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", - "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" - }, - "localEnclaveReport": { - "cpuSvn": "0x0b0b100fffff00000000000000000000", - "miscSelect": "0x00000000", - "reserved1": "0x00000000000000000000000000000000000000000000000000000000", - "attributes": "0x0700000000000000e700000000000000", - "mrEnclave": "0x21c3fac1fee25b4f8a4f5764da7dc52ff9c3cf2aa5b6b68c5a19c4ec69c51421", - "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", - "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "isvProdId": 0, - "isvSvn": 0, - "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "reportData": "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" - }, - "v3AuthData": { - "ecdsa256BitSignature": "0x0bab69c919b1247266c11b137097623aac4d3e4e36c9000f7c22ab7b767145bac9cd5f1ab1eae683ac85a53b4a0d0dbfe19055e5babe254451e1646a1be42c1b", - "ecdsaAttestationKey": "0x98dcbff3d66af81d0004ae624e8d922da31c4aefc2a85d0723f38997563ea5449dcbf7d4d351b171625415fde6f443ea3e56d099fa62cc77553f80f18a054ba7", - "pckSignedQeReport": { - "cpuSvn": "0x0b0b100fffff00000000000000000000", - "miscSelect": "0x00000000", - "reserved1": "0x00000000000000000000000000000000000000000000000000000000", - "attributes": "0x1500000000000000e700000000000000", - "mrEnclave": "0x192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf", - "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "mrSigner": "0x8c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff", - "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "isvProdId": 1, - "isvSvn": 9, - "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "reportData": "0x915aca8fa4e14365a753fc034261f5d8b2a4e75c83c6ffb90316a11ba6df1b550000000000000000000000000000000000000000000000000000000000000000" - }, - "qeReportSignature": "0xc5ce106db64b25bdd5c9f6c52bfb993cd231d73774a1e9532ed155b0ee43848ec2107e28f63313405a33c59b547f74099b673bc8ee101797ce9c6ba01fb399c5", - "qeAuthData": { - "parsedDataSize": 32, - "data": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" - }, - "certification": { - "certType": 5, - "certDataSize": 3682, - "decodedCertDataArray": [ - "0x308204f330820499a003020102021500bcfe8d88f1717f9f26898051b089aa089f22897a300a06082a8648ce3d04030230703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3233303832383131313330355a170d3330303832383131313330355a30703122302006035504030c19496e74656c205347582050434b204365727469666963617465311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000432b004ab4baae47a3d781dfd494a9b8f3b5343515cb35c10afa75878d85d74514d001545a0d58e3ca1e060eedbcde57d884c6101e731c18f38eff64b96c948d4a382030e3082030a301f0603551d23041830168014956f5dcdbd1be1e94049c9d4f433ce01570bde54306b0603551d1f046430623060a05ea05c865a68747470733a2f2f6170692e7472757374656473657276696365732e696e74656c2e636f6d2f7367782f63657274696669636174696f6e2f76342f70636b63726c3f63613d706c6174666f726d26656e636f64696e673d646572301d0603551d0e041604145357a665cf5bc991849f9098fc3627f3aa06b058300e0603551d0f0101ff0404030206c0300c0603551d130101ff040230003082023b06092a864886f84d010d010482022c30820228301e060a2a864886f84d010d01010410fe46ae011cce8a4d6e8334b08d1bb40130820165060a2a864886f84d010d0102308201553010060b2a864886f84d010d01020102010b3010060b2a864886f84d010d01020202010b3010060b2a864886f84d010d0102030201033010060b2a864886f84d010d0102040201033011060b2a864886f84d010d010205020200ff3011060b2a864886f84d010d010206020200ff3010060b2a864886f84d010d0102070201003010060b2a864886f84d010d0102080201003010060b2a864886f84d010d0102090201003010060b2a864886f84d010d01020a0201003010060b2a864886f84d010d01020b0201003010060b2a864886f84d010d01020c0201003010060b2a864886f84d010d01020d0201003010060b2a864886f84d010d01020e0201003010060b2a864886f84d010d01020f0201003010060b2a864886f84d010d0102100201003010060b2a864886f84d010d01021102010d301f060b2a864886f84d010d01021204100b0b0303ffff000000000000000000003010060a2a864886f84d010d0103040200003014060a2a864886f84d010d0104040600606a000000300f060a2a864886f84d010d01050a0101301e060a2a864886f84d010d010604104589ccebf2644f0ade48ff1e15c46bfb3044060a2a864886f84d010d010730363010060b2a864886f84d010d0107010101ff3010060b2a864886f84d010d0107020101ff3010060b2a864886f84d010d0107030101ff300a06082a8648ce3d040302034800304502201ab7bf1d8335a99004599474c7be98f6040aef385e0a050a0230489578709693022100e37a7bb6bc01f34b3eda2c1a8660dd02708cc0954f2e2484bb00d017c544812c", - "0x308202963082023da003020102021500956f5dcdbd1be1e94049c9d4f433ce01570bde54300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130353031305a170d3333303532313130353031305a30703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000435207feeddb595748ed82bb3a71c3be1e241ef61320c6816e6b5c2b71dad5532eaea12a4eb3f948916429ea47ba6c3af82a15e4b19664e52657939a2d96633dea381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e04160414956f5dcdbd1be1e94049c9d4f433ce01570bde54300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100300a06082a8648ce3d040302034700304402205ec5648b4c3e8ba558196dd417fdb6b9a5ded182438f551e9c0f938c3d5a8b970220261bd520260f9c647d3569be8e14a32892631ac358b994478088f4d2b27cf37e", - "0x3082028f30820234a003020102021422650cd65a9d3489f383b49552bf501b392706ac300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130343531305a170d3439313233313233353935395a3068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d030107034200040ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394a381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e0416041422650cd65a9d3489f383b49552bf501b392706ac300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020101300a06082a8648ce3d0403020349003046022100e5bfe50911f92f428920dc368a302ee3d12ec5867ff622ec6497f78060c13c20022100e09d25ac7a0cb3e5e8e68fec5fa3bd416c47440bd950639d450edcbea4576aa2" - ] - } - } -} \ No newline at end of file diff --git a/packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json b/packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json deleted file mode 100644 index c55ea89f652..00000000000 --- a/packages/protocol/contracts/thirdparty/onchainRA/assets/v3quote.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "header": { - "version": "0x0300", - "attestationKeyType": "0x0200", - "teeType": "0x00000000", - "qeSvn": "0x0900", - "pceSvn": "0x0e00", - "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", - "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" - }, - "localEnclaveReport": { - "cpuSvn": "0x0b0b100fffff00000000000000000000", - "miscSelect": "0x00000000", - "reserved1": "0x00000000000000000000000000000000000000000000000000000000", - "attributes": "0x0700000000000000e700000000000000", - "mrEnclave": "0x21c3fac1fee25b4f8a4f5764da7dc52ff9c3cf2aa5b6b68c5a19c4ec69c51421", - "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", - "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "isvProdId": 0, - "isvSvn": 0, - "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "reportData": "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" - }, - "v3AuthData": { - "ecdsa256BitSignature": "0x0bab69c919b1247266c11b137097623aac4d3e4e36c9000f7c22ab7b767145bac9cd5f1ab1eae683ac85a53b4a0d0dbfe19055e5babe254451e1646a1be42c1b", - "ecdsaAttestationKey": "0x98dcbff3d66af81d0004ae624e8d922da31c4aefc2a85d0723f38997563ea5449dcbf7d4d351b171625415fde6f443ea3e56d099fa62cc77553f80f18a054ba7", - "pckSignedQeReport": { - "cpuSvn": "0x0b0b100fffff00000000000000000000", - "miscSelect": "0x00000000", - "reserved1": "0x00000000000000000000000000000000000000000000000000000000", - "attributes": "0x1500000000000000e700000000000000", - "mrEnclave": "0x192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf", - "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "mrSigner": "0x8c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff", - "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "isvProdId": 1, - "isvSvn": 9, - "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "reportData": "0x915aca8fa4e14365a753fc034261f5d8b2a4e75c83c6ffb90316a11ba6df1b550000000000000000000000000000000000000000000000000000000000000000" - }, - "qeReportSignature": "0xc5ce106db64b25bdd5c9f6c52bfb993cd231d73774a1e9532ed155b0ee43848ec2107e28f63313405a33c59b547f74099b673bc8ee101797ce9c6ba01fb399c5", - "qeAuthData": { - "parsedDataSize": 32, - "data": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" - }, - "certification": { - "certType": 5, - "certDataSize": 3682, - "decodedCertDataArray": [ - "0x308204f330820499a003020102021500bcfe8d88f1717f9f26898051b089aa089f22897a300a06082a8648ce3d04030230703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3233303832383131313330355a170d3330303832383131313330355a30703122302006035504030c19496e74656c205347582050434b204365727469666963617465311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000432b004ab4baae47a3d781dfd494a9b8f3b5343515cb35c10afa75878d85d74514d001545a0d58e3ca1e060eedbcde57d884c6101e731c18f38eff64b96c948d4a382030e3082030a301f0603551d23041830168014956f5dcdbd1be1e94049c9d4f433ce01570bde54306b0603551d1f046430623060a05ea05c865a68747470733a2f2f6170692e7472757374656473657276696365732e696e74656c2e636f6d2f7367782f63657274696669636174696f6e2f76342f70636b63726c3f63613d706c6174666f726d26656e636f64696e673d646572301d0603551d0e041604145357a665cf5bc991849f9098fc3627f3aa06b058300e0603551d0f0101ff0404030206c0300c0603551d130101ff040230003082023b06092a864886f84d010d010482022c30820228301e060a2a864886f84d010d01010410fe46ae011cce8a4d6e8334b08d1bb40130820165060a2a864886f84d010d0102308201553010060b2a864886f84d010d01020102010b3010060b2a864886f84d010d01020202010b3010060b2a864886f84d010d0102030201033010060b2a864886f84d010d0102040201033011060b2a864886f84d010d010205020200ff3011060b2a864886f84d010d010206020200ff3010060b2a864886f84d010d0102070201003010060b2a864886f84d010d0102080201003010060b2a864886f84d010d0102090201003010060b2a864886f84d010d01020a0201003010060b2a864886f84d010d01020b0201003010060b2a864886f84d010d01020c0201003010060b2a864886f84d010d01020d0201003010060b2a864886f84d010d01020e0201003010060b2a864886f84d010d01020f0201003010060b2a864886f84d010d0102100201003010060b2a864886f84d010d01021102010d301f060b2a864886f84d010d01021204100b0b0303ffff000000000000000000003010060a2a864886f84d010d0103040200003014060a2a864886f84d010d0104040600606a000000300f060a2a864886f84d010d01050a0101301e060a2a864886f84d010d010604104589ccebf2644f0ade48ff1e15c46bfb3044060a2a864886f84d010d010730363010060b2a864886f84d010d0107010101ff3010060b2a864886f84d010d0107020101ff3010060b2a864886f84d010d0107030101ff300a06082a8648ce3d040302034800304502201ab7bf1d8335a99004599474c7be98f6040aef385e0a050a0230489578709693022100e37a7bb6bc01f34b3eda2c1a8660dd02708cc0954f2e2484bb00d017c544812c", - "0x308202963082023da003020102021500956f5dcdbd1be1e94049c9d4f433ce01570bde54300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130353031305a170d3333303532313130353031305a30703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000435207feeddb595748ed82bb3a71c3be1e241ef61320c6816e6b5c2b71dad5532eaea12a4eb3f948916429ea47ba6c3af82a15e4b19664e52657939a2d96633dea381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e04160414956f5dcdbd1be1e94049c9d4f433ce01570bde54300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100300a06082a8648ce3d040302034700304402205ec5648b4c3e8ba558196dd417fdb6b9a5ded182438f551e9c0f938c3d5a8b970220261bd520260f9c647d3569be8e14a32892631ac358b994478088f4d2b27cf37e", - "0x3082028f30820234a003020102021422650cd65a9d3489f383b49552bf501b392706ac300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130343531305a170d3439313233313233353935395a3068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d030107034200040ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394a381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e0416041422650cd65a9d3489f383b49552bf501b392706ac300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020101300a06082a8648ce3d0403020349003046022100e5bfe50911f92f428920dc368a302ee3d12ec5867ff622ec6497f78060c13c20022100e09d25ac7a0cb3e5e8e68fec5fa3bd416c47440bd950639d450edcbea4576aa2" - ] - } - } -} \ No newline at end of file diff --git a/packages/protocol/foundry.toml b/packages/protocol/foundry.toml index e168a2a152a..124a3b98dbf 100644 --- a/packages/protocol/foundry.toml +++ b/packages/protocol/foundry.toml @@ -23,6 +23,7 @@ fs_permissions = [ { access = "read-write", path = "./deployments" }, { access = "read", path = "./test" }, { access = "read", path = "./genesis" }, + { access = "read", path = "./test/onchainRA/assets/0923"}, ] fuzz = { runs = 256 } diff --git a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol index bf8cd7cc4f1..d74bfd598ea 100644 --- a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol @@ -26,9 +26,9 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { // use a network that where the P256Verifier contract exists // ref: https://github.com/daimo-eth/p256-verifier //string internal rpcUrl = vm.envString("RPC_URL"); - string internal constant tcbInfoPath = "contracts/assets/0923/tcbInfo.json"; - string internal constant idPath = "contracts/assets/0923/identity.json"; - string internal constant v3QuotePath = "contracts/assets/0923/v3quote.json"; + string internal constant tcbInfoPath = "/test/onchainRA/assets/0923/tcbInfo.json"; + string internal constant idPath = "/test/onchainRA/assets/0923/identity.json"; + string internal constant v3QuotePath = "/test/onchainRA/assets/0923/v3quote.json"; address constant admin = address(1); address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; @@ -52,15 +52,12 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { p256Verifier = new P256Verifier(); sigVerifyLib = new SigVerifyLib(address(p256Verifier)); pemCertChainLib = new PEMCertChainLib(); - attestation = new AutomataDcapV3Attestation( - address(sigVerifyLib), - address(pemCertChainLib) - ); + attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); attestation.setMrEnclave(mrEnclave, true); attestation.setMrSigner(mrSigner, true); - string memory tcbInfoJson = vm.readFile(tcbInfoPath); - string memory enclaveIdJson = vm.readFile(idPath); + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); string memory fmspc = "00606a000000"; (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = @@ -84,7 +81,7 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { function testParsedQuoteAttestation() public { vm.prank(user); - string memory v3QuoteJsonStr = vm.readFile(v3QuotePath); + string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); console.log("[LOG] v3QuoteJsonStr: %s", v3QuoteJsonStr); bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); console.logBytes(v3QuotePacked); @@ -141,7 +138,8 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { function testComplexJson() public { vm.prank(user); - string memory simpleStr = vm.readFile("forge-test/assets/complex.json"); + string memory simpleStr = + vm.readFile(string.concat(vm.projectRoot(), "/test/onchainRA/assets/complex.json")); console.log("[LOG] simpleStr: %s", simpleStr); bytes memory jsonPacked = vm.parseJson(simpleStr); console.logBytes(jsonPacked); diff --git a/packages/protocol/test/onchainRA/assets/0923/identity.json b/packages/protocol/test/onchainRA/assets/0923/identity.json new file mode 100644 index 00000000000..621a2eab13f --- /dev/null +++ b/packages/protocol/test/onchainRA/assets/0923/identity.json @@ -0,0 +1,78 @@ +{ + "enclaveIdentity": { + "id": "QE", + "version": 2, + "issueDate": "2024-01-03T01:56:45Z", + "nextUpdate": "2024-02-02T01:56:45Z", + "tcbEvaluationDataNumber": 16, + "miscselect": "00000000", + "miscselectMask": "FFFFFFFF", + "attributes": "11000000000000000000000000000000", + "attributesMask": "FBFFFFFFFFFFFFFF0000000000000000", + "mrsigner": "8C4F5775D796503E96137F77C68A829A0056AC8DED70140B081B094490C57BFF", + "isvprodid": 1, + "tcbLevels": [ + { + "tcb": { + "isvsvn": 8 + }, + "tcbDate": "2023-08-09T00:00:00Z", + "tcbStatus": "UpToDate" + }, + { + "tcb": { + "isvsvn": 6 + }, + "tcbDate": "2021-11-10T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": ["INTEL-SA-00615"] + }, + { + "tcb": { + "isvsvn": 5 + }, + "tcbDate": "2020-11-11T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": ["INTEL-SA-00477", "INTEL-SA-00615"] + }, + { + "tcb": { + "isvsvn": 4 + }, + "tcbDate": "2019-11-13T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": ["INTEL-SA-00334", "INTEL-SA-00477", "INTEL-SA-00615"] + }, + { + "tcb": { + "isvsvn": 2 + }, + "tcbDate": "2019-05-15T00:00:00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": [ + "INTEL-SA-00219", + "INTEL-SA-00293", + "INTEL-SA-00334", + "INTEL-SA-00477", + "INTEL-SA-00615" + ] + }, + { + "tcb": { + "isvsvn": 1 + }, + "tcbDate": "2018-08-15T00: 00: 00Z", + "tcbStatus": "OutOfDate", + "advisoryIDs": [ + "INTEL-SA-00202", + "INTEL-SA-00219", + "INTEL-SA-00293", + "INTEL-SA-00334", + "INTEL-SA-00477", + "INTEL-SA-00615" + ] + } + ] + }, + "signature": "510deee07e2ca622264c87e8324351a3c3faf7679ee13efa2883d4cc30373c6f51e45f1fc95c983410bf66604f1ee218a3ee6c8e279367a1991f40cba53aff9b" +} diff --git a/packages/protocol/test/onchainRA/assets/0923/tcbInfo.json b/packages/protocol/test/onchainRA/assets/0923/tcbInfo.json new file mode 100644 index 00000000000..0be7ef91eaa --- /dev/null +++ b/packages/protocol/test/onchainRA/assets/0923/tcbInfo.json @@ -0,0 +1,221 @@ +{ + "tcbInfo": { + "version": 2, + "issueDate": "2024-01-10T02:32:48Z", + "nextUpdate": "2024-02-09T02:32:48Z", + "fmspc": "00606a000000", + "pceId": "0000", + "tcbType": 0, + "tcbEvaluationDataNumber": 16, + "tcbLevels": [ + { + "tcb": { + "sgxtcbcomp01svn": 12, + "sgxtcbcomp02svn": 12, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 1, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-08-09T00:00:00Z", + "tcbStatus": "SWHardeningNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 12, + "sgxtcbcomp02svn": 12, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-08-09T00:00:00Z", + "tcbStatus": "ConfigurationAndSWHardeningNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 11, + "sgxtcbcomp02svn": 11, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 1, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-02-15T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 11, + "sgxtcbcomp02svn": 11, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2023-02-15T00:00:00Z", + "tcbStatus": "OutOfDateConfigurationNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 7, + "sgxtcbcomp02svn": 9, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 1, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2022-08-10T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 7, + "sgxtcbcomp02svn": 9, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 13 + }, + "tcbDate": "2022-08-10T00:00:00Z", + "tcbStatus": "OutOfDateConfigurationNeeded" + }, + { + "tcb": { + "sgxtcbcomp01svn": 4, + "sgxtcbcomp02svn": 4, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 11 + }, + "tcbDate": "2021-11-10T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 4, + "sgxtcbcomp02svn": 4, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 10 + }, + "tcbDate": "2020-11-11T00:00:00Z", + "tcbStatus": "OutOfDate" + }, + { + "tcb": { + "sgxtcbcomp01svn": 4, + "sgxtcbcomp02svn": 4, + "sgxtcbcomp03svn": 3, + "sgxtcbcomp04svn": 3, + "sgxtcbcomp05svn": 255, + "sgxtcbcomp06svn": 255, + "sgxtcbcomp07svn": 0, + "sgxtcbcomp08svn": 0, + "sgxtcbcomp09svn": 0, + "sgxtcbcomp10svn": 0, + "sgxtcbcomp11svn": 0, + "sgxtcbcomp12svn": 0, + "sgxtcbcomp13svn": 0, + "sgxtcbcomp14svn": 0, + "sgxtcbcomp15svn": 0, + "sgxtcbcomp16svn": 0, + "pcesvn": 5 + }, + "tcbDate": "2018-01-04T00:00:00Z", + "tcbStatus": "OutOfDate" + } + ] + }, + "signature": "82d69c3a986618c91ac973fc2c4ae1baf7ec0de1c1e2366a412dabc3198c507caafb6bce84c8ee3ca13091f442ae387688431ff2779257328b59bfd7cfd2772e" +} diff --git a/packages/protocol/test/onchainRA/assets/0923/v3quote.json b/packages/protocol/test/onchainRA/assets/0923/v3quote.json new file mode 100644 index 00000000000..4b25483ad0e --- /dev/null +++ b/packages/protocol/test/onchainRA/assets/0923/v3quote.json @@ -0,0 +1,57 @@ +{ + "header": { + "version": "0x0300", + "attestationKeyType": "0x0200", + "teeType": "0x00000000", + "qeSvn": "0x0900", + "pceSvn": "0x0e00", + "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", + "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" + }, + "localEnclaveReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x0700000000000000e700000000000000", + "mrEnclave": "0x21c3fac1fee25b4f8a4f5764da7dc52ff9c3cf2aa5b6b68c5a19c4ec69c51421", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 0, + "isvSvn": 0, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" + }, + "v3AuthData": { + "ecdsa256BitSignature": "0x0bab69c919b1247266c11b137097623aac4d3e4e36c9000f7c22ab7b767145bac9cd5f1ab1eae683ac85a53b4a0d0dbfe19055e5babe254451e1646a1be42c1b", + "ecdsaAttestationKey": "0x98dcbff3d66af81d0004ae624e8d922da31c4aefc2a85d0723f38997563ea5449dcbf7d4d351b171625415fde6f443ea3e56d099fa62cc77553f80f18a054ba7", + "pckSignedQeReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x1500000000000000e700000000000000", + "mrEnclave": "0x192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x8c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 1, + "isvSvn": 9, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x915aca8fa4e14365a753fc034261f5d8b2a4e75c83c6ffb90316a11ba6df1b550000000000000000000000000000000000000000000000000000000000000000" + }, + "qeReportSignature": "0xc5ce106db64b25bdd5c9f6c52bfb993cd231d73774a1e9532ed155b0ee43848ec2107e28f63313405a33c59b547f74099b673bc8ee101797ce9c6ba01fb399c5", + "qeAuthData": { + "parsedDataSize": 32, + "data": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + }, + "certification": { + "certType": 5, + "certDataSize": 3682, + "decodedCertDataArray": [ + "0x308204f330820499a003020102021500bcfe8d88f1717f9f26898051b089aa089f22897a300a06082a8648ce3d04030230703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3233303832383131313330355a170d3330303832383131313330355a30703122302006035504030c19496e74656c205347582050434b204365727469666963617465311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000432b004ab4baae47a3d781dfd494a9b8f3b5343515cb35c10afa75878d85d74514d001545a0d58e3ca1e060eedbcde57d884c6101e731c18f38eff64b96c948d4a382030e3082030a301f0603551d23041830168014956f5dcdbd1be1e94049c9d4f433ce01570bde54306b0603551d1f046430623060a05ea05c865a68747470733a2f2f6170692e7472757374656473657276696365732e696e74656c2e636f6d2f7367782f63657274696669636174696f6e2f76342f70636b63726c3f63613d706c6174666f726d26656e636f64696e673d646572301d0603551d0e041604145357a665cf5bc991849f9098fc3627f3aa06b058300e0603551d0f0101ff0404030206c0300c0603551d130101ff040230003082023b06092a864886f84d010d010482022c30820228301e060a2a864886f84d010d01010410fe46ae011cce8a4d6e8334b08d1bb40130820165060a2a864886f84d010d0102308201553010060b2a864886f84d010d01020102010b3010060b2a864886f84d010d01020202010b3010060b2a864886f84d010d0102030201033010060b2a864886f84d010d0102040201033011060b2a864886f84d010d010205020200ff3011060b2a864886f84d010d010206020200ff3010060b2a864886f84d010d0102070201003010060b2a864886f84d010d0102080201003010060b2a864886f84d010d0102090201003010060b2a864886f84d010d01020a0201003010060b2a864886f84d010d01020b0201003010060b2a864886f84d010d01020c0201003010060b2a864886f84d010d01020d0201003010060b2a864886f84d010d01020e0201003010060b2a864886f84d010d01020f0201003010060b2a864886f84d010d0102100201003010060b2a864886f84d010d01021102010d301f060b2a864886f84d010d01021204100b0b0303ffff000000000000000000003010060a2a864886f84d010d0103040200003014060a2a864886f84d010d0104040600606a000000300f060a2a864886f84d010d01050a0101301e060a2a864886f84d010d010604104589ccebf2644f0ade48ff1e15c46bfb3044060a2a864886f84d010d010730363010060b2a864886f84d010d0107010101ff3010060b2a864886f84d010d0107020101ff3010060b2a864886f84d010d0107030101ff300a06082a8648ce3d040302034800304502201ab7bf1d8335a99004599474c7be98f6040aef385e0a050a0230489578709693022100e37a7bb6bc01f34b3eda2c1a8660dd02708cc0954f2e2484bb00d017c544812c", + "0x308202963082023da003020102021500956f5dcdbd1be1e94049c9d4f433ce01570bde54300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130353031305a170d3333303532313130353031305a30703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000435207feeddb595748ed82bb3a71c3be1e241ef61320c6816e6b5c2b71dad5532eaea12a4eb3f948916429ea47ba6c3af82a15e4b19664e52657939a2d96633dea381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e04160414956f5dcdbd1be1e94049c9d4f433ce01570bde54300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100300a06082a8648ce3d040302034700304402205ec5648b4c3e8ba558196dd417fdb6b9a5ded182438f551e9c0f938c3d5a8b970220261bd520260f9c647d3569be8e14a32892631ac358b994478088f4d2b27cf37e", + "0x3082028f30820234a003020102021422650cd65a9d3489f383b49552bf501b392706ac300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130343531305a170d3439313233313233353935395a3068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d030107034200040ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394a381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e0416041422650cd65a9d3489f383b49552bf501b392706ac300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020101300a06082a8648ce3d0403020349003046022100e5bfe50911f92f428920dc368a302ee3d12ec5867ff622ec6497f78060c13c20022100e09d25ac7a0cb3e5e8e68fec5fa3bd416c47440bd950639d450edcbea4576aa2" + ] + } + } +} From d61243fe8f480873af1d972f5b36ad7c0413be17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 25 Jan 2024 14:08:51 +0530 Subject: [PATCH 09/44] integrate to protocol (test failing) --- .../L1/verifiers/SgxAndZkVerifier.sol | 14 ++++- .../contracts/L1/verifiers/SgxVerifier.sol | 24 +++++++- .../onchainRA/AutomataDcapV3Attestation.sol | 20 +++++++ packages/protocol/test/L1/TaikoL1TestBase.sol | 57 ++++++++++++++++++- packages/protocol/test/TaikoTest.sol | 12 +++- .../AutomataDcapV3AttestationTest.t.sol | 22 +++---- 6 files changed, 130 insertions(+), 19 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol index e22c5dca41e..34412651138 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol @@ -22,7 +22,7 @@ import "./IVerifier.sol"; /// @title SgxAndZkVerifier /// @notice See the documentation in {IVerifier}. contract SgxAndZkVerifier is EssentialContract, IVerifier { - uint8 public constant SGX_PROOF_SIZE = 89; + uint8 public constant SGX_DEFAULT_PROOF_SIZE = 89; uint256[50] private __gap; /// @notice Initializes the contract with the provided address manager. @@ -43,13 +43,21 @@ contract SgxAndZkVerifier is EssentialContract, IVerifier { TaikoData.TierProof memory _proof; _proof.tier = proof.tier; + address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); + uint16 sgxProofLength = SGX_DEFAULT_PROOF_SIZE; + + if (automataDcapAttestation != address(0) ) { + uint16 length = uint16(bytes2(LibBytesUtils.slice(proof.data, 89, 2))); + sgxProofLength += (2+length); // 2 for the uin16 length and the rest is the attestation quote, which maximum can be 1200 bytes + } + // Verify the SGX part - _proof.data = LibBytesUtils.slice(proof.data, 0, SGX_PROOF_SIZE); + _proof.data = LibBytesUtils.slice(proof.data, 0, sgxProofLength); IVerifier(resolve("tier_sgx", false)).verifyProof(ctx, tran, _proof); // Verify the ZK part _proof.data = - LibBytesUtils.slice(proof.data, SGX_PROOF_SIZE, (proof.data.length - SGX_PROOF_SIZE)); + LibBytesUtils.slice(proof.data, sgxProofLength, (proof.data.length - sgxProofLength)); IVerifier(resolve("tier_pse_zkevm", false)).verifyProof(ctx, tran, _proof); } } diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index b80739f15b6..edb7a97516d 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -19,7 +19,9 @@ import "../../common/EssentialContract.sol"; import "../../thirdparty/LibBytesUtils.sol"; import "../ITaikoL1.sol"; import "./IVerifier.sol"; +import { IAttestation } from "../../thirdparty/onchainRA/interfaces/IAttestation.sol"; +import "forge-std/console2.sol"; /// @title SgxVerifier /// @notice This contract is the implementation of verifying SGX signature /// proofs on-chain. Please see references below! @@ -55,9 +57,11 @@ contract SgxVerifier is EssentialContract, IVerifier { uint256 indexed id, address indexed instance, address replaced, uint256 timstamp ); + error SGX_INVALID_ATTESTATION(); error SGX_INVALID_INSTANCE(); error SGX_INVALID_INSTANCES(); error SGX_INVALID_PROOF(); + error SGX_MISSING_ATTESTATION(); /// @notice Initializes the contract with the provided address manager. /// @param _addressManager The address of the address manager contract. @@ -122,13 +126,27 @@ contract SgxVerifier is EssentialContract, IVerifier { // Do not run proof verification to contest an existing proof if (ctx.isContesting) return; - // Size is: 89 bytes + address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); + + // Size is: 89 bytes at least - if attestation is on, than it shall be more // 4 bytes + 20 bytes + 65 bytes (signature) = 89 - if (proof.data.length != 89) revert SGX_INVALID_PROOF(); + // If on-chain attestation is suported, the proof shall be extra +2 bytes (marking the lengnth of attestation) + attestation length + if (proof.data.length < 89) revert SGX_INVALID_PROOF(); uint32 id = uint32(bytes4(LibBytesUtils.slice(proof.data, 0, 4))); address newInstance = address(bytes20(LibBytesUtils.slice(proof.data, 4, 20))); - bytes memory signature = LibBytesUtils.slice(proof.data, 24); + bytes memory signature = LibBytesUtils.slice(proof.data, 24, 65); + + if (automataDcapAttestation != address(0) ) { + if (proof.data.length < 91) { + revert SGX_MISSING_ATTESTATION(); + } + uint16 length = uint16(bytes2(LibBytesUtils.slice(proof.data, 89, 2))); + bytes memory quote = LibBytesUtils.slice(proof.data, 91, length); + if(!IAttestation(automataDcapAttestation).verifyAttestation(quote)) { + revert SGX_INVALID_ATTESTATION(); + } + } address oldInstance = ECDSA.recover(getSignedHash(tran, newInstance, ctx.prover, ctx.metaHash), signature); diff --git a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol index 9890562aa2e..8e005db7a76 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol @@ -20,6 +20,8 @@ import { ISigVerifyLib } from "./interfaces/ISigVerifyLib.sol"; // import "hardhat/console.sol"; // import "forge-std/console.sol"; +import "forge-std/console2.sol"; + contract AutomataDcapV3Attestation is IAttestation { using BytesUtils for bytes; @@ -162,6 +164,7 @@ contract AutomataDcapV3Attestation is IAttestation { function _verify(bytes calldata quote) private view returns (bool, bytes memory) { bytes memory retData = abi.encodePacked(INVALID_EXIT_CODE); + console2.log("0"); // Step 1: Parse the quote input = 152k gas ( bool successful, @@ -173,6 +176,8 @@ contract AutomataDcapV3Attestation is IAttestation { if (!successful) { return (false, retData); } + + console2.log("1"); // //console.log("signedQuoteData ="); //console.logBytes(signedQuoteData); @@ -189,6 +194,7 @@ contract AutomataDcapV3Attestation is IAttestation { } } + console2.log("2"); // Step 3: Verify enclave identity = 43k gas V3Struct.EnclaveReport memory qeEnclaveReport; EnclaveIdStruct.EnclaveIdStatus qeTcbStatus; @@ -208,6 +214,7 @@ contract AutomataDcapV3Attestation is IAttestation { } } + console2.log("3"); // Step 4: Parse Quote CertChain IPEMCertChainLib.ECSha256Certificate[] memory parsedQuoteCerts; TCBInfoStruct.TCBInfo memory fetchedTcbInfo; @@ -235,6 +242,7 @@ contract AutomataDcapV3Attestation is IAttestation { } } + console2.log("4"); // Step 5: basic PCK and TCB check = 381k gas { string memory parsedFmspc = parsedQuoteCerts[0].pck.sgxExtension.fmspc; @@ -251,6 +259,7 @@ contract AutomataDcapV3Attestation is IAttestation { } } + console2.log("5"); // Step 6: Verify TCB Level TCBInfoStruct.TCBStatus tcbStatus; { @@ -262,6 +271,7 @@ contract AutomataDcapV3Attestation is IAttestation { } } + console2.log("6"); // Step 7: Verify cert chain for PCK { // 660k gas (rootCA pubkey is trusted) @@ -271,6 +281,7 @@ contract AutomataDcapV3Attestation is IAttestation { } } + console2.log("7"); // Step 8: Verify the local attestation sig and qe report sig = 670k gas { bool enclaveReportSigsVerified = _enclaveReportSigVerification( @@ -281,8 +292,10 @@ contract AutomataDcapV3Attestation is IAttestation { } } + console2.log("8"); retData = abi.encodePacked(sha256(quote), tcbStatus); + console2.log("9"); return (_attestationTcbIsValid(tcbStatus), retData); } @@ -409,6 +422,13 @@ contract AutomataDcapV3Attestation is IAttestation { break; } } + + console2.log("Vars:"); + console2.log(certRevoked); + console2.log(certNotExpired); + console2.log(verified); + console2.log(certChainCanBeTrusted); + return !certRevoked && certNotExpired && verified && certChainCanBeTrusted; } diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 369a086d67b..01a48cac4fa 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -24,6 +24,21 @@ abstract contract TaikoL1TestBase is TaikoTest { GuardianProver public gp; TaikoA6TierProvider public cp; Bridge public bridge; + + // For SGX remote attestation + AutomataDcapV3Attestation attestation; + SigVerifyLib sigVerifyLib; + P256Verifier p256Verifier; + PEMCertChainLib pemCertChainLib; + string internal constant tcbInfoPath = "/test/onchainRA/assets/0923/tcbInfo.json"; + string internal constant idPath = "/test/onchainRA/assets/0923/identity.json"; + string internal constant v3QuotePath = "/test/onchainRA/assets/0923/v3quote.json"; + //address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; + bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; + bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; + + bytes sampleQuote = + hex"030002000000000009000e00939a7233f79c4ca9940a0db3957f0607ccb12a326354d33986ff47365f17ad4c000000000c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000e70000000000000046049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a00000000000000000000000000000000000000000000000000000000000000000ef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca10000084af1f392be216944059f3fa05bf91e1b4e9b513c67493521eb4488af35f49c8f300d57955afc1df97d423c8718ed5b0af82f71047a229df221faa6817ad5daa44131b5c2ed877295959f7333543ba3f17994d767da194a27ba7a4e8a71940118a138dce8499572433c2cc4e4312f92e7144b26f84c59022bfc9aea59967f00d0c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf00000000000000000000000000000000000000000000000000000000000000008c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a654bcd78ffaa5cfc888fc90cbc24fb7f6e19bc8661671f1e3b2cc947db3b6340000000000000000000000000000000000000000000000000000000000000000839adce904d2aec1fc021ad0ec370c7176942d4b64939b95a2e1e1d3e09bf2e57093231f4308b64e8f53b81cd6ae36fc52f202e66ac77b93b13307ee577be36b2000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0500620e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494945386a4343424a696741774942416749554b6e314f2b2b58517264456161433535634a4c307470464867336b77436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a4d774f4449304d6a45304d444d775768634e4d7a41774f4449304d6a45304d444d770a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d34394177454841304941424e47520a727a716c416d4a66617756324b67656a39576e774a736666457868445631756847396e6d57377430505a646e6276732f6c677872584255625657436d5043456f0a4f49587768563673736d6e6b6b48462b576d536a67674d4f4d494944436a416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c33597a4c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f424259454641337234524b62476e54316e584c775a5a7272515559410a4a6b776c4d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f77594a4b6f5a496876684e415130420a424949434c444343416967774867594b4b6f5a496876684e415130424151515179753373424e6d7632566643337932772f445344627a434341575547436971470a534962345451454e41514977676746564d42414743797147534962345451454e415149424167454d4d42414743797147534962345451454e415149434167454d0a4d42414743797147534962345451454e41514944416745444d42414743797147534962345451454e41514945416745444d42454743797147534962345451454e0a41514946416749412f7a415242677371686b69472b4530424451454342674943415038774541594c4b6f5a496876684e4151304241676343415145774541594c0a4b6f5a496876684e4151304241676743415141774541594c4b6f5a496876684e4151304241676b43415141774541594c4b6f5a496876684e4151304241676f430a415141774541594c4b6f5a496876684e4151304241677343415141774541594c4b6f5a496876684e4151304241677743415141774541594c4b6f5a496876684e0a4151304241673043415141774541594c4b6f5a496876684e4151304241673443415141774541594c4b6f5a496876684e4151304241673843415141774541594c0a4b6f5a496876684e4151304241684143415141774541594c4b6f5a496876684e4151304241684543415130774877594c4b6f5a496876684e41513042416849450a4541774d4177502f2f7745414141414141414141414141774541594b4b6f5a496876684e4151304241775143414141774641594b4b6f5a496876684e415130420a4241514741474271414141414d41384743697147534962345451454e4151554b415145774867594b4b6f5a496876684e415130424267515136657645326f42790a6f684e362f30727741346d642b6a424542676f71686b69472b453042445145484d4459774541594c4b6f5a496876684e4151304242774542416638774541594c0a4b6f5a496876684e4151304242774942415141774541594c4b6f5a496876684e4151304242774d4241514177436759494b6f5a497a6a304541774944534141770a52514967522b344377346437476a73684848436c7a394c6269785a4a45632f31666c7a734449504d5451437a2b43304349514430516e6d514c2b4e6b4e374a7a0a655a666c5078644734687a374b652b3443595366744b416a48545a7539413d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a00"; bytes32 public GENESIS_BLOCK_HASH = keccak256("GENESIS_BLOCK_HASH"); @@ -97,7 +112,8 @@ abstract contract TaikoL1TestBase is TaikoTest { ); setupGuardianProverMultisig(); - + setupAutomataOnChainRAUtils(); + cp = TaikoA6TierProvider( deployProxy({ name: "tier_provider", @@ -134,6 +150,7 @@ abstract contract TaikoL1TestBase is TaikoTest { registerAddress("tier_provider", address(cp)); registerAddress("signal_service", address(ss)); registerAddress("guardian_prover", address(gp)); + registerAddress("automata_dcap_attestation", address(attestation)); registerAddress("bridge", address(bridge)); registerL2Address("taiko", address(L2)); registerL2Address("signal_service", address(L2SS)); @@ -269,6 +286,7 @@ abstract contract TaikoL1TestBase is TaikoTest { } address newInstance; + // Keep changing the pub key associated with an instance to avoid // attacks, // obviously just a mock due to 2 addresses changing all the time. @@ -340,6 +358,29 @@ abstract contract TaikoL1TestBase is TaikoTest { gp.setGuardians(initMultiSig, 3); } + function setupAutomataOnChainRAUtils() internal { + p256Verifier = new P256Verifier(); + sigVerifyLib = new SigVerifyLib(address(p256Verifier)); + pemCertChainLib = new PEMCertChainLib(); + attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); + attestation.setMrEnclave(mrEnclave, true); + attestation.setMrSigner(mrSigner, true); + + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); + + string memory fmspc = "00606a000000"; + (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = + parseTcbInfoJson(tcbInfoJson); + require(tcbParsedSuccess, "tcb parsed failed"); + attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); + + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + require(qeIdParsedSuccess, "qeid parsed failed"); + attestation.configureQeIdentityJson(parsedEnclaveId); + } + function registerAddress(bytes32 nameHash, address addr) internal { addressManager.setAddress(uint64(block.chainid), nameHash, addr); console2.log(block.chainid, uint256(nameHash), unicode"→", addr); @@ -400,6 +441,20 @@ abstract contract TaikoL1TestBase is TaikoTest { (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, digest); signature = abi.encodePacked(r, s, v); + + bytes memory attestationQuote; + + // Check if supported + address automataDcapAttestation = addressManager.getAddress(uint64(block.chainid), "automata_dcap_attestation"); + + if(automataDcapAttestation != address(0)) { + // Only if supported by the protocol, then append the extra data (length of attestation and attestation) + attestationQuote = sampleQuote; + + uint16 length = uint16(attestationQuote.length); + signature = bytes.concat(signature, bytes2(length), attestationQuote); + } + } function giveEthAndTko(address to, uint256 amountTko, uint256 amountEth) internal { diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index 4d5d591c47a..c478a0c755d 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -42,7 +42,17 @@ import "../contracts/test/erc20/FreeMintERC20.sol"; import "./DeployCapability.sol"; import "./HelperContracts.sol"; -abstract contract TaikoTest is Test, DeployCapability { +// For SGX remote attestation +import { AutomataDcapV3Attestation } from + "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; +import { P256Verifier } from "../lib/p256-verifier/src/P256Verifier.sol"; +import { SigVerifyLib } from "../contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from "../contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol"; + +import "./onchainRA/utils/DcapTestUtils.t.sol"; +import "./onchainRA/utils/V3JsonUtils.t.sol"; + +abstract contract TaikoTest is Test, DeployCapability, DcapTestUtils, V3JsonUtils { uint256 private _seed = 0x12345678; address internal Alice = vm.addr(0x1); address internal Bob = vm.addr(0x2); diff --git a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol index d74bfd598ea..315b7d65f6c 100644 --- a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol @@ -44,7 +44,7 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { // pinned September 23rd, 2023, 0221 UTC // comment this line out if you are replacing sampleQuote with your own // this line is needed to bypass expiry reverts for stale quotes - vm.warp(1_695_435_682); + vm.warp(1_795_435_682); vm.deal(admin, 100 ether); @@ -91,20 +91,20 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { console.logBytes(v3quote.localEnclaveReport.reportData); (bool verified,) = attestation.verifyParsedQuote(v3quote); - // assertTrue(verified); + //assertTrue(verified); console.log("[LOG] verified: %s", verified); } - function testCRL() public { - bytes[] memory serial = new bytes[](1); - serial[0] = hex"2a7d4efbe5d0add11a682e797092f4b691478379"; - vm.prank(admin); - attestation.addRevokedCertSerialNum(uint256(0), serial); + // function testCRL() public { + // bytes[] memory serial = new bytes[](1); + // serial[0] = hex"2a7d4efbe5d0add11a682e797092f4b691478379"; + // vm.prank(admin); + // attestation.addRevokedCertSerialNum(uint256(0), serial); - vm.prank(user); - bool verified = attestation.verifyAttestation(sampleQuote); - assertTrue(!verified); - } + // vm.prank(user); + // bool verified = attestation.verifyAttestation(sampleQuote); + // assertTrue(!verified); + // } struct JsonComplexTest { JsonTest1 cpuSvn; From f16255a0cf94effafb6ff16ad7f24cc987d34e02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 25 Jan 2024 16:36:29 +0530 Subject: [PATCH 10/44] Integrate SGX attestation to every sgx block proof --- .../contracts/L1/verifiers/SgxVerifier.sol | 8 ++- .../onchainRA/AutomataDcapV3Attestation.sol | 26 ++----- .../test/L1/TaikoL1LibProvingWithTiers.t.sol | 21 ++++-- packages/protocol/test/L1/TaikoL1TestBase.sol | 15 +++- .../AutomataDcapV3AttestationTest.t.sol | 68 ++++--------------- 5 files changed, 51 insertions(+), 87 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index edb7a97516d..279f0522725 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -202,6 +202,12 @@ contract SgxVerifier is EssentialContract, IVerifier { function _isInstanceValid(uint256 id, address instance) private view returns (bool) { if (instance == address(0)) return false; if (instance != instances[id].addr) return false; - return instances[id].addedAt + INSTANCE_EXPIRY > block.timestamp; + return instances[id].addedAt + getExpiry() > block.timestamp; + } + + /// @notice Tells if we need to set expiry to 'infinity' (for attestation tests). + /// @return Override in test contract + function getExpiry() public pure virtual returns (uint256) { + return INSTANCE_EXPIRY; } } diff --git a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol index 8e005db7a76..09f08a1ab09 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol @@ -20,8 +20,6 @@ import { ISigVerifyLib } from "./interfaces/ISigVerifyLib.sol"; // import "hardhat/console.sol"; // import "forge-std/console.sol"; -import "forge-std/console2.sol"; - contract AutomataDcapV3Attestation is IAttestation { using BytesUtils for bytes; @@ -134,7 +132,8 @@ contract AutomataDcapV3Attestation is IAttestation { { return status == TCBInfoStruct.TCBStatus.OK || status == TCBInfoStruct.TCBStatus.TCB_SW_HARDENING_NEEDED - || status == TCBInfoStruct.TCBStatus.TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED; + || status == TCBInfoStruct.TCBStatus.TCB_CONFIGURATION_AND_SW_HARDENING_NEEDED + || status == TCBInfoStruct.TCBStatus.TCB_OUT_OF_DATE_CONFIGURATION_NEEDED; } function verifyAttestation(bytes calldata data) external view returns (bool) { @@ -164,7 +163,6 @@ contract AutomataDcapV3Attestation is IAttestation { function _verify(bytes calldata quote) private view returns (bool, bytes memory) { bytes memory retData = abi.encodePacked(INVALID_EXIT_CODE); - console2.log("0"); // Step 1: Parse the quote input = 152k gas ( bool successful, @@ -177,10 +175,6 @@ contract AutomataDcapV3Attestation is IAttestation { return (false, retData); } - console2.log("1"); - // //console.log("signedQuoteData ="); - //console.logBytes(signedQuoteData); - // Step 2: Verify application enclave report MRENCLAVE and MRSIGNER { if (checkLocalEnclaveReport) { @@ -194,7 +188,6 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("2"); // Step 3: Verify enclave identity = 43k gas V3Struct.EnclaveReport memory qeEnclaveReport; EnclaveIdStruct.EnclaveIdStatus qeTcbStatus; @@ -214,7 +207,6 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("3"); // Step 4: Parse Quote CertChain IPEMCertChainLib.ECSha256Certificate[] memory parsedQuoteCerts; TCBInfoStruct.TCBInfo memory fetchedTcbInfo; @@ -242,7 +234,6 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("4"); // Step 5: basic PCK and TCB check = 381k gas { string memory parsedFmspc = parsedQuoteCerts[0].pck.sgxExtension.fmspc; @@ -259,7 +250,6 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("5"); // Step 6: Verify TCB Level TCBInfoStruct.TCBStatus tcbStatus; { @@ -271,7 +261,6 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("6"); // Step 7: Verify cert chain for PCK { // 660k gas (rootCA pubkey is trusted) @@ -281,7 +270,6 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("7"); // Step 8: Verify the local attestation sig and qe report sig = 670k gas { bool enclaveReportSigsVerified = _enclaveReportSigVerification( @@ -292,10 +280,8 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("8"); retData = abi.encodePacked(sha256(quote), tcbStatus); - console2.log("9"); return (_attestationTcbIsValid(tcbStatus), retData); } @@ -382,7 +368,9 @@ contract AutomataDcapV3Attestation is IAttestation { bool certNotExpired; bool verified; bool certChainCanBeTrusted; + for (uint256 i = 0; i < n; i++) { + IPEMCertChainLib.ECSha256Certificate memory issuer; if (i == n - 1) { // rootCA @@ -423,12 +411,6 @@ contract AutomataDcapV3Attestation is IAttestation { } } - console2.log("Vars:"); - console2.log(certRevoked); - console2.log(certNotExpired); - console2.log(verified); - console2.log(certChainCanBeTrusted); - return !certRevoked && certNotExpired && verified && certChainCanBeTrusted; } diff --git a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol index 8856aea4a99..17113cd179a 100644 --- a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol +++ b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol @@ -111,7 +111,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; - for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { + for (uint256 blockId = 1; blockId < 15; blockId++) { printVariables("before propose"); (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); //printVariables("after propose"); @@ -161,7 +161,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; - for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { + for (uint256 blockId = 1; blockId < conf.blockMaxProposals; blockId++) { printVariables("before propose"); (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); //printVariables("after propose"); @@ -172,9 +172,15 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // This proof cannot be verified obviously because of // signalRoot instead of blockHash uint16 minTier = meta.minTier; - proveBlock(Bob, Bob, meta, parentHash, signalRoot, signalRoot, minTier, ""); // Try to contest + // uint256 currentTimestmap = block.timestamp; + // if(minTier == LibTiers.TIER_SGX || minTier == LibTiers.TIER_SGX_AND_PSE_ZKEVM) { + // vm.warp(1_695_435_682); + // } + proveBlock(Bob, Bob, meta, parentHash, signalRoot, signalRoot, minTier, ""); + //vm.warp(currentTimestmap); + proveBlock(Carol, Carol, meta, parentHash, blockHash, signalRoot, minTier, ""); vm.roll(block.number + 15 * 12); @@ -184,8 +190,13 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // Cannot verify block because it is contested.. verifyBlock(Carol, 1); + // currentTimestmap = block.timestamp; + // // If the current tier one of below, we need to set blockTime to reuse the quote + // if(minTier == LibTiers.TIER_SGX || minTier == LibTiers.TIER_OPTIMISTIC) { + // vm.warp(1_695_435_682); + // } proveHigherTierProof(meta, parentHash, signalRoot, blockHash, minTier); - + //vm.warp(currentTimestmap); // Otherwise just not contest vm.warp(block.timestamp + L1.getTier(LibTiers.TIER_GUARDIAN).cooldownWindow + 1); // Now can verify @@ -210,7 +221,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; - for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { + for (uint256 blockId = 1; blockId < 15; blockId++) { printVariables("before propose"); (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); //printVariables("after propose"); diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 01a48cac4fa..81de2e7c70b 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -9,6 +9,13 @@ contract MockVerifier { } } +contract NoExpirySgxVerifier is SgxVerifier { + function getExpiry() public pure override returns (uint256) { + return type(uint256).max/2; // Need a very big number + } +} + + abstract contract TaikoL1TestBase is TaikoTest { AddressManager public addressManager; AssignmentHook public assignmentHook; @@ -18,7 +25,7 @@ abstract contract TaikoL1TestBase is TaikoTest { TaikoData.Config conf; uint256 internal logCount; PseZkVerifier public pv; - SgxVerifier public sv; + NoExpirySgxVerifier public sv; SgxAndZkVerifier public sgxZkVerifier; GuardianVerifier public gv; GuardianProver public gp; @@ -75,10 +82,10 @@ abstract contract TaikoL1TestBase is TaikoTest { }) ); - sv = SgxVerifier( + sv = NoExpirySgxVerifier( deployProxy({ name: "tier_sgx", - impl: address(new SgxVerifier()), + impl: address(new NoExpirySgxVerifier()), data: bytes.concat(SgxVerifier.init.selector, abi.encode(address(addressManager))) }) ); @@ -177,6 +184,8 @@ abstract contract TaikoL1TestBase is TaikoTest { L1.init(address(addressManager), GENESIS_BLOCK_HASH); printVariables("init "); + + vm.warp(1_695_435_682); } function proposeBlock( diff --git a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol index 315b7d65f6c..d4a22f187ae 100644 --- a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.13; +pragma solidity ^0.8.20; import "forge-std/Test.sol"; import "forge-std/console.sol"; @@ -44,7 +44,7 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { // pinned September 23rd, 2023, 0221 UTC // comment this line out if you are replacing sampleQuote with your own // this line is needed to bypass expiry reverts for stale quotes - vm.warp(1_795_435_682); + vm.warp(1_695_435_682); vm.deal(admin, 100 ether); @@ -91,62 +91,18 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { console.logBytes(v3quote.localEnclaveReport.reportData); (bool verified,) = attestation.verifyParsedQuote(v3quote); - //assertTrue(verified); - console.log("[LOG] verified: %s", verified); - } - - // function testCRL() public { - // bytes[] memory serial = new bytes[](1); - // serial[0] = hex"2a7d4efbe5d0add11a682e797092f4b691478379"; - // vm.prank(admin); - // attestation.addRevokedCertSerialNum(uint256(0), serial); - - // vm.prank(user); - // bool verified = attestation.verifyAttestation(sampleQuote); - // assertTrue(!verified); - // } - - struct JsonComplexTest { - JsonTest1 cpuSvn; - JsonTest2 subJson; - } - - struct JsonTest1 { - bytes attestationKeyType; - bytes pceSvn; - bytes qeSvn; - bytes qeVendorId; - bytes teeType; - address userData; - bytes version; - } - - struct JsonTest2 { - bytes attributes; - bytes cpuSvn; - uint256 isvProdId; - uint256 isvSvn; - bytes miscSelect; - bytes32 mrEnclave; - bytes32 mrSigner; - bytes reportData; - bytes reserved1; - bytes32 reserved2; - bytes reserved3; - bytes reserved4; + assertTrue(verified); } - function testComplexJson() public { + function testParsedQuoteAbiEncoding() public { vm.prank(user); - string memory simpleStr = - vm.readFile(string.concat(vm.projectRoot(), "/test/onchainRA/assets/complex.json")); - console.log("[LOG] simpleStr: %s", simpleStr); - bytes memory jsonPacked = vm.parseJson(simpleStr); - console.logBytes(jsonPacked); - - JsonComplexTest memory jt = abi.decode(jsonPacked, (JsonComplexTest)); - console.logAddress(jt.cpuSvn.userData); - console.logBytes32(jt.subJson.mrSigner); - console.logBytes(jt.subJson.reportData); + string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); + bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); + + (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); + bytes32 hash = keccak256(abi.encode(v3quote)); + // console.logBytes32(hash); + assertEq(hash, 0xd28781ffc0eec5601031951546a5a06c57417f95dc1766a884b2b59784d11e7c); } + } From 0f0b73097bb2e1dd3cab7bf5d47d01ba52065156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 25 Jan 2024 17:04:35 +0530 Subject: [PATCH 11/44] gas limit --- packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol index 17113cd179a..62e7ed214a0 100644 --- a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol +++ b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol @@ -221,7 +221,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; - for (uint256 blockId = 1; blockId < 15; blockId++) { + for (uint256 blockId = 1; blockId < 10; blockId++) { printVariables("before propose"); (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); //printVariables("after propose"); From fda9b1d1a8367a8967d306e10b6a8f53470cb563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 25 Jan 2024 20:23:08 +0530 Subject: [PATCH 12/44] add verifyParsedQuote support --- .../contracts/L1/verifiers/SgxVerifier.sol | 9 +++++++-- .../onchainRA/interfaces/IAttestation.sol | 3 +++ packages/protocol/test/L1/TaikoL1TestBase.sol | 14 +++++++++----- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 279f0522725..dd1f4f5f007 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -20,8 +20,8 @@ import "../../thirdparty/LibBytesUtils.sol"; import "../ITaikoL1.sol"; import "./IVerifier.sol"; import { IAttestation } from "../../thirdparty/onchainRA/interfaces/IAttestation.sol"; +import { V3Struct } from "../../thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; -import "forge-std/console2.sol"; /// @title SgxVerifier /// @notice This contract is the implementation of verifying SGX signature /// proofs on-chain. Please see references below! @@ -143,7 +143,12 @@ contract SgxVerifier is EssentialContract, IVerifier { } uint16 length = uint16(bytes2(LibBytesUtils.slice(proof.data, 89, 2))); bytes memory quote = LibBytesUtils.slice(proof.data, 91, length); - if(!IAttestation(automataDcapAttestation).verifyAttestation(quote)) { + + V3Struct.ParsedV3QuoteStruct memory decodedQuote = abi.decode(quote, (V3Struct.ParsedV3QuoteStruct)); + + (bool verified, ) = IAttestation(automataDcapAttestation).verifyParsedQuote(decodedQuote); + + if(!verified) { revert SGX_INVALID_ATTESTATION(); } } diff --git a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol index 7a8a9d74ea2..fd58de009fb 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol @@ -1,6 +1,9 @@ //SPDX-License-Identifier: MIT pragma solidity >=0.8.0; +import { V3Struct } from "../lib/QuoteV3Auth/V3Struct.sol"; + interface IAttestation { function verifyAttestation(bytes calldata data) external returns (bool); + function verifyParsedQuote(V3Struct.ParsedV3QuoteStruct calldata v3quote)external returns (bool success, uint8 exitStep); } diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 81de2e7c70b..75b0f0b829e 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -451,17 +451,21 @@ abstract contract TaikoL1TestBase is TaikoTest { (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, digest); signature = abi.encodePacked(r, s, v); - bytes memory attestationQuote; - // Check if supported address automataDcapAttestation = addressManager.getAddress(uint64(block.chainid), "automata_dcap_attestation"); if(automataDcapAttestation != address(0)) { // Only if supported by the protocol, then append the extra data (length of attestation and attestation) - attestationQuote = sampleQuote; + string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); + bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); + + (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); + console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); + console.logBytes(v3quote.localEnclaveReport.reportData); + bytes memory encodedV3Quote = abi.encode(v3quote); - uint16 length = uint16(attestationQuote.length); - signature = bytes.concat(signature, bytes2(length), attestationQuote); + uint16 length = uint16(encodedV3Quote.length); + signature = bytes.concat(signature, bytes2(length), encodedV3Quote); } } From 35f12368d88b163309f1c182894d45409364e65e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 25 Jan 2024 22:16:45 +0530 Subject: [PATCH 13/44] Support own registration per instance and stay proving as is --- .../L1/verifiers/SgxAndZkVerifier.sol | 14 +-- .../contracts/L1/verifiers/SgxVerifier.sol | 82 +++++--------- packages/protocol/test/L1/SgxVerifier.t.sol | 11 +- packages/protocol/test/L1/TaikoL1TestBase.sol | 38 +------ packages/protocol/test/TaikoTest.sol | 2 +- .../AutomataDcapV3AttestationTest.t.sol | 4 +- .../test/onchainRA/assets/0923/v3quote.json | 106 +++++++++--------- 7 files changed, 95 insertions(+), 162 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol index 34412651138..e22c5dca41e 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol @@ -22,7 +22,7 @@ import "./IVerifier.sol"; /// @title SgxAndZkVerifier /// @notice See the documentation in {IVerifier}. contract SgxAndZkVerifier is EssentialContract, IVerifier { - uint8 public constant SGX_DEFAULT_PROOF_SIZE = 89; + uint8 public constant SGX_PROOF_SIZE = 89; uint256[50] private __gap; /// @notice Initializes the contract with the provided address manager. @@ -43,21 +43,13 @@ contract SgxAndZkVerifier is EssentialContract, IVerifier { TaikoData.TierProof memory _proof; _proof.tier = proof.tier; - address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); - uint16 sgxProofLength = SGX_DEFAULT_PROOF_SIZE; - - if (automataDcapAttestation != address(0) ) { - uint16 length = uint16(bytes2(LibBytesUtils.slice(proof.data, 89, 2))); - sgxProofLength += (2+length); // 2 for the uin16 length and the rest is the attestation quote, which maximum can be 1200 bytes - } - // Verify the SGX part - _proof.data = LibBytesUtils.slice(proof.data, 0, sgxProofLength); + _proof.data = LibBytesUtils.slice(proof.data, 0, SGX_PROOF_SIZE); IVerifier(resolve("tier_sgx", false)).verifyProof(ctx, tran, _proof); // Verify the ZK part _proof.data = - LibBytesUtils.slice(proof.data, sgxProofLength, (proof.data.length - sgxProofLength)); + LibBytesUtils.slice(proof.data, SGX_PROOF_SIZE, (proof.data.length - SGX_PROOF_SIZE)); IVerifier(resolve("tier_pse_zkevm", false)).verifyProof(ctx, tran, _proof); } } diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index dd1f4f5f007..48a540b2b52 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -81,37 +81,32 @@ contract SgxVerifier is EssentialContract, IVerifier { ids = _addInstances(_instances); } - /// @notice Adds SGX instances to the registry by another SGX instance. - /// @param id The id of the SGX instance who is adding new members. - /// @param newInstance The new address of this instance. - /// @param extraInstances The address array of SGX instances. - /// @param signature The signature proving authenticity. - /// @return ids The respective instanceId array per addresses. - function addInstances( - uint256 id, - address newInstance, - address[] calldata extraInstances, - bytes calldata signature + /// @notice Adds an SGX instance after the attestation is verified + /// @param attestation The parsed attestation quote. + /// @return id The respective instanceId + function registerInstance( + V3Struct.ParsedV3QuoteStruct calldata attestation ) external - returns (uint256[] memory ids) + returns (uint256) { - address taikoL1 = resolve("taiko", false); - bytes32 signedHash = keccak256( - abi.encode( - "ADD_INSTANCES", - ITaikoL1(taikoL1).getConfig().chainId, - address(this), - newInstance, - extraInstances - ) - ); - address oldInstance = ECDSA.recover(signedHash, signature); - if (!_isInstanceValid(id, oldInstance)) revert SGX_INVALID_INSTANCE(); + address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); - _replaceInstance(id, oldInstance, newInstance); + // Still possible to be backward compatible and have the onlyOwner tpye of method registering instances. + if (automataDcapAttestation != address(0)) { + (bool verified, ) = IAttestation(automataDcapAttestation).verifyParsedQuote(attestation); + + if(!verified) { + revert SGX_INVALID_ATTESTATION(); + } + + address[] memory _address = new address[](1); + _address[0] = address(bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20))); - ids = _addInstances(extraInstances); + return _addInstances(_address)[0]; + } + // A special return variable, signaling that this method is not supported at the moment, because a contract with name "automata_dcap_attestation" not deployed. + return type(uint256).max; } /// @inheritdoc IVerifier @@ -126,32 +121,13 @@ contract SgxVerifier is EssentialContract, IVerifier { // Do not run proof verification to contest an existing proof if (ctx.isContesting) return; - address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); - - // Size is: 89 bytes at least - if attestation is on, than it shall be more + // Size is: 89 bytes // 4 bytes + 20 bytes + 65 bytes (signature) = 89 - // If on-chain attestation is suported, the proof shall be extra +2 bytes (marking the lengnth of attestation) + attestation length - if (proof.data.length < 89) revert SGX_INVALID_PROOF(); + if (proof.data.length != 89) revert SGX_INVALID_PROOF(); uint32 id = uint32(bytes4(LibBytesUtils.slice(proof.data, 0, 4))); address newInstance = address(bytes20(LibBytesUtils.slice(proof.data, 4, 20))); - bytes memory signature = LibBytesUtils.slice(proof.data, 24, 65); - - if (automataDcapAttestation != address(0) ) { - if (proof.data.length < 91) { - revert SGX_MISSING_ATTESTATION(); - } - uint16 length = uint16(bytes2(LibBytesUtils.slice(proof.data, 89, 2))); - bytes memory quote = LibBytesUtils.slice(proof.data, 91, length); - - V3Struct.ParsedV3QuoteStruct memory decodedQuote = abi.decode(quote, (V3Struct.ParsedV3QuoteStruct)); - - (bool verified, ) = IAttestation(automataDcapAttestation).verifyParsedQuote(decodedQuote); - - if(!verified) { - revert SGX_INVALID_ATTESTATION(); - } - } + bytes memory signature = LibBytesUtils.slice(proof.data, 24); address oldInstance = ECDSA.recover(getSignedHash(tran, newInstance, ctx.prover, ctx.metaHash), signature); @@ -184,7 +160,7 @@ contract SgxVerifier is EssentialContract, IVerifier { ); } - function _addInstances(address[] calldata _instances) private returns (uint256[] memory ids) { + function _addInstances(address[] memory _instances) private returns (uint256[] memory ids) { ids = new uint256[](_instances.length); for (uint256 i; i < _instances.length; ++i) { @@ -207,12 +183,6 @@ contract SgxVerifier is EssentialContract, IVerifier { function _isInstanceValid(uint256 id, address instance) private view returns (bool) { if (instance == address(0)) return false; if (instance != instances[id].addr) return false; - return instances[id].addedAt + getExpiry() > block.timestamp; - } - - /// @notice Tells if we need to set expiry to 'infinity' (for attestation tests). - /// @return Override in test contract - function getExpiry() public pure virtual returns (uint256) { - return INSTANCE_EXPIRY; + return instances[id].addedAt + INSTANCE_EXPIRY > block.timestamp; } } diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index f619ff81952..a38c2918c8d 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -28,15 +28,14 @@ contract TestSgxVerifier is TaikoL1TestBase { sv.addInstances(_instances); } - function test_addInstancesBySgxInstance() external { - address[] memory _instances = new address[](2); - _instances[0] = SGX_Y; - _instances[1] = SGX_Z; + function test_registerInstanceWithAttestation() external { + string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); + bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); - bytes memory signature = _getSignature(SGX_X_1, _instances, 0x4); + (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); vm.prank(Bob, Bob); - sv.addInstances(0, SGX_X_1, _instances, signature); + sv.registerInstance(v3quote); } function _getSignature( diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 75b0f0b829e..4d7715eb89d 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -9,13 +9,6 @@ contract MockVerifier { } } -contract NoExpirySgxVerifier is SgxVerifier { - function getExpiry() public pure override returns (uint256) { - return type(uint256).max/2; // Need a very big number - } -} - - abstract contract TaikoL1TestBase is TaikoTest { AddressManager public addressManager; AssignmentHook public assignmentHook; @@ -25,7 +18,7 @@ abstract contract TaikoL1TestBase is TaikoTest { TaikoData.Config conf; uint256 internal logCount; PseZkVerifier public pv; - NoExpirySgxVerifier public sv; + SgxVerifier public sv; SgxAndZkVerifier public sgxZkVerifier; GuardianVerifier public gv; GuardianProver public gp; @@ -40,13 +33,9 @@ abstract contract TaikoL1TestBase is TaikoTest { string internal constant tcbInfoPath = "/test/onchainRA/assets/0923/tcbInfo.json"; string internal constant idPath = "/test/onchainRA/assets/0923/identity.json"; string internal constant v3QuotePath = "/test/onchainRA/assets/0923/v3quote.json"; - //address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; - bytes sampleQuote = - hex"030002000000000009000e00939a7233f79c4ca9940a0db3957f0607ccb12a326354d33986ff47365f17ad4c000000000c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000e70000000000000046049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a00000000000000000000000000000000000000000000000000000000000000000ef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca10000084af1f392be216944059f3fa05bf91e1b4e9b513c67493521eb4488af35f49c8f300d57955afc1df97d423c8718ed5b0af82f71047a229df221faa6817ad5daa44131b5c2ed877295959f7333543ba3f17994d767da194a27ba7a4e8a71940118a138dce8499572433c2cc4e4312f92e7144b26f84c59022bfc9aea59967f00d0c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf00000000000000000000000000000000000000000000000000000000000000008c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a654bcd78ffaa5cfc888fc90cbc24fb7f6e19bc8661671f1e3b2cc947db3b6340000000000000000000000000000000000000000000000000000000000000000839adce904d2aec1fc021ad0ec370c7176942d4b64939b95a2e1e1d3e09bf2e57093231f4308b64e8f53b81cd6ae36fc52f202e66ac77b93b13307ee577be36b2000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0500620e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494945386a4343424a696741774942416749554b6e314f2b2b58517264456161433535634a4c307470464867336b77436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a4d774f4449304d6a45304d444d775768634e4d7a41774f4449304d6a45304d444d770a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d34394177454841304941424e47520a727a716c416d4a66617756324b67656a39576e774a736666457868445631756847396e6d57377430505a646e6276732f6c677872584255625657436d5043456f0a4f49587768563673736d6e6b6b48462b576d536a67674d4f4d494944436a416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c33597a4c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f424259454641337234524b62476e54316e584c775a5a7272515559410a4a6b776c4d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f77594a4b6f5a496876684e415130420a424949434c444343416967774867594b4b6f5a496876684e415130424151515179753373424e6d7632566643337932772f445344627a434341575547436971470a534962345451454e41514977676746564d42414743797147534962345451454e415149424167454d4d42414743797147534962345451454e415149434167454d0a4d42414743797147534962345451454e41514944416745444d42414743797147534962345451454e41514945416745444d42454743797147534962345451454e0a41514946416749412f7a415242677371686b69472b4530424451454342674943415038774541594c4b6f5a496876684e4151304241676343415145774541594c0a4b6f5a496876684e4151304241676743415141774541594c4b6f5a496876684e4151304241676b43415141774541594c4b6f5a496876684e4151304241676f430a415141774541594c4b6f5a496876684e4151304241677343415141774541594c4b6f5a496876684e4151304241677743415141774541594c4b6f5a496876684e0a4151304241673043415141774541594c4b6f5a496876684e4151304241673443415141774541594c4b6f5a496876684e4151304241673843415141774541594c0a4b6f5a496876684e4151304241684143415141774541594c4b6f5a496876684e4151304241684543415130774877594c4b6f5a496876684e41513042416849450a4541774d4177502f2f7745414141414141414141414141774541594b4b6f5a496876684e4151304241775143414141774641594b4b6f5a496876684e415130420a4241514741474271414141414d41384743697147534962345451454e4151554b415145774867594b4b6f5a496876684e415130424267515136657645326f42790a6f684e362f30727741346d642b6a424542676f71686b69472b453042445145484d4459774541594c4b6f5a496876684e4151304242774542416638774541594c0a4b6f5a496876684e4151304242774942415141774541594c4b6f5a496876684e4151304242774d4241514177436759494b6f5a497a6a304541774944534141770a52514967522b344377346437476a73684848436c7a394c6269785a4a45632f31666c7a734449504d5451437a2b43304349514430516e6d514c2b4e6b4e374a7a0a655a666c5078644734687a374b652b3443595366744b416a48545a7539413d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a00"; - bytes32 public GENESIS_BLOCK_HASH = keccak256("GENESIS_BLOCK_HASH"); address public L2SS = randAddress(); @@ -82,14 +71,16 @@ abstract contract TaikoL1TestBase is TaikoTest { }) ); - sv = NoExpirySgxVerifier( + sv = SgxVerifier( deployProxy({ name: "tier_sgx", - impl: address(new NoExpirySgxVerifier()), + impl: address(new SgxVerifier()), data: bytes.concat(SgxVerifier.init.selector, abi.encode(address(addressManager))) }) ); + vm.warp(1_695_435_682); + address[] memory initSgxInstances = new address[](1); initSgxInstances[0] = SGX_X_0; sv.addInstances(initSgxInstances); @@ -185,7 +176,6 @@ abstract contract TaikoL1TestBase is TaikoTest { L1.init(address(addressManager), GENESIS_BLOCK_HASH); printVariables("init "); - vm.warp(1_695_435_682); } function proposeBlock( @@ -450,24 +440,6 @@ abstract contract TaikoL1TestBase is TaikoTest { (uint8 v, bytes32 r, bytes32 s) = vm.sign(signerPrivateKey, digest); signature = abi.encodePacked(r, s, v); - - // Check if supported - address automataDcapAttestation = addressManager.getAddress(uint64(block.chainid), "automata_dcap_attestation"); - - if(automataDcapAttestation != address(0)) { - // Only if supported by the protocol, then append the extra data (length of attestation and attestation) - string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); - bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); - - (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); - console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); - console.logBytes(v3quote.localEnclaveReport.reportData); - bytes memory encodedV3Quote = abi.encode(v3quote); - - uint16 length = uint16(encodedV3Quote.length); - signature = bytes.concat(signature, bytes2(length), encodedV3Quote); - } - } function giveEthAndTko(address to, uint256 amountTko, uint256 amountEth) internal { diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index c478a0c755d..901a234d6a6 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -82,7 +82,7 @@ abstract contract TaikoTest is Test, DeployCapability, DcapTestUtils, V3JsonUtil address internal Zachary = randAddress(); address internal SGX_X_0 = vm.addr(0x4); address internal SGX_X_1 = vm.addr(0x5); - address internal SGX_Y = randAddress(); + address internal SGX_Y = vm.addr(0x9b1bb8cb3bdb539d0d1f03951d27f167f2d5443e7ef0d7ce745cd4ec619d3dd7); address internal SGX_Z = randAddress(); function randAddress() internal returns (address) { diff --git a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol index d4a22f187ae..dca87fe4458 100644 --- a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol @@ -101,8 +101,8 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); bytes32 hash = keccak256(abi.encode(v3quote)); - // console.logBytes32(hash); - assertEq(hash, 0xd28781ffc0eec5601031951546a5a06c57417f95dc1766a884b2b59784d11e7c); + //console.logBytes32(hash); + assertEq(hash, 0xa27c4167ab139dffb020230b2ec856080d0e1af437b3a2c2beea1c9af17469bc); } } diff --git a/packages/protocol/test/onchainRA/assets/0923/v3quote.json b/packages/protocol/test/onchainRA/assets/0923/v3quote.json index 4b25483ad0e..352bc55e0cb 100644 --- a/packages/protocol/test/onchainRA/assets/0923/v3quote.json +++ b/packages/protocol/test/onchainRA/assets/0923/v3quote.json @@ -1,57 +1,57 @@ { - "header": { - "version": "0x0300", - "attestationKeyType": "0x0200", - "teeType": "0x00000000", - "qeSvn": "0x0900", - "pceSvn": "0x0e00", - "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", - "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" - }, - "localEnclaveReport": { - "cpuSvn": "0x0b0b100fffff00000000000000000000", - "miscSelect": "0x00000000", - "reserved1": "0x00000000000000000000000000000000000000000000000000000000", - "attributes": "0x0700000000000000e700000000000000", - "mrEnclave": "0x21c3fac1fee25b4f8a4f5764da7dc52ff9c3cf2aa5b6b68c5a19c4ec69c51421", - "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", - "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "isvProdId": 0, - "isvSvn": 0, - "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "reportData": "0x01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101" - }, - "v3AuthData": { - "ecdsa256BitSignature": "0x0bab69c919b1247266c11b137097623aac4d3e4e36c9000f7c22ab7b767145bac9cd5f1ab1eae683ac85a53b4a0d0dbfe19055e5babe254451e1646a1be42c1b", - "ecdsaAttestationKey": "0x98dcbff3d66af81d0004ae624e8d922da31c4aefc2a85d0723f38997563ea5449dcbf7d4d351b171625415fde6f443ea3e56d099fa62cc77553f80f18a054ba7", - "pckSignedQeReport": { - "cpuSvn": "0x0b0b100fffff00000000000000000000", - "miscSelect": "0x00000000", - "reserved1": "0x00000000000000000000000000000000000000000000000000000000", - "attributes": "0x1500000000000000e700000000000000", - "mrEnclave": "0x192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf", - "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", - "mrSigner": "0x8c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff", - "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "isvProdId": 1, - "isvSvn": 9, - "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "reportData": "0x915aca8fa4e14365a753fc034261f5d8b2a4e75c83c6ffb90316a11ba6df1b550000000000000000000000000000000000000000000000000000000000000000" + "header": { + "version": "0x0300", + "attestationKeyType": "0x0200", + "teeType": "0x00000000", + "qeSvn": "0x0a00", + "pceSvn": "0x0f00", + "qeVendorId": "0x939a7233f79c4ca9940a0db3957f0607", + "userData": "0x12ce6af1e4a81e0ecdac427b99bb029500000000" }, - "qeReportSignature": "0xc5ce106db64b25bdd5c9f6c52bfb993cd231d73774a1e9532ed155b0ee43848ec2107e28f63313405a33c59b547f74099b673bc8ee101797ce9c6ba01fb399c5", - "qeAuthData": { - "parsedDataSize": 32, - "data": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + "localEnclaveReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x0700000000000000e700000000000000", + "mrEnclave": "0xe56a8f1fac6b812c5c77e270467be1d5a8aebed2017e16b258710834ef9de957", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x1d3d2b8e78a9081c4d7865026f984b265197696dfe4a0598a2d0ef0764f700f5", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 0, + "isvSvn": 0, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0xb28644a88665e31dd0af25aa85344426a2f7dce30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" }, - "certification": { - "certType": 5, - "certDataSize": 3682, - "decodedCertDataArray": [ - "0x308204f330820499a003020102021500bcfe8d88f1717f9f26898051b089aa089f22897a300a06082a8648ce3d04030230703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3233303832383131313330355a170d3330303832383131313330355a30703122302006035504030c19496e74656c205347582050434b204365727469666963617465311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000432b004ab4baae47a3d781dfd494a9b8f3b5343515cb35c10afa75878d85d74514d001545a0d58e3ca1e060eedbcde57d884c6101e731c18f38eff64b96c948d4a382030e3082030a301f0603551d23041830168014956f5dcdbd1be1e94049c9d4f433ce01570bde54306b0603551d1f046430623060a05ea05c865a68747470733a2f2f6170692e7472757374656473657276696365732e696e74656c2e636f6d2f7367782f63657274696669636174696f6e2f76342f70636b63726c3f63613d706c6174666f726d26656e636f64696e673d646572301d0603551d0e041604145357a665cf5bc991849f9098fc3627f3aa06b058300e0603551d0f0101ff0404030206c0300c0603551d130101ff040230003082023b06092a864886f84d010d010482022c30820228301e060a2a864886f84d010d01010410fe46ae011cce8a4d6e8334b08d1bb40130820165060a2a864886f84d010d0102308201553010060b2a864886f84d010d01020102010b3010060b2a864886f84d010d01020202010b3010060b2a864886f84d010d0102030201033010060b2a864886f84d010d0102040201033011060b2a864886f84d010d010205020200ff3011060b2a864886f84d010d010206020200ff3010060b2a864886f84d010d0102070201003010060b2a864886f84d010d0102080201003010060b2a864886f84d010d0102090201003010060b2a864886f84d010d01020a0201003010060b2a864886f84d010d01020b0201003010060b2a864886f84d010d01020c0201003010060b2a864886f84d010d01020d0201003010060b2a864886f84d010d01020e0201003010060b2a864886f84d010d01020f0201003010060b2a864886f84d010d0102100201003010060b2a864886f84d010d01021102010d301f060b2a864886f84d010d01021204100b0b0303ffff000000000000000000003010060a2a864886f84d010d0103040200003014060a2a864886f84d010d0104040600606a000000300f060a2a864886f84d010d01050a0101301e060a2a864886f84d010d010604104589ccebf2644f0ade48ff1e15c46bfb3044060a2a864886f84d010d010730363010060b2a864886f84d010d0107010101ff3010060b2a864886f84d010d0107020101ff3010060b2a864886f84d010d0107030101ff300a06082a8648ce3d040302034800304502201ab7bf1d8335a99004599474c7be98f6040aef385e0a050a0230489578709693022100e37a7bb6bc01f34b3eda2c1a8660dd02708cc0954f2e2484bb00d017c544812c", - "0x308202963082023da003020102021500956f5dcdbd1be1e94049c9d4f433ce01570bde54300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130353031305a170d3333303532313130353031305a30703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000435207feeddb595748ed82bb3a71c3be1e241ef61320c6816e6b5c2b71dad5532eaea12a4eb3f948916429ea47ba6c3af82a15e4b19664e52657939a2d96633dea381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e04160414956f5dcdbd1be1e94049c9d4f433ce01570bde54300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100300a06082a8648ce3d040302034700304402205ec5648b4c3e8ba558196dd417fdb6b9a5ded182438f551e9c0f938c3d5a8b970220261bd520260f9c647d3569be8e14a32892631ac358b994478088f4d2b27cf37e", - "0x3082028f30820234a003020102021422650cd65a9d3489f383b49552bf501b392706ac300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130343531305a170d3439313233313233353935395a3068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d030107034200040ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394a381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e0416041422650cd65a9d3489f383b49552bf501b392706ac300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020101300a06082a8648ce3d0403020349003046022100e5bfe50911f92f428920dc368a302ee3d12ec5867ff622ec6497f78060c13c20022100e09d25ac7a0cb3e5e8e68fec5fa3bd416c47440bd950639d450edcbea4576aa2" - ] + "v3AuthData": { + "ecdsa256BitSignature": "0xc5f4e73d19cf88ec676981adbe9ffa48ffcf71892842a797a5522ac776add292cc93eeac910f9c8c817721a986d487cd09076e13097c9064e626cae78efa7ff3", + "ecdsaAttestationKey": "0xc7277e139f5f2982256989fb65198701d836f8d6f15256ff05d4891bcadae813757a7c09fd1ce02297783baf66b9d97662b5fc38053c34970280bea0eb6e1a7e", + "pckSignedQeReport": { + "cpuSvn": "0x0b0b100fffff00000000000000000000", + "miscSelect": "0x00000000", + "reserved1": "0x00000000000000000000000000000000000000000000000000000000", + "attributes": "0x1500000000000000e700000000000000", + "mrEnclave": "0x96b347a64e5a045e27369c26e6dcda51fd7c850e9b3a3a79e718f43261dee1e4", + "reserved2": "0x0000000000000000000000000000000000000000000000000000000000000000", + "mrSigner": "0x8c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff", + "reserved3": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "isvProdId": 1, + "isvSvn": 10, + "reserved4": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "reportData": "0x35b9ea12f4cf90ec68e8f4b0cbeb15ab6c70e858f1ed8b00c6f3b8471bf114660000000000000000000000000000000000000000000000000000000000000000" + }, + "qeReportSignature": "0x5ec0f952f3ef6572b1dfa26bbd07e36d47bff6cfa731c726bd977f93beda6edf836944a8ddd88f3809ab8746a1875cf13089e481d8c36275d1fb71f5837c58f1", + "qeAuthData": { + "parsedDataSize": 32, + "data": "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" + }, + "certification": { + "certType": 5, + "certDataSize": 3682, + "decodedCertDataArray": [ + "0x308204f330820499a003020102021500bcfe8d88f1717f9f26898051b089aa089f22897a300a06082a8648ce3d04030230703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3233303832383131313330355a170d3330303832383131313330355a30703122302006035504030c19496e74656c205347582050434b204365727469666963617465311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000432b004ab4baae47a3d781dfd494a9b8f3b5343515cb35c10afa75878d85d74514d001545a0d58e3ca1e060eedbcde57d884c6101e731c18f38eff64b96c948d4a382030e3082030a301f0603551d23041830168014956f5dcdbd1be1e94049c9d4f433ce01570bde54306b0603551d1f046430623060a05ea05c865a68747470733a2f2f6170692e7472757374656473657276696365732e696e74656c2e636f6d2f7367782f63657274696669636174696f6e2f76342f70636b63726c3f63613d706c6174666f726d26656e636f64696e673d646572301d0603551d0e041604145357a665cf5bc991849f9098fc3627f3aa06b058300e0603551d0f0101ff0404030206c0300c0603551d130101ff040230003082023b06092a864886f84d010d010482022c30820228301e060a2a864886f84d010d01010410fe46ae011cce8a4d6e8334b08d1bb40130820165060a2a864886f84d010d0102308201553010060b2a864886f84d010d01020102010b3010060b2a864886f84d010d01020202010b3010060b2a864886f84d010d0102030201033010060b2a864886f84d010d0102040201033011060b2a864886f84d010d010205020200ff3011060b2a864886f84d010d010206020200ff3010060b2a864886f84d010d0102070201003010060b2a864886f84d010d0102080201003010060b2a864886f84d010d0102090201003010060b2a864886f84d010d01020a0201003010060b2a864886f84d010d01020b0201003010060b2a864886f84d010d01020c0201003010060b2a864886f84d010d01020d0201003010060b2a864886f84d010d01020e0201003010060b2a864886f84d010d01020f0201003010060b2a864886f84d010d0102100201003010060b2a864886f84d010d01021102010d301f060b2a864886f84d010d01021204100b0b0303ffff000000000000000000003010060a2a864886f84d010d0103040200003014060a2a864886f84d010d0104040600606a000000300f060a2a864886f84d010d01050a0101301e060a2a864886f84d010d010604104589ccebf2644f0ade48ff1e15c46bfb3044060a2a864886f84d010d010730363010060b2a864886f84d010d0107010101ff3010060b2a864886f84d010d0107020101ff3010060b2a864886f84d010d0107030101ff300a06082a8648ce3d040302034800304502201ab7bf1d8335a99004599474c7be98f6040aef385e0a050a0230489578709693022100e37a7bb6bc01f34b3eda2c1a8660dd02708cc0954f2e2484bb00d017c544812c", + "0x308202963082023da003020102021500956f5dcdbd1be1e94049c9d4f433ce01570bde54300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130353031305a170d3333303532313130353031305a30703122302006035504030c19496e74656c205347582050434b20506c6174666f726d204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d0301070342000435207feeddb595748ed82bb3a71c3be1e241ef61320c6816e6b5c2b71dad5532eaea12a4eb3f948916429ea47ba6c3af82a15e4b19664e52657939a2d96633dea381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e04160414956f5dcdbd1be1e94049c9d4f433ce01570bde54300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020100300a06082a8648ce3d040302034700304402205ec5648b4c3e8ba558196dd417fdb6b9a5ded182438f551e9c0f938c3d5a8b970220261bd520260f9c647d3569be8e14a32892631ac358b994478088f4d2b27cf37e", + "0x3082028f30820234a003020102021422650cd65a9d3489f383b49552bf501b392706ac300a06082a8648ce3d0403023068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b3009060355040613025553301e170d3138303532313130343531305a170d3439313233313233353935395a3068311a301806035504030c11496e74656c2053475820526f6f74204341311a3018060355040a0c11496e74656c20436f72706f726174696f6e3114301206035504070c0b53616e746120436c617261310b300906035504080c024341310b30090603550406130255533059301306072a8648ce3d020106082a8648ce3d030107034200040ba9c4c0c0c86193a3fe23d6b02cda10a8bbd4e88e48b4458561a36e705525f567918e2edc88e40d860bd0cc4ee26aacc988e505a953558c453f6b0904ae7394a381bb3081b8301f0603551d2304183016801422650cd65a9d3489f383b49552bf501b392706ac30520603551d1f044b30493047a045a043864168747470733a2f2f6365727469666963617465732e7472757374656473657276696365732e696e74656c2e636f6d2f496e74656c534758526f6f7443412e646572301d0603551d0e0416041422650cd65a9d3489f383b49552bf501b392706ac300e0603551d0f0101ff04040302010630120603551d130101ff040830060101ff020101300a06082a8648ce3d0403020349003046022100e5bfe50911f92f428920dc368a302ee3d12ec5867ff622ec6497f78060c13c20022100e09d25ac7a0cb3e5e8e68fec5fa3bd416c47440bd950639d450edcbea4576aa2" + ] + } } - } -} +} \ No newline at end of file From eef3ec69536f3b6d1d1eea03a16034c597ff3330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 25 Jan 2024 22:22:43 +0530 Subject: [PATCH 14/44] add back long iterations in test --- .../test/L1/TaikoL1LibProvingWithTiers.t.sol | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol index 62e7ed214a0..0b8da110073 100644 --- a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol +++ b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol @@ -111,7 +111,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; - for (uint256 blockId = 1; blockId < 15; blockId++) { + for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); //printVariables("after propose"); @@ -161,7 +161,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; - for (uint256 blockId = 1; blockId < conf.blockMaxProposals; blockId++) { + for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); //printVariables("after propose"); @@ -173,13 +173,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // signalRoot instead of blockHash uint16 minTier = meta.minTier; - // Try to contest - // uint256 currentTimestmap = block.timestamp; - // if(minTier == LibTiers.TIER_SGX || minTier == LibTiers.TIER_SGX_AND_PSE_ZKEVM) { - // vm.warp(1_695_435_682); - // } proveBlock(Bob, Bob, meta, parentHash, signalRoot, signalRoot, minTier, ""); - //vm.warp(currentTimestmap); proveBlock(Carol, Carol, meta, parentHash, blockHash, signalRoot, minTier, ""); @@ -190,13 +184,8 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // Cannot verify block because it is contested.. verifyBlock(Carol, 1); - // currentTimestmap = block.timestamp; - // // If the current tier one of below, we need to set blockTime to reuse the quote - // if(minTier == LibTiers.TIER_SGX || minTier == LibTiers.TIER_OPTIMISTIC) { - // vm.warp(1_695_435_682); - // } proveHigherTierProof(meta, parentHash, signalRoot, blockHash, minTier); - //vm.warp(currentTimestmap); + // Otherwise just not contest vm.warp(block.timestamp + L1.getTier(LibTiers.TIER_GUARDIAN).cooldownWindow + 1); // Now can verify @@ -221,7 +210,7 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { vm.prank(Bob, Bob); bytes32 parentHash = GENESIS_BLOCK_HASH; - for (uint256 blockId = 1; blockId < 10; blockId++) { + for (uint256 blockId = 1; blockId < conf.blockMaxProposals * 3; blockId++) { printVariables("before propose"); (TaikoData.BlockMetadata memory meta,) = proposeBlock(Alice, Bob, 1_000_000, 1024); //printVariables("after propose"); From 16ed784063b1c534bad1d574ec365f028198d8d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Fri, 26 Jan 2024 14:46:37 +0530 Subject: [PATCH 15/44] deploy and config setter scripts --- packages/protocol/script/DeployOnL1.s.sol | 26 +++++++++ packages/protocol/script/SetDcapParams.s.sol | 59 ++++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 packages/protocol/script/SetDcapParams.s.sol diff --git a/packages/protocol/script/DeployOnL1.s.sol b/packages/protocol/script/DeployOnL1.s.sol index 688f04c53a8..308d4d689d7 100644 --- a/packages/protocol/script/DeployOnL1.s.sol +++ b/packages/protocol/script/DeployOnL1.s.sol @@ -36,6 +36,15 @@ import "../contracts/signal/SignalService.sol"; import "../contracts/test/erc20/FreeMintERC20.sol"; import "../contracts/test/erc20/MayFailFreeMintERC20.sol"; import "../test/DeployCapability.sol"; +import "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; +import "../contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol"; +import "../contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol"; + +// Actually this one is deployed already on mainnets, but we are now deploying our own (non vi-ir) +// version. For mainnet, it is easier to go with either this: +// https://github.com/daimo-eth/p256-verifier or this: +// https://github.com/rdubois-crypto/FreshCryptoLib +import { P256Verifier } from "../lib/p256-verifier/src/P256Verifier.sol"; /// @title DeployOnL1 /// @notice This script deploys the core Taiko protocol smart contract on L1, @@ -374,6 +383,23 @@ contract DeployOnL1 is DeployCapability { uint8 minGuardians = uint8(vm.envUint("MIN_GUARDIANS")); GuardianProver(guardianProver).setGuardians(guardians, minGuardians); GuardianProver(guardianProver).transferOwnership(timelock); + + // No need to proxy these, because they are 3rd party. If we want to modify, we simply + // change the registerAddress("automata_dcap_attestation", address(attestation)); + P256Verifier p256Verifier = new P256Verifier(); + SigVerifyLib sigVerifyLib = new SigVerifyLib(address(p256Verifier)); + PEMCertChainLib pemCertChainLib = new PEMCertChainLib(); + AutomataDcapV3Attestation automateDcapV3Attestation = + new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); + + register( + rollupAddressManager, + "automata_dcap_attestation", + address(automateDcapV3Attestation), + block.chainId + ); + + //Todo (@WangYue): } function deployAuxContracts() private { diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol new file mode 100644 index 00000000000..bdf8dbe0850 --- /dev/null +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: MIT +// _____ _ _ _ _ +// |_ _|_ _(_) |_____ | | __ _| |__ ___ +// | |/ _` | | / / _ \ | |__/ _` | '_ (_-< +// |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/ +// +// Email: security@taiko.xyz +// Website: https://taiko.xyz +// GitHub: https://github.com/taikoxyz +// Discord: https://discord.gg/taikoxyz +// Twitter: https://twitter.com/taikoxyz +// Blog: https://mirror.xyz/labs.taiko.eth +// Youtube: https://www.youtube.com/@taikoxyz + +pragma solidity 0.8.20; + +import "forge-std/Script.sol"; +import "forge-std/console2.sol"; + +import "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; +import "../test/onchainRA/utils/DcapTestUtils.t.sol"; + +contract SetAddress is Script, DcapTestUtils { + //@todo: Wand Yue -> after deployed with DeployOnL1, you have the parameters, fill in the proper + // .env vars the the parameter files, and run this script. + uint256 public ownerPrivateKey = vm.envUint("PRIVATE_KEY"); // Owner of the attestation contract + address public dcapAttestationAddress = vm.envAddress("ATTESTATION_ADDRESS"); + string public tcbInfoPath = vm.envString("TCB_INFO_PATH"); + string public idPath = vm.envString("TCB_ID_PATH"); + string public v3QuotePath = vm.envString("V3_QUOTE_PATH"); + bytes32 public mrEnclave = vm.envBytes32("MR_ENCLAVE"); + bytes32 public mrSigner = vm.envBytes32("MR_SIGNER"); + + function run() external { + require(ownerPrivateKey != 0, "PRIVATE_KEY not set"); + require(dcapAttestationAddress != address(0), "ATTESTATION_ADDRESS not set"); + + vm.startBroadcast(ownerPrivateKey); + + AutomataDcapV3Attestation(dcapAttestationAddress).setMrEnclave(mrEnclave, true); + AutomataDcapV3Attestation(dcapAttestationAddress).setMrSigner(mrSigner, true); + + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); + + string memory fmspc = "00606a000000"; + (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = + parseTcbInfoJson(tcbInfoJson); + require(tcbParsedSuccess, "tcb parsed failed"); + AutomataDcapV3Attestation(dcapAttestationAddress).configureTcbInfoJson(fmspc, parsedTcbInfo); + + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + require(qeIdParsedSuccess, "qeid parsed failed"); + AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); + + vm.stopBroadcast(); + } +} From 59fa0bcf10a21d24e07f3991b664d9c5f67b550a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Fri, 26 Jan 2024 14:51:00 +0530 Subject: [PATCH 16/44] fix typo --- packages/protocol/script/DeployOnL1.s.sol | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/protocol/script/DeployOnL1.s.sol b/packages/protocol/script/DeployOnL1.s.sol index 308d4d689d7..17d08b42c75 100644 --- a/packages/protocol/script/DeployOnL1.s.sol +++ b/packages/protocol/script/DeployOnL1.s.sol @@ -396,10 +396,8 @@ contract DeployOnL1 is DeployCapability { rollupAddressManager, "automata_dcap_attestation", address(automateDcapV3Attestation), - block.chainId + block.chainid ); - - //Todo (@WangYue): } function deployAuxContracts() private { From de3701adbe45722cc955af6743f410162b40c48e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Sat, 27 Jan 2024 20:55:15 +0530 Subject: [PATCH 17/44] fix deploy --- packages/protocol/script/DeployOnL1.s.sol | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/protocol/script/DeployOnL1.s.sol b/packages/protocol/script/DeployOnL1.s.sol index 17d08b42c75..2411046e0c9 100644 --- a/packages/protocol/script/DeployOnL1.s.sol +++ b/packages/protocol/script/DeployOnL1.s.sol @@ -393,10 +393,7 @@ contract DeployOnL1 is DeployCapability { new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); register( - rollupAddressManager, - "automata_dcap_attestation", - address(automateDcapV3Attestation), - block.chainid + rollupAddressManager, "automata_dcap_attestation", address(automateDcapV3Attestation) ); } From 91bb1db47cc20975555abd9ae870683c53a30037 Mon Sep 17 00:00:00 2001 From: Daniel Wang Date: Mon, 29 Jan 2024 12:43:26 +0800 Subject: [PATCH 18/44] Merge branch 'submodules' into onchain_remote_attestation --- .gitmodules | 23 ++++++++------ .../ChainSelector/ChainSelectorWrapper.svelte | 31 +++++++++++++------ .../TokenDropdown/TokenDropdown.svelte | 25 ++++++++------- .../http/routes.go | 2 ++ packages/protocol/README.md | 28 ++++++++++++++++- .../contracts/L1/libs/LibProposing.sol | 6 ++-- .../contracts/L1/provers/Guardians.sol | 5 +-- packages/protocol/contracts/L2/TaikoL2.sol | 2 +- packages/protocol/contracts/bridge/Bridge.sol | 13 ++++++-- .../contracts/team/TimelockTokenPool.sol | 2 +- .../contracts/team/airdrop/ERC20Airdrop.sol | 4 +-- .../contracts/team/airdrop/ERC20Airdrop2.sol | 4 +-- .../contracts/tokenvault/ERC20Vault.sol | 17 ++++++---- .../contracts/tokenvault/ERC721Vault.sol | 2 +- .../tokenvault/adaptors/USDCAdaptor.sol | 2 +- 15 files changed, 112 insertions(+), 54 deletions(-) diff --git a/.gitmodules b/.gitmodules index 13907426c32..5adac460f62 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,22 +1,25 @@ -[submodule "packages/protocol/lib/solmate"] - path = packages/protocol/lib/solmate - url = https://github.com/rari-capital/solmate - branch = v1.5.0 +# git submodule update --recursive --remote +[submodule "packages/protocol/lib/forge-std"] + path = packages/protocol/lib/forge-std + url = https://github.com/foundry-rs/forge-std + tag = v1.7.6 [submodule "packages/protocol/lib/openzeppelin-contracts-upgradeable"] path = packages/protocol/lib/openzeppelin-contracts-upgradeable url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable - branch = v4.8.2 + tag = v4.8.2 [submodule "packages/protocol/lib/openzeppelin-contracts"] path = packages/protocol/lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts - branch = v4.8.2 -[submodule "packages/protocol/lib/forge-std"] - path = packages/protocol/lib/forge-std - url = https://github.com/foundry-rs/forge-std - branch = chore/v1.5.1 + tag = v4.8.2 [submodule "packages/protocol/lib/solady"] path = packages/protocol/lib/solady url = https://github.com/Vectorized/solady + tag = v0.0.166 [submodule "packages/protocol/lib/p256-verifier"] path = packages/protocol/lib/p256-verifier url = https://github.com/taikoxyz/p256-verifier + commit = c8210cd99f9f81a58e25a6a8afdb992fefbd9748 +[submodule "packages/protocol/lib/automata-dcap-v3-attestation"] + path = packages/protocol/lib/automata-dcap-v3-attestation + url = https://github.com/automata-network/automata-dcap-v3-attestation + commit = 80eba1c014c193d4e83e07ac7d015cea8ebf1232 \ No newline at end of file diff --git a/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelectorWrapper.svelte b/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelectorWrapper.svelte index 4f10f9ae1d1..791c098cac6 100644 --- a/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelectorWrapper.svelte +++ b/packages/bridge-ui-v2/src/components/ChainSelector/ChainSelectorWrapper.svelte @@ -6,9 +6,11 @@ import { destNetwork, destOptions } from '$components/Bridge/state'; import SwitchChainsButton from '$components/Bridge/SwitchChainsButton.svelte'; import { ChainSelector } from '$components/ChainSelector'; + import { OnAccount } from '$components/OnAccount'; import { OnNetwork } from '$components/OnNetwork'; import { hasBridge } from '$libs/bridge/bridges'; import { chainIdToChain, chains } from '$libs/chain'; + import { account } from '$stores/account'; import { network } from '$stores/network'; let destChainElement: ChainSelector; @@ -30,15 +32,6 @@ }); } - function onNetworkChange() { - updateDestOptions(); - const alternateChainID = getAlternateNetwork(); - if (!$destNetwork && alternateChainID) { - // if only two chains are available, set the destination chain to the other one - $destNetwork = chainIdToChain(alternateChainID); - } - } - const getAlternateNetwork = (): number | null => { if (!$network?.id) { return null; @@ -48,18 +41,35 @@ // only allow switching between two chains, if we have more we do not use this util if (chainKeys.length !== 2) { + updateDestOptions(); return null; } const alternateChainId = chainKeys.find((key) => key !== currentNetwork); if (!alternateChainId) return null; + updateDestOptions(); return alternateChainId; }; $: highlight = $destNetwork ? false : true; + const onNetworkChange = () => setAlternateNetwork(); + + const onAccountChange = () => setAlternateNetwork(); + + const setAlternateNetwork = () => { + if ($account && ($account.isConnected || $account.isConnecting)) { + const alternateChainID = getAlternateNetwork(); + if (alternateChainID) { + $destNetwork = chainIdToChain(alternateChainID); + } + } else { + $destNetwork = null; + } + }; + onMount(() => { - updateDestOptions(); + setAlternateNetwork(); }); @@ -82,3 +92,4 @@ fromToLabel={$t('common.to')} /> + diff --git a/packages/bridge-ui-v2/src/components/TokenDropdown/TokenDropdown.svelte b/packages/bridge-ui-v2/src/components/TokenDropdown/TokenDropdown.svelte index 69bcd7a71af..3f236ec75cc 100644 --- a/packages/bridge-ui-v2/src/components/TokenDropdown/TokenDropdown.svelte +++ b/packages/bridge-ui-v2/src/components/TokenDropdown/TokenDropdown.svelte @@ -65,10 +65,6 @@ warningToast({ title: $t('messages.network.required') }); return; } - if (!destChain || !destChain.id) { - warningToast({ title: $t('messages.network.required_dest') }); - return; - } // if it is an imported Token, chances are we do not yet have the bridged address // for the destination chain, so we need to fetch it @@ -76,7 +72,10 @@ // ... in the case of imported tokens, we also require the destination chain to be selected. if (!destChain) { let bridgedAddress = null; - + if (!destChain || !destChain.id) { + warningToast({ title: $t('messages.network.required_dest') }); + return; + } try { bridgedAddress = await getCrossChainAddress({ token, @@ -94,13 +93,17 @@ tokenService.updateToken(token, $account?.address as Address); } } + value = token; - const info = await getCanonicalInfoForToken({ token, srcChainId: srcChain.id, destChainId: destChain.id }); - if (info && value.addresses[srcChain.id] !== info.address) { - log('selected token is not canonical'); - $selectedTokenIsBridged = true; - } else { - $selectedTokenIsBridged = false; + + if (destChain) { + const info = await getCanonicalInfoForToken({ token, srcChainId: srcChain.id, destChainId: destChain.id }); + if (info && value.addresses[srcChain.id] !== info.address) { + log('selected token is not canonical'); + $selectedTokenIsBridged = true; + } else { + $selectedTokenIsBridged = false; + } } closeMenu(); }; diff --git a/packages/guardian-prover-health-check/http/routes.go b/packages/guardian-prover-health-check/http/routes.go index 495351df2dd..1b2ca39405f 100644 --- a/packages/guardian-prover-health-check/http/routes.go +++ b/packages/guardian-prover-health-check/http/routes.go @@ -23,4 +23,6 @@ func (srv *Server) configureRoutes() { srv.echo.GET("/startups/:id", srv.GetStartupsByGuardianProverID) srv.echo.GET("/mostRecentStartup/:id", srv.GetMostRecentStartupByGuardianProverID) + + srv.echo.POST("/startup", srv.PostStartup) } diff --git a/packages/protocol/README.md b/packages/protocol/README.md index 2037a682d10..21ffc2f4d0d 100644 --- a/packages/protocol/README.md +++ b/packages/protocol/README.md @@ -4,7 +4,33 @@ This package contains rollup contracts on both L1 and L2, along with other assis ## Getting Started -Before compiling smart contracts, ensure all necessary dependencies are installed: +Before compiling smart contracts, ensure all necessary submodules are updated and all dependencies are installed: + +```sh +git submodule update --recursive --remote + +``` + +If some git submodules are not initialized correctly, use the following commands in the root directory: + +```sh +git submodule add \ +--name packages/protocol/lib/automata-dcap-v3-attestation\ +https://github.com/automata-network/automata-dcap-v3-attestation \ +packages/protocol/lib/automata-dcap-v3-attestation + +git submodule add \ +--name packages/protocol/lib/p256-verifier \ +https://github.com/taikoxyz/p256-verifier \ +packages/protocol/lib/p256-verifier + +git submodule add \ +--name packages/protocol/lib/solady \ +https://github.com/Vectorized/solady \ +packages/protocol/lib/solady + +``` + ```sh pnpm install diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 36a880ccd25..5f454ca51a5 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -134,7 +134,7 @@ library LibProposing { if (params.blobHash != 0) { // We try to reuse an old blob - if (isBlobReusable(state, config, params.blobHash)) { + if (!isBlobReusable(state, config, params.blobHash)) { revert L1_BLOB_NOT_REUSEABLE(); } meta.blobHash = params.blobHash; @@ -193,9 +193,7 @@ library LibProposing { // of multiple Taiko blocks being proposed within a single // Ethereum block, we must introduce a salt to this random // number as the L2 mixHash. - unchecked { - meta.difficulty = meta.blobHash ^ bytes32(block.prevrandao * b.numBlocks * block.number); - } + meta.difficulty = keccak256(abi.encodePacked(block.prevrandao, b.numBlocks, block.number)); // Use the difficulty as a random number meta.minTier = ITierProvider(resolver.resolve("tier_provider", false)).getMinTier( diff --git a/packages/protocol/contracts/L1/provers/Guardians.sol b/packages/protocol/contracts/L1/provers/Guardians.sol index 560786ad1b6..832c3ec3184 100644 --- a/packages/protocol/contracts/L1/provers/Guardians.sol +++ b/packages/protocol/contracts/L1/provers/Guardians.sol @@ -94,8 +94,9 @@ abstract contract Guardians is EssentialContract { _approvals[version][hash] |= 1 << (id - 1); } - approved = isApproved(_approvals[version][hash]); - emit Approved(operationId, _approvals[version][hash], approved); + uint256 _approval = _approvals[version][hash]; + approved = isApproved(_approval); + emit Approved(operationId, _approval, approved); } function deleteApproval(bytes32 hash) internal { diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index f740a39a160..c024fd435c6 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -199,7 +199,7 @@ contract TaikoL2 is CrossChainOwned, TaikoL2Signer, ICrossChainSync { /// block id is greater than or equal to the current block number. function getBlockHash(uint64 blockId) public view returns (bytes32) { if (blockId >= block.number) return 0; - if (blockId >= block.number - 256) return blockhash(blockId); + if (blockId + 256 >= block.number) return blockhash(blockId); return l2Hashes[blockId]; } diff --git a/packages/protocol/contracts/bridge/Bridge.sol b/packages/protocol/contracts/bridge/Bridge.sol index 571a7b8656a..3918904844c 100644 --- a/packages/protocol/contracts/bridge/Bridge.sol +++ b/packages/protocol/contracts/bridge/Bridge.sol @@ -40,17 +40,20 @@ contract Bridge is EssentialContract, IBridge { mapping(bytes32 msgHash => bool recalled) public isMessageRecalled; mapping(bytes32 msgHash => Status) public messageStatus; // slot 3 Context private _ctx; // // slot 4,5,6pnpm - uint256[44] private __gap; + mapping(address => bool) public addressBanned; + uint256[43] private __gap; event SignalSent(address indexed sender, bytes32 msgHash); event MessageSent(bytes32 indexed msgHash, Message message); event MessageRecalled(bytes32 indexed msgHash); event DestChainEnabled(uint64 indexed chainId, bool enabled); event MessageStatusChanged(bytes32 indexed msgHash, Status status); + event AddressBanned(address indexed addr, bool banned); error B_INVALID_CHAINID(); error B_INVALID_CONTEXT(); error B_INVALID_GAS_LIMIT(); + error B_INVALID_STATUS(); error B_INVALID_USER(); error B_INVALID_VALUE(); error B_MESSAGE_NOT_SENT(); @@ -75,6 +78,12 @@ contract Bridge is EssentialContract, IBridge { _ctx.msgHash == bytes32(PLACEHOLDER); } + function banAddress(address addr, bool toBan) external onlyOwner nonReentrant { + if (addressBanned[addr] == toBan) revert B_INVALID_STATUS(); + addressBanned[addr] = toBan; + emit AddressBanned(addr, toBan); + } + /// @notice Sends a message to the destination chain and takes custody /// of Ether required in this contract. All extra Ether will be refunded. /// @inheritdoc IBridge @@ -207,7 +216,7 @@ contract Bridge is EssentialContract, IBridge { // Process message differently based on the target address if ( message.to == address(0) || message.to == address(this) - || message.to == address(signalService) + || message.to == address(signalService) || addressBanned[message.to] ) { // Handle special addresses that don't require actual invocation but // mark message as DONE diff --git a/packages/protocol/contracts/team/TimelockTokenPool.sol b/packages/protocol/contracts/team/TimelockTokenPool.sol index b4bcf12fae2..d7c848abb3e 100644 --- a/packages/protocol/contracts/team/TimelockTokenPool.sol +++ b/packages/protocol/contracts/team/TimelockTokenPool.sol @@ -186,7 +186,7 @@ contract TimelockTokenPool is EssentialContract { totalCostPaid += costToWithdraw; IERC20(taikoToken).transferFrom(sharedVault, to, amountToWithdraw); - IERC20(costToken).transferFrom(recipient, sharedVault, costToWithdraw); + IERC20(costToken).safeTransferFrom(recipient, sharedVault, costToWithdraw); emit Withdrawn(recipient, to, amountToWithdraw, costToWithdraw); } diff --git a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol index 89ccafec042..c11712b02cc 100644 --- a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol +++ b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol @@ -14,7 +14,7 @@ pragma solidity 0.8.20; -import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; +import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "./MerkleClaimable.sol"; /// @title ERC20Airdrop @@ -43,6 +43,6 @@ contract ERC20Airdrop is MerkleClaimable { function _claimWithData(bytes calldata data) internal override { (address user, uint256 amount) = abi.decode(data, (address, uint256)); - IERC20Upgradeable(token).transferFrom(vault, user, amount); + IERC20(token).transferFrom(vault, user, amount); } } diff --git a/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol b/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol index dcaeb0a9792..d72e5dcd976 100644 --- a/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol +++ b/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol @@ -14,7 +14,7 @@ pragma solidity 0.8.20; -import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; +import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../libs/LibMath.sol"; import "./MerkleClaimable.sol"; @@ -71,7 +71,7 @@ contract ERC20Airdrop2 is MerkleClaimable { function withdraw(address user) external ongoingWithdrawals { (, uint256 amount) = getBalance(user); withdrawnAmount[user] += amount; - IERC20Upgradeable(token).transferFrom(vault, user, amount); + IERC20(token).transferFrom(vault, user, amount); emit Withdrawn(user, amount); } diff --git a/packages/protocol/contracts/tokenvault/ERC20Vault.sol b/packages/protocol/contracts/tokenvault/ERC20Vault.sol index c3f517a739d..2c140806ab5 100644 --- a/packages/protocol/contracts/tokenvault/ERC20Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC20Vault.sol @@ -256,22 +256,27 @@ contract ERC20Vault is BaseVault { { checkRecallMessageContext(); - (, address token,, uint256 amount) = + (CanonicalERC20 memory ctoken,,, uint256 amount) = abi.decode(message.data[4:], (CanonicalERC20, address, address, uint256)); - if (token == address(0)) revert VAULT_INVALID_TOKEN(); + if (ctoken.addr == address(0)) revert VAULT_INVALID_TOKEN(); if (amount > 0) { - if (bridgedToCanonical[token].addr != address(0)) { - IBridgedERC20(token).mint(message.owner, amount); + if (bridgedToCanonical[ctoken.addr].addr != address(0)) { + IBridgedERC20(ctoken.addr).mint(message.owner, amount); } else { - ERC20(token).safeTransfer(message.owner, amount); + ERC20(ctoken.addr).safeTransfer(message.owner, amount); } } message.owner.sendEther(message.value); - emit TokenReleased({ msgHash: msgHash, from: message.owner, token: token, amount: amount }); + emit TokenReleased({ + msgHash: msgHash, + from: message.owner, + token: ctoken.addr, + amount: amount + }); } function name() public pure override returns (bytes32) { diff --git a/packages/protocol/contracts/tokenvault/ERC721Vault.sol b/packages/protocol/contracts/tokenvault/ERC721Vault.sol index 856422bff45..dd93eea0a85 100644 --- a/packages/protocol/contracts/tokenvault/ERC721Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC721Vault.sol @@ -234,7 +234,7 @@ contract ERC721Vault is BaseNFTVault, IERC721ReceiverUpgradeable { }); for (uint256 i; i < op.tokenIds.length; ++i) { - t.transferFrom(user, address(this), op.tokenIds[i]); + t.safeTransferFrom(user, address(this), op.tokenIds[i]); } } } diff --git a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol index fa4851d7571..aaeb11265d1 100644 --- a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol +++ b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol @@ -19,7 +19,7 @@ import "../BridgedERC20Base.sol"; interface IUSDC { function burn(uint256 amount) external; function mint(address to, uint256 amount) external; - function transferFrom(address from, address to, uint256 amount) external; + function transferFrom(address from, address to, uint256 value) external returns (bool); } /// @title USDCAdaptor From 99d7a60ab716f86483f39f74df5b777d77296f69 Mon Sep 17 00:00:00 2001 From: adaki2004 Date: Mon, 29 Jan 2024 11:21:25 +0530 Subject: [PATCH 19/44] add taiko on automata dcap submodule --- .gitmodules | 5 +++-- packages/protocol/lib/automata-dcap-v3-attestation | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) create mode 160000 packages/protocol/lib/automata-dcap-v3-attestation diff --git a/.gitmodules b/.gitmodules index 5adac460f62..6a2fb8ef46e 100644 --- a/.gitmodules +++ b/.gitmodules @@ -21,5 +21,6 @@ commit = c8210cd99f9f81a58e25a6a8afdb992fefbd9748 [submodule "packages/protocol/lib/automata-dcap-v3-attestation"] path = packages/protocol/lib/automata-dcap-v3-attestation - url = https://github.com/automata-network/automata-dcap-v3-attestation - commit = 80eba1c014c193d4e83e07ac7d015cea8ebf1232 \ No newline at end of file + url = https://github.com/taikoxyz/automata-dcap-v3-attestation + commit = 80eba1c014c193d4e83e07ac7d015cea8ebf1232 + branch = optimize-gas diff --git a/packages/protocol/lib/automata-dcap-v3-attestation b/packages/protocol/lib/automata-dcap-v3-attestation new file mode 160000 index 00000000000..37369f1cf7b --- /dev/null +++ b/packages/protocol/lib/automata-dcap-v3-attestation @@ -0,0 +1 @@ +Subproject commit 37369f1cf7b5af4ee58d0b8a93667386de56c37e From 4d4ebadb64cf493e33bf5bcf9151bc60ba081e05 Mon Sep 17 00:00:00 2001 From: adaki2004 Date: Mon, 29 Jan 2024 11:22:36 +0530 Subject: [PATCH 20/44] update readme --- packages/protocol/README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/protocol/README.md b/packages/protocol/README.md index 21ffc2f4d0d..91d6ac138a9 100644 --- a/packages/protocol/README.md +++ b/packages/protocol/README.md @@ -13,6 +13,26 @@ git submodule update --recursive --remote If some git submodules are not initialized correctly, use the following commands in the root directory: +```sh +git submodule add \ +-b optimize-gas \ +https://github.com/taikoxyz/automata-dcap-v3-attestation \ +packages/protocol/lib/automata-dcap-v3-attestation + +git submodule add \ +--name packages/protocol/lib/p256-verifier \ +https://github.com/taikoxyz/p256-verifier \ +packages/protocol/lib/p256-verifier + +git submodule add \ +--name packages/protocol/lib/solady \ +https://github.com/Vectorized/solady \ +packages/protocol/lib/solady + +``` + +If some git submodules are not initialized correctly, use the following commands in the root directory: + ```sh git submodule add \ --name packages/protocol/lib/automata-dcap-v3-attestation\ @@ -31,7 +51,6 @@ packages/protocol/lib/solady ``` - ```sh pnpm install ``` From 728fd6c7b0e11339aa8ad5093229f93432fab559 Mon Sep 17 00:00:00 2001 From: smtmfft <99081233+smtmfft@users.noreply.github.com> Date: Mon, 29 Jan 2024 13:59:33 +0800 Subject: [PATCH 21/44] feat(protocol): add forge script to config dcap sgx verifier (#15596) Signed-off-by: smtmfft --- .../contracts/L1/verifiers/SgxVerifier.sol | 18 ++++--- packages/protocol/script/SetDcapParams.s.sol | 52 +++++++++++++++---- .../script/config_dcap_sgx_verifier.sh | 31 +++++++++++ 3 files changed, 83 insertions(+), 18 deletions(-) create mode 100755 packages/protocol/script/config_dcap_sgx_verifier.sh diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 48a540b2b52..61c18eb5080 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -84,28 +84,30 @@ contract SgxVerifier is EssentialContract, IVerifier { /// @notice Adds an SGX instance after the attestation is verified /// @param attestation The parsed attestation quote. /// @return id The respective instanceId - function registerInstance( - V3Struct.ParsedV3QuoteStruct calldata attestation - ) + function registerInstance(V3Struct.ParsedV3QuoteStruct calldata attestation) external returns (uint256) { address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); - // Still possible to be backward compatible and have the onlyOwner tpye of method registering instances. + // Still possible to be backward compatible and have the onlyOwner type of method + // registering instances. if (automataDcapAttestation != address(0)) { - (bool verified, ) = IAttestation(automataDcapAttestation).verifyParsedQuote(attestation); + (bool verified,) = IAttestation(automataDcapAttestation).verifyParsedQuote(attestation); - if(!verified) { + if (!verified) { revert SGX_INVALID_ATTESTATION(); } address[] memory _address = new address[](1); - _address[0] = address(bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20))); + _address[0] = address( + bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20)) + ); return _addInstances(_address)[0]; } - // A special return variable, signaling that this method is not supported at the moment, because a contract with name "automata_dcap_attestation" not deployed. + // A special return variable, signaling that this method is not supported at the moment, + // because a contract with name "automata_dcap_attestation" not deployed. return type(uint256).max; } diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol index bdf8dbe0850..17e698e8dc9 100644 --- a/packages/protocol/script/SetDcapParams.s.sol +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -18,15 +18,18 @@ import "forge-std/Script.sol"; import "forge-std/console2.sol"; import "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; +import "../contracts/L1/verifiers/SgxVerifier.sol"; import "../test/onchainRA/utils/DcapTestUtils.t.sol"; +import "../test/onchainRA/utils/V3JsonUtils.t.sol"; -contract SetAddress is Script, DcapTestUtils { +contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { //@todo: Wand Yue -> after deployed with DeployOnL1, you have the parameters, fill in the proper // .env vars the the parameter files, and run this script. uint256 public ownerPrivateKey = vm.envUint("PRIVATE_KEY"); // Owner of the attestation contract address public dcapAttestationAddress = vm.envAddress("ATTESTATION_ADDRESS"); + address public sgxVerifier = vm.envAddress("SGX_VERIFIER_ADDRESS"); string public tcbInfoPath = vm.envString("TCB_INFO_PATH"); - string public idPath = vm.envString("TCB_ID_PATH"); + string public idPath = vm.envString("QEID_PATH"); string public v3QuotePath = vm.envString("V3_QUOTE_PATH"); bytes32 public mrEnclave = vm.envBytes32("MR_ENCLAVE"); bytes32 public mrSigner = vm.envBytes32("MR_SIGNER"); @@ -37,23 +40,52 @@ contract SetAddress is Script, DcapTestUtils { vm.startBroadcast(ownerPrivateKey); + // all in one + setMrEnclave(); + setMrSigner(); + configureQeIdentityJson(); + configureTcbInfoJson(); + registerSgxInstanceWithQuote(); + + vm.stopBroadcast(); + } + + function setMrEnclave() internal { AutomataDcapV3Attestation(dcapAttestationAddress).setMrEnclave(mrEnclave, true); + } + + function setMrSigner() internal { AutomataDcapV3Attestation(dcapAttestationAddress).setMrSigner(mrSigner, true); + } - string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + function configureQeIdentityJson() internal { string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); + console.log("qeIdParsedSuccess: %s", qeIdParsedSuccess); + } - string memory fmspc = "00606a000000"; + function configureTcbInfoJson() internal { + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = parseTcbInfoJson(tcbInfoJson); - require(tcbParsedSuccess, "tcb parsed failed"); + // string memory fmspc = "00606a000000"; + string memory fmspc = parsedTcbInfo.fmspc; AutomataDcapV3Attestation(dcapAttestationAddress).configureTcbInfoJson(fmspc, parsedTcbInfo); + console.log("tcbParsedSuccess: %s", tcbParsedSuccess); + } - (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - require(qeIdParsedSuccess, "qeid parsed failed"); - AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); + function registerSgxInstanceWithQuote() internal { + string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); + console.log("[LOG] v3QuoteJsonStr: %s", v3QuoteJsonStr); + bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); + console.logBytes(v3QuotePacked); - vm.stopBroadcast(); + (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); + console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); + console.logBytes(v3quote.localEnclaveReport.reportData); + uint256 ret = SgxVerifier(sgxVerifier).registerInstance(v3quote); + console.log("ret: %s", ret); } } diff --git a/packages/protocol/script/config_dcap_sgx_verifier.sh b/packages/protocol/script/config_dcap_sgx_verifier.sh new file mode 100755 index 00000000000..2e64a2ff827 --- /dev/null +++ b/packages/protocol/script/config_dcap_sgx_verifier.sh @@ -0,0 +1,31 @@ +PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ +PROPOSER=0x0000000000000000000000000000000000000000 \ +PROPOSER_ONE=0x0000000000000000000000000000000000000000 \ +GUARDIAN_PROVERS="0x1000777700000000000000000000000000000001,0x1000777700000000000000000000000000000002,0x1000777700000000000000000000000000000003,0x1000777700000000000000000000000000000004,0x1000777700000000000000000000000000000005" \ +MIN_GUARDIANS=3 \ +TAIKO_L2_ADDRESS=0x1000777700000000000000000000000000000001 \ +L2_SIGNAL_SERVICE=0x1000777700000000000000000000000000000007 \ +SECURITY_COUNCIL=0x60997970C51812dc3A010C7d01b50e0d17dc79C8 \ +TAIKO_TOKEN_PREMINT_RECIPIENT=0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 \ +TAIKO_TOKEN_NAME="Taiko Token Katla" \ +TAIKO_TOKEN_SYMBOL=TTKOk \ +SHARED_ADDRESS_MANAGER=0x0000000000000000000000000000000000000000 \ +L2_GENESIS_HASH=0xee1950562d42f0da28bd4550d88886bc90894c77c9c9eaefef775d4c8223f259 \ +ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1 \ +LOG_LEVEL=DEBUG \ +REPORT_GAS=true \ +SGX_VERIFIER_ADDRESS=0x1fA02b2d6A771842690194Cf62D91bdd92BfE28d \ +TIMELOCK_ADDRESS=0xB2b580ce436E6F77A5713D80887e14788Ef49c9A \ +ATTESTATION_ADDRESS=0xC9a43158891282A2B1475592D5719c001986Aaec \ +TCB_INFO_PATH=/test/onchainRA/assets/0923/tcbInfo.json \ +QEID_PATH=/test/onchainRA/assets/0923/identity.json \ +V3_QUOTE_PATH=/test/onchainRA/assets/0923/v3quote.json \ +MR_ENCLAVE=0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef \ +MR_SIGNER=0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef \ +forge script script/SetDcapParams.s.sol:SetDcapParams \ + --fork-url http://localhost:8545 \ + --broadcast \ + --ffi \ + -vvvv \ + --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + --block-gas-limit 100000000 \ No newline at end of file From 5d84deb16e3364c03d92d45c9640ce65fb584674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Mon, 29 Jan 2024 14:38:12 +0530 Subject: [PATCH 22/44] Reverting to de3701a --- .gitmodules | 24 ++++----- packages/protocol/README.md | 47 +---------------- .../contracts/L1/libs/LibProposing.sol | 6 ++- .../contracts/L1/provers/Guardians.sol | 5 +- .../contracts/L1/verifiers/SgxVerifier.sol | 2 +- packages/protocol/contracts/L2/TaikoL2.sol | 2 +- packages/protocol/contracts/bridge/Bridge.sol | 13 +---- .../contracts/team/TimelockTokenPool.sol | 2 +- .../contracts/team/airdrop/ERC20Airdrop.sol | 4 +- .../contracts/team/airdrop/ERC20Airdrop2.sol | 4 +- .../contracts/tokenvault/ERC20Vault.sol | 17 +++--- .../contracts/tokenvault/ERC721Vault.sol | 2 +- .../tokenvault/adaptors/USDCAdaptor.sol | 2 +- packages/protocol/script/SetDcapParams.s.sol | 52 ++++--------------- 14 files changed, 44 insertions(+), 138 deletions(-) diff --git a/.gitmodules b/.gitmodules index 6a2fb8ef46e..13907426c32 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,26 +1,22 @@ -# git submodule update --recursive --remote -[submodule "packages/protocol/lib/forge-std"] - path = packages/protocol/lib/forge-std - url = https://github.com/foundry-rs/forge-std - tag = v1.7.6 +[submodule "packages/protocol/lib/solmate"] + path = packages/protocol/lib/solmate + url = https://github.com/rari-capital/solmate + branch = v1.5.0 [submodule "packages/protocol/lib/openzeppelin-contracts-upgradeable"] path = packages/protocol/lib/openzeppelin-contracts-upgradeable url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable - tag = v4.8.2 + branch = v4.8.2 [submodule "packages/protocol/lib/openzeppelin-contracts"] path = packages/protocol/lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts - tag = v4.8.2 + branch = v4.8.2 +[submodule "packages/protocol/lib/forge-std"] + path = packages/protocol/lib/forge-std + url = https://github.com/foundry-rs/forge-std + branch = chore/v1.5.1 [submodule "packages/protocol/lib/solady"] path = packages/protocol/lib/solady url = https://github.com/Vectorized/solady - tag = v0.0.166 [submodule "packages/protocol/lib/p256-verifier"] path = packages/protocol/lib/p256-verifier url = https://github.com/taikoxyz/p256-verifier - commit = c8210cd99f9f81a58e25a6a8afdb992fefbd9748 -[submodule "packages/protocol/lib/automata-dcap-v3-attestation"] - path = packages/protocol/lib/automata-dcap-v3-attestation - url = https://github.com/taikoxyz/automata-dcap-v3-attestation - commit = 80eba1c014c193d4e83e07ac7d015cea8ebf1232 - branch = optimize-gas diff --git a/packages/protocol/README.md b/packages/protocol/README.md index 91d6ac138a9..2037a682d10 100644 --- a/packages/protocol/README.md +++ b/packages/protocol/README.md @@ -4,52 +4,7 @@ This package contains rollup contracts on both L1 and L2, along with other assis ## Getting Started -Before compiling smart contracts, ensure all necessary submodules are updated and all dependencies are installed: - -```sh -git submodule update --recursive --remote - -``` - -If some git submodules are not initialized correctly, use the following commands in the root directory: - -```sh -git submodule add \ --b optimize-gas \ -https://github.com/taikoxyz/automata-dcap-v3-attestation \ -packages/protocol/lib/automata-dcap-v3-attestation - -git submodule add \ ---name packages/protocol/lib/p256-verifier \ -https://github.com/taikoxyz/p256-verifier \ -packages/protocol/lib/p256-verifier - -git submodule add \ ---name packages/protocol/lib/solady \ -https://github.com/Vectorized/solady \ -packages/protocol/lib/solady - -``` - -If some git submodules are not initialized correctly, use the following commands in the root directory: - -```sh -git submodule add \ ---name packages/protocol/lib/automata-dcap-v3-attestation\ -https://github.com/automata-network/automata-dcap-v3-attestation \ -packages/protocol/lib/automata-dcap-v3-attestation - -git submodule add \ ---name packages/protocol/lib/p256-verifier \ -https://github.com/taikoxyz/p256-verifier \ -packages/protocol/lib/p256-verifier - -git submodule add \ ---name packages/protocol/lib/solady \ -https://github.com/Vectorized/solady \ -packages/protocol/lib/solady - -``` +Before compiling smart contracts, ensure all necessary dependencies are installed: ```sh pnpm install diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 5f454ca51a5..36a880ccd25 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -134,7 +134,7 @@ library LibProposing { if (params.blobHash != 0) { // We try to reuse an old blob - if (!isBlobReusable(state, config, params.blobHash)) { + if (isBlobReusable(state, config, params.blobHash)) { revert L1_BLOB_NOT_REUSEABLE(); } meta.blobHash = params.blobHash; @@ -193,7 +193,9 @@ library LibProposing { // of multiple Taiko blocks being proposed within a single // Ethereum block, we must introduce a salt to this random // number as the L2 mixHash. - meta.difficulty = keccak256(abi.encodePacked(block.prevrandao, b.numBlocks, block.number)); + unchecked { + meta.difficulty = meta.blobHash ^ bytes32(block.prevrandao * b.numBlocks * block.number); + } // Use the difficulty as a random number meta.minTier = ITierProvider(resolver.resolve("tier_provider", false)).getMinTier( diff --git a/packages/protocol/contracts/L1/provers/Guardians.sol b/packages/protocol/contracts/L1/provers/Guardians.sol index 832c3ec3184..560786ad1b6 100644 --- a/packages/protocol/contracts/L1/provers/Guardians.sol +++ b/packages/protocol/contracts/L1/provers/Guardians.sol @@ -94,9 +94,8 @@ abstract contract Guardians is EssentialContract { _approvals[version][hash] |= 1 << (id - 1); } - uint256 _approval = _approvals[version][hash]; - approved = isApproved(_approval); - emit Approved(operationId, _approval, approved); + approved = isApproved(_approvals[version][hash]); + emit Approved(operationId, _approvals[version][hash], approved); } function deleteApproval(bytes32 hash) internal { diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 61c18eb5080..f2ca455bc8f 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -90,7 +90,7 @@ contract SgxVerifier is EssentialContract, IVerifier { { address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); - // Still possible to be backward compatible and have the onlyOwner type of method + // Still possible to be backward compatible and have the onlyOwner tpye of method // registering instances. if (automataDcapAttestation != address(0)) { (bool verified,) = IAttestation(automataDcapAttestation).verifyParsedQuote(attestation); diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index c024fd435c6..f740a39a160 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -199,7 +199,7 @@ contract TaikoL2 is CrossChainOwned, TaikoL2Signer, ICrossChainSync { /// block id is greater than or equal to the current block number. function getBlockHash(uint64 blockId) public view returns (bytes32) { if (blockId >= block.number) return 0; - if (blockId + 256 >= block.number) return blockhash(blockId); + if (blockId >= block.number - 256) return blockhash(blockId); return l2Hashes[blockId]; } diff --git a/packages/protocol/contracts/bridge/Bridge.sol b/packages/protocol/contracts/bridge/Bridge.sol index 3918904844c..571a7b8656a 100644 --- a/packages/protocol/contracts/bridge/Bridge.sol +++ b/packages/protocol/contracts/bridge/Bridge.sol @@ -40,20 +40,17 @@ contract Bridge is EssentialContract, IBridge { mapping(bytes32 msgHash => bool recalled) public isMessageRecalled; mapping(bytes32 msgHash => Status) public messageStatus; // slot 3 Context private _ctx; // // slot 4,5,6pnpm - mapping(address => bool) public addressBanned; - uint256[43] private __gap; + uint256[44] private __gap; event SignalSent(address indexed sender, bytes32 msgHash); event MessageSent(bytes32 indexed msgHash, Message message); event MessageRecalled(bytes32 indexed msgHash); event DestChainEnabled(uint64 indexed chainId, bool enabled); event MessageStatusChanged(bytes32 indexed msgHash, Status status); - event AddressBanned(address indexed addr, bool banned); error B_INVALID_CHAINID(); error B_INVALID_CONTEXT(); error B_INVALID_GAS_LIMIT(); - error B_INVALID_STATUS(); error B_INVALID_USER(); error B_INVALID_VALUE(); error B_MESSAGE_NOT_SENT(); @@ -78,12 +75,6 @@ contract Bridge is EssentialContract, IBridge { _ctx.msgHash == bytes32(PLACEHOLDER); } - function banAddress(address addr, bool toBan) external onlyOwner nonReentrant { - if (addressBanned[addr] == toBan) revert B_INVALID_STATUS(); - addressBanned[addr] = toBan; - emit AddressBanned(addr, toBan); - } - /// @notice Sends a message to the destination chain and takes custody /// of Ether required in this contract. All extra Ether will be refunded. /// @inheritdoc IBridge @@ -216,7 +207,7 @@ contract Bridge is EssentialContract, IBridge { // Process message differently based on the target address if ( message.to == address(0) || message.to == address(this) - || message.to == address(signalService) || addressBanned[message.to] + || message.to == address(signalService) ) { // Handle special addresses that don't require actual invocation but // mark message as DONE diff --git a/packages/protocol/contracts/team/TimelockTokenPool.sol b/packages/protocol/contracts/team/TimelockTokenPool.sol index d7c848abb3e..b4bcf12fae2 100644 --- a/packages/protocol/contracts/team/TimelockTokenPool.sol +++ b/packages/protocol/contracts/team/TimelockTokenPool.sol @@ -186,7 +186,7 @@ contract TimelockTokenPool is EssentialContract { totalCostPaid += costToWithdraw; IERC20(taikoToken).transferFrom(sharedVault, to, amountToWithdraw); - IERC20(costToken).safeTransferFrom(recipient, sharedVault, costToWithdraw); + IERC20(costToken).transferFrom(recipient, sharedVault, costToWithdraw); emit Withdrawn(recipient, to, amountToWithdraw, costToWithdraw); } diff --git a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol index c11712b02cc..89ccafec042 100644 --- a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol +++ b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol @@ -14,7 +14,7 @@ pragma solidity 0.8.20; -import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; import "./MerkleClaimable.sol"; /// @title ERC20Airdrop @@ -43,6 +43,6 @@ contract ERC20Airdrop is MerkleClaimable { function _claimWithData(bytes calldata data) internal override { (address user, uint256 amount) = abi.decode(data, (address, uint256)); - IERC20(token).transferFrom(vault, user, amount); + IERC20Upgradeable(token).transferFrom(vault, user, amount); } } diff --git a/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol b/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol index d72e5dcd976..dcaeb0a9792 100644 --- a/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol +++ b/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol @@ -14,7 +14,7 @@ pragma solidity 0.8.20; -import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; import "../../libs/LibMath.sol"; import "./MerkleClaimable.sol"; @@ -71,7 +71,7 @@ contract ERC20Airdrop2 is MerkleClaimable { function withdraw(address user) external ongoingWithdrawals { (, uint256 amount) = getBalance(user); withdrawnAmount[user] += amount; - IERC20(token).transferFrom(vault, user, amount); + IERC20Upgradeable(token).transferFrom(vault, user, amount); emit Withdrawn(user, amount); } diff --git a/packages/protocol/contracts/tokenvault/ERC20Vault.sol b/packages/protocol/contracts/tokenvault/ERC20Vault.sol index 2c140806ab5..c3f517a739d 100644 --- a/packages/protocol/contracts/tokenvault/ERC20Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC20Vault.sol @@ -256,27 +256,22 @@ contract ERC20Vault is BaseVault { { checkRecallMessageContext(); - (CanonicalERC20 memory ctoken,,, uint256 amount) = + (, address token,, uint256 amount) = abi.decode(message.data[4:], (CanonicalERC20, address, address, uint256)); - if (ctoken.addr == address(0)) revert VAULT_INVALID_TOKEN(); + if (token == address(0)) revert VAULT_INVALID_TOKEN(); if (amount > 0) { - if (bridgedToCanonical[ctoken.addr].addr != address(0)) { - IBridgedERC20(ctoken.addr).mint(message.owner, amount); + if (bridgedToCanonical[token].addr != address(0)) { + IBridgedERC20(token).mint(message.owner, amount); } else { - ERC20(ctoken.addr).safeTransfer(message.owner, amount); + ERC20(token).safeTransfer(message.owner, amount); } } message.owner.sendEther(message.value); - emit TokenReleased({ - msgHash: msgHash, - from: message.owner, - token: ctoken.addr, - amount: amount - }); + emit TokenReleased({ msgHash: msgHash, from: message.owner, token: token, amount: amount }); } function name() public pure override returns (bytes32) { diff --git a/packages/protocol/contracts/tokenvault/ERC721Vault.sol b/packages/protocol/contracts/tokenvault/ERC721Vault.sol index dd93eea0a85..856422bff45 100644 --- a/packages/protocol/contracts/tokenvault/ERC721Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC721Vault.sol @@ -234,7 +234,7 @@ contract ERC721Vault is BaseNFTVault, IERC721ReceiverUpgradeable { }); for (uint256 i; i < op.tokenIds.length; ++i) { - t.safeTransferFrom(user, address(this), op.tokenIds[i]); + t.transferFrom(user, address(this), op.tokenIds[i]); } } } diff --git a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol index aaeb11265d1..fa4851d7571 100644 --- a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol +++ b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol @@ -19,7 +19,7 @@ import "../BridgedERC20Base.sol"; interface IUSDC { function burn(uint256 amount) external; function mint(address to, uint256 amount) external; - function transferFrom(address from, address to, uint256 value) external returns (bool); + function transferFrom(address from, address to, uint256 amount) external; } /// @title USDCAdaptor diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol index 17e698e8dc9..bdf8dbe0850 100644 --- a/packages/protocol/script/SetDcapParams.s.sol +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -18,18 +18,15 @@ import "forge-std/Script.sol"; import "forge-std/console2.sol"; import "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; -import "../contracts/L1/verifiers/SgxVerifier.sol"; import "../test/onchainRA/utils/DcapTestUtils.t.sol"; -import "../test/onchainRA/utils/V3JsonUtils.t.sol"; -contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { +contract SetAddress is Script, DcapTestUtils { //@todo: Wand Yue -> after deployed with DeployOnL1, you have the parameters, fill in the proper // .env vars the the parameter files, and run this script. uint256 public ownerPrivateKey = vm.envUint("PRIVATE_KEY"); // Owner of the attestation contract address public dcapAttestationAddress = vm.envAddress("ATTESTATION_ADDRESS"); - address public sgxVerifier = vm.envAddress("SGX_VERIFIER_ADDRESS"); string public tcbInfoPath = vm.envString("TCB_INFO_PATH"); - string public idPath = vm.envString("QEID_PATH"); + string public idPath = vm.envString("TCB_ID_PATH"); string public v3QuotePath = vm.envString("V3_QUOTE_PATH"); bytes32 public mrEnclave = vm.envBytes32("MR_ENCLAVE"); bytes32 public mrSigner = vm.envBytes32("MR_SIGNER"); @@ -40,52 +37,23 @@ contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { vm.startBroadcast(ownerPrivateKey); - // all in one - setMrEnclave(); - setMrSigner(); - configureQeIdentityJson(); - configureTcbInfoJson(); - registerSgxInstanceWithQuote(); - - vm.stopBroadcast(); - } - - function setMrEnclave() internal { AutomataDcapV3Attestation(dcapAttestationAddress).setMrEnclave(mrEnclave, true); - } - - function setMrSigner() internal { AutomataDcapV3Attestation(dcapAttestationAddress).setMrSigner(mrSigner, true); - } - function configureQeIdentityJson() internal { + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); - (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); - console.log("qeIdParsedSuccess: %s", qeIdParsedSuccess); - } - function configureTcbInfoJson() internal { - string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + string memory fmspc = "00606a000000"; (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = parseTcbInfoJson(tcbInfoJson); - // string memory fmspc = "00606a000000"; - string memory fmspc = parsedTcbInfo.fmspc; + require(tcbParsedSuccess, "tcb parsed failed"); AutomataDcapV3Attestation(dcapAttestationAddress).configureTcbInfoJson(fmspc, parsedTcbInfo); - console.log("tcbParsedSuccess: %s", tcbParsedSuccess); - } - function registerSgxInstanceWithQuote() internal { - string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); - console.log("[LOG] v3QuoteJsonStr: %s", v3QuoteJsonStr); - bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); - console.logBytes(v3QuotePacked); + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + require(qeIdParsedSuccess, "qeid parsed failed"); + AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); - (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); - console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); - console.logBytes(v3quote.localEnclaveReport.reportData); - uint256 ret = SgxVerifier(sgxVerifier).registerInstance(v3quote); - console.log("ret: %s", ret); + vm.stopBroadcast(); } } From 859396cab59663a5b3fd2bb00b85cbc6c0322dce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Mon, 29 Jan 2024 14:39:24 +0530 Subject: [PATCH 23/44] forge fmt --- .../onchainRA/AutomataDcapV3Attestation.sol | 1 - .../onchainRA/interfaces/IAttestation.sol | 4 +- .../onchainRA/interfaces/ISigVerifyLib.sol | 30 +++- .../onchainRA/lib/QuoteV3Auth/V3Parser.sol | 154 ++++++------------ .../onchainRA/lib/QuoteV3Auth/V3Struct.sol | 6 +- .../lib/interfaces/IPEMCertChainLib.sol | 10 +- .../thirdparty/onchainRA/utils/Asn1Decode.sol | 9 +- .../thirdparty/onchainRA/utils/BytesUtils.sol | 79 +++++++-- .../thirdparty/onchainRA/utils/RsaVerify.sol | 123 ++++++++++++-- .../thirdparty/onchainRA/utils/SHA1.sol | 61 +++++-- .../onchainRA/utils/SigVerifyLib.sol | 32 +++- .../onchainRA/utils/X509DateUtils.sol | 17 +- packages/protocol/test/L1/TaikoL1TestBase.sol | 7 +- packages/protocol/test/TaikoTest.sol | 3 +- .../AutomataDcapV3AttestationTest.t.sol | 1 - 15 files changed, 370 insertions(+), 167 deletions(-) diff --git a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol index 09f08a1ab09..e476101a55f 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol @@ -370,7 +370,6 @@ contract AutomataDcapV3Attestation is IAttestation { bool certChainCanBeTrusted; for (uint256 i = 0; i < n; i++) { - IPEMCertChainLib.ECSha256Certificate memory issuer; if (i == n - 1) { // rootCA diff --git a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol index fd58de009fb..95494455d18 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol @@ -5,5 +5,7 @@ import { V3Struct } from "../lib/QuoteV3Auth/V3Struct.sol"; interface IAttestation { function verifyAttestation(bytes calldata data) external returns (bool); - function verifyParsedQuote(V3Struct.ParsedV3QuoteStruct calldata v3quote)external returns (bool success, uint8 exitStep); + function verifyParsedQuote(V3Struct.ParsedV3QuoteStruct calldata v3quote) + external + returns (bool success, uint8 exitStep); } diff --git a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol index 8ff441a236c..0ab36429783 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol @@ -33,7 +33,12 @@ interface ISigVerifyLib { RS1 } - function verifyAttStmtSignature(bytes memory tbs, bytes memory signature, PublicKey memory publicKey, Algorithm alg) + function verifyAttStmtSignature( + bytes memory tbs, + bytes memory signature, + PublicKey memory publicKey, + Algorithm alg + ) external view returns (bool); @@ -43,19 +48,34 @@ interface ISigVerifyLib { bytes memory signature, PublicKey memory publicKey, CertSigAlgorithm alg - ) external view returns (bool); + ) + external + view + returns (bool); - function verifyRS256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + function verifyRS256Signature( + bytes memory tbs, + bytes memory signature, + bytes memory publicKey + ) external view returns (bool sigValid); - function verifyRS1Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + function verifyRS1Signature( + bytes memory tbs, + bytes memory signature, + bytes memory publicKey + ) external view returns (bool sigValid); - function verifyES256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + function verifyES256Signature( + bytes memory tbs, + bytes memory signature, + bytes memory publicKey + ) external view returns (bool sigValid); diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol index 6582976ba11..653786c97f1 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol @@ -1,8 +1,8 @@ //SPDX-License-Identifier: MIT pragma solidity ^0.8.0; -import {BytesUtils} from "../../utils/BytesUtils.sol"; -import {V3Struct} from "./V3Struct.sol"; +import { BytesUtils } from "../../utils/BytesUtils.sol"; +import { V3Struct } from "./V3Struct.sol"; // import {PEMCertChainLib} from "../PEMCertChainLib.sol"; // import "hardhat/console.sol"; @@ -23,9 +23,7 @@ library V3Parser { uint256 constant HEADER_LENGTH = 27; uint256 constant FOOTER_LENGTH = 25; - function parseInput( - bytes memory quote - ) + function parseInput(bytes memory quote) internal pure returns ( @@ -37,54 +35,26 @@ library V3Parser { ) { if (quote.length <= MINIMUM_QUOTE_LENGTH) { - return ( - false, - header, - localEnclaveReport, - signedQuoteData, - authDataV3 - ); + return (false, header, localEnclaveReport, signedQuoteData, authDataV3); } uint256 localAuthDataSize = littleEndianDecode(quote.substring(432, 4)); if (quote.length - 436 != localAuthDataSize) { - return ( - false, - header, - localEnclaveReport, - signedQuoteData, - authDataV3 - ); + return (false, header, localEnclaveReport, signedQuoteData, authDataV3); } bytes memory rawHeader = quote.substring(0, 48); bool headerVerifiedSuccessfully; (headerVerifiedSuccessfully, header) = parseAndVerifyHeader(rawHeader); if (!headerVerifiedSuccessfully) { - return ( - false, - header, - localEnclaveReport, - signedQuoteData, - authDataV3 - ); + return (false, header, localEnclaveReport, signedQuoteData, authDataV3); } bool authDataVerifiedSuccessfully; - ( - authDataVerifiedSuccessfully, - authDataV3 - ) = parseAuthDataAndVerifyCertType( - quote.substring(436, localAuthDataSize) - ); + (authDataVerifiedSuccessfully, authDataV3) = + parseAuthDataAndVerifyCertType(quote.substring(436, localAuthDataSize)); if (!authDataVerifiedSuccessfully) { - return ( - false, - header, - localEnclaveReport, - signedQuoteData, - authDataV3 - ); + return (false, header, localEnclaveReport, signedQuoteData, authDataV3); } bytes memory rawLocalEnclaveReport = quote.substring(48, 384); @@ -94,9 +64,7 @@ library V3Parser { success = true; } - function validateParsedInput( - V3Struct.ParsedV3QuoteStruct calldata v3Quote - ) + function validateParsedInput(V3Struct.ParsedV3QuoteStruct calldata v3Quote) internal pure returns ( @@ -109,20 +77,16 @@ library V3Parser { { success = true; localEnclaveReport = v3Quote.localEnclaveReport; - V3Struct.EnclaveReport memory pckSignedQeReport = v3Quote - .v3AuthData - .pckSignedQeReport; + V3Struct.EnclaveReport memory pckSignedQeReport = v3Quote.v3AuthData.pckSignedQeReport; require( - localEnclaveReport.reserved3.length == 96 && - localEnclaveReport.reserved4.length == 60 && - localEnclaveReport.reportData.length == 64, + localEnclaveReport.reserved3.length == 96 && localEnclaveReport.reserved4.length == 60 + && localEnclaveReport.reportData.length == 64, "local QE report has wrong length" ); require( - pckSignedQeReport.reserved3.length == 96 && - pckSignedQeReport.reserved4.length == 60 && - pckSignedQeReport.reportData.length == 64, + pckSignedQeReport.reserved3.length == 96 && pckSignedQeReport.reserved4.length == 60 + && pckSignedQeReport.reportData.length == 64, "QE report has wrong length" ); require( @@ -130,18 +94,17 @@ library V3Parser { "certType must be 5: Concatenated PCK Cert Chain (PEM formatted)" ); require( - v3Quote.v3AuthData.certification.decodedCertDataArray.length == 3, - "3 certs in chain" + v3Quote.v3AuthData.certification.decodedCertDataArray.length == 3, "3 certs in chain" ); require( - v3Quote.v3AuthData.ecdsa256BitSignature.length == 64 && - v3Quote.v3AuthData.ecdsaAttestationKey.length == 64 && - v3Quote.v3AuthData.qeReportSignature.length == 64, + v3Quote.v3AuthData.ecdsa256BitSignature.length == 64 + && v3Quote.v3AuthData.ecdsaAttestationKey.length == 64 + && v3Quote.v3AuthData.qeReportSignature.length == 64, "Invalid ECDSA signature format" ); require( - v3Quote.v3AuthData.qeAuthData.parsedDataSize == - v3Quote.v3AuthData.qeAuthData.data.length, + v3Quote.v3AuthData.qeAuthData.parsedDataSize + == v3Quote.v3AuthData.qeAuthData.data.length, "Invalid QEAuthData size" ); @@ -167,14 +130,14 @@ library V3Parser { // "Invalid certData size" // ); - uint32 totalQuoteSize = 48 + // header - 384 + // local QE report - 64 + // ecdsa256BitSignature - 64 + // ecdsaAttestationKey - 384 + // QE report - 64 + // qeReportSignature - v3Quote.v3AuthData.qeAuthData.parsedDataSize + - v3Quote.v3AuthData.certification.certDataSize; + uint32 totalQuoteSize = 48 // header + + 384 // local QE report + + 64 // ecdsa256BitSignature + + 64 // ecdsaAttestationKey + + 384 // QE report + + 64 // qeReportSignature + + v3Quote.v3AuthData.qeAuthData.parsedDataSize + + v3Quote.v3AuthData.certification.certDataSize; require(totalQuoteSize >= MINIMUM_QUOTE_LENGTH, "Invalid quote size"); header = v3Quote.header; @@ -188,16 +151,15 @@ library V3Parser { header.userData ); - signedQuoteData = abi.encodePacked( - headerBytes, - V3Parser.packQEReport(localEnclaveReport) - ); + signedQuoteData = abi.encodePacked(headerBytes, V3Parser.packQEReport(localEnclaveReport)); authDataV3 = v3Quote.v3AuthData; } - function parseEnclaveReport( - bytes memory rawEnclaveReport - ) internal pure returns (V3Struct.EnclaveReport memory enclaveReport) { + function parseEnclaveReport(bytes memory rawEnclaveReport) + internal + pure + returns (V3Struct.EnclaveReport memory enclaveReport) + { enclaveReport.cpuSvn = bytes16(rawEnclaveReport.substring(0, 16)); enclaveReport.miscSelect = bytes4(rawEnclaveReport.substring(16, 4)); enclaveReport.reserved1 = bytes28(rawEnclaveReport.substring(20, 28)); @@ -206,19 +168,13 @@ library V3Parser { enclaveReport.reserved2 = bytes32(rawEnclaveReport.substring(96, 32)); enclaveReport.mrSigner = bytes32(rawEnclaveReport.substring(128, 32)); enclaveReport.reserved3 = rawEnclaveReport.substring(160, 96); - enclaveReport.isvProdId = uint16( - littleEndianDecode(rawEnclaveReport.substring(256, 2)) - ); - enclaveReport.isvSvn = uint16( - littleEndianDecode(rawEnclaveReport.substring(258, 2)) - ); + enclaveReport.isvProdId = uint16(littleEndianDecode(rawEnclaveReport.substring(256, 2))); + enclaveReport.isvSvn = uint16(littleEndianDecode(rawEnclaveReport.substring(258, 2))); enclaveReport.reserved4 = rawEnclaveReport.substring(260, 60); enclaveReport.reportData = rawEnclaveReport.substring(320, 64); } - function littleEndianDecode( - bytes memory encoded - ) private pure returns (uint256 decoded) { + function littleEndianDecode(bytes memory encoded) private pure returns (uint256 decoded) { for (uint256 i = 0; i < encoded.length; i++) { uint256 digits = uint256(uint8(bytes1(encoded[i]))); uint256 upperDigit = digits / 16; @@ -231,9 +187,11 @@ library V3Parser { } } - function parseAndVerifyHeader( - bytes memory rawHeader - ) private pure returns (bool success, V3Struct.Header memory header) { + function parseAndVerifyHeader(bytes memory rawHeader) + private + pure + returns (bool success, V3Struct.Header memory header) + { bytes2 version = bytes2(rawHeader.substring(0, 2)); if (version != SUPPORTED_QUOTE_VERSION) { return (false, header); @@ -267,17 +225,13 @@ library V3Parser { success = true; } - function parseAuthDataAndVerifyCertType( - bytes memory rawAuthData - ) + function parseAuthDataAndVerifyCertType(bytes memory rawAuthData) private pure returns (bool success, V3Struct.ECDSAQuoteV3AuthData memory authDataV3) { V3Struct.QEAuthData memory qeAuthData; - qeAuthData.parsedDataSize = littleEndianDecode( - rawAuthData.substring(576, 2) - ); + qeAuthData.parsedDataSize = littleEndianDecode(rawAuthData.substring(576, 2)); qeAuthData.data = rawAuthData.substring(578, qeAuthData.parsedDataSize); uint256 offset = 578 + qeAuthData.parsedDataSize; @@ -287,9 +241,7 @@ library V3Parser { return (false, authDataV3); } offset += 2; - cert.certDataSize = littleEndianDecode( - rawAuthData.substring(offset, 4) - ); + cert.certDataSize = littleEndianDecode(rawAuthData.substring(offset, 4)); offset += 4; cert.certData = rawAuthData.substring(offset, cert.certDataSize); @@ -310,13 +262,13 @@ library V3Parser { /// in bytes should be in big endian according to Intel spec. /// @param enclaveReport enclave report /// @return packedQEReport enclave report in bytes - function packQEReport( - V3Struct.EnclaveReport memory enclaveReport - ) internal pure returns (bytes memory packedQEReport) { - uint16 isvProdIdPackBE = (enclaveReport.isvProdId >> 8) | - (enclaveReport.isvProdId << 8); - uint16 isvSvnPackBE = (enclaveReport.isvSvn >> 8) | - (enclaveReport.isvSvn << 8); + function packQEReport(V3Struct.EnclaveReport memory enclaveReport) + internal + pure + returns (bytes memory packedQEReport) + { + uint16 isvProdIdPackBE = (enclaveReport.isvProdId >> 8) | (enclaveReport.isvProdId << 8); + uint16 isvSvnPackBE = (enclaveReport.isvSvn >> 8) | (enclaveReport.isvSvn << 8); packedQEReport = abi.encodePacked( enclaveReport.cpuSvn, enclaveReport.miscSelect, diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol index 2e9767833ea..33b6b0c4f1d 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol @@ -24,7 +24,8 @@ library V3Struct { uint16 isvProdId; uint16 isvSvn; bytes reserved4; // 60 bytes - bytes reportData; // 64 bytes - For QEReports, this contains the hash of the concatenation of attestation key and QEAuthData + bytes reportData; // 64 bytes - For QEReports, this contains the hash of the concatenation + // of attestation key and QEAuthData } struct QEAuthData { @@ -49,7 +50,8 @@ library V3Struct { struct ParsedCertificationData { uint16 certType; // avoid uint256 -> uint32 conversion to save gas - uint32 certDataSize; // todo! certDataSize = len(join((BEGIN_CERT, certArray[i], END_CERT) for i in 0..3)) + uint32 certDataSize; // todo! certDataSize = len(join((BEGIN_CERT, certArray[i], END_CERT) + // for i in 0..3)) bytes[3] decodedCertDataArray; // base64 decoded cert bytes array } diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol index 5b0d9531ce0..c6a0de81f23 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol @@ -31,12 +31,18 @@ interface IPEMCertChainLib { ROOT } - function splitCertificateChain(bytes memory pemChain, uint256 size) + function splitCertificateChain( + bytes memory pemChain, + uint256 size + ) external pure returns (bool success, bytes[] memory certs); - function decodeCert(bytes memory der, bool isPckCert) + function decodeCert( + bytes memory der, + bool isPckCert + ) external pure returns (bool success, ECSha256Certificate memory cert); diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol index 30f6947f675..f0708f76fa2 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol @@ -92,7 +92,10 @@ library Asn1Decode { * @return True iff j is child of i or i is child of j. */ function isChildOf(uint256 i, uint256 j) internal pure returns (bool) { - return (((i.ixf() <= j.ixs()) && (j.ixl() <= i.ixl())) || ((j.ixf() <= i.ixs()) && (i.ixl() <= j.ixl()))); + return ( + ((i.ixf() <= j.ixs()) && (j.ixl() <= i.ixl())) + || ((j.ixf() <= i.ixs()) && (i.ixl() <= j.ixl())) + ); } /* @@ -192,7 +195,9 @@ library Asn1Decode { } else if (lengthbytesLength == 2) { length = der.readUint16(ix + 2); } else { - length = uint256(der.readBytesN(ix + 2, lengthbytesLength) >> (32 - lengthbytesLength) * 8); + length = uint256( + der.readBytesN(ix + 2, lengthbytesLength) >> (32 - lengthbytesLength) * 8 + ); } ixFirstContentByte = uint80(ix + 2 + lengthbytesLength); ixLastContentByte = uint80(ixFirstContentByte + length - 1); diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol index 8d03feff88a..8f88a60edd3 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol @@ -12,7 +12,15 @@ library BytesUtils { * @param len The number of bytes to hash. * @return The hash of the byte range. */ - function keccak(bytes memory self, uint256 offset, uint256 len) internal pure returns (bytes32 ret) { + function keccak( + bytes memory self, + uint256 offset, + uint256 len + ) + internal + pure + returns (bytes32 ret) + { require(offset + len <= self.length); assembly { ret := keccak256(add(add(self, 32), offset), len) @@ -51,7 +59,11 @@ library BytesUtils { bytes memory other, uint256 otheroffset, uint256 otherlen - ) internal pure returns (int256) { + ) + internal + pure + returns (int256) + { uint256 shortest = len; if (otherlen < len) { shortest = otherlen; @@ -100,7 +112,13 @@ library BytesUtils { * @param len The number of bytes to compare * @return True if the byte ranges are equal, false otherwise. */ - function equals(bytes memory self, uint256 offset, bytes memory other, uint256 otherOffset, uint256 len) + function equals( + bytes memory self, + uint256 offset, + bytes memory other, + uint256 otherOffset, + uint256 len + ) internal pure returns (bool) @@ -116,12 +134,18 @@ library BytesUtils { * @param otherOffset The offset into the second byte range. * @return True if the byte ranges are equal, false otherwise. */ - function equals(bytes memory self, uint256 offset, bytes memory other, uint256 otherOffset) + function equals( + bytes memory self, + uint256 offset, + bytes memory other, + uint256 otherOffset + ) internal pure returns (bool) { - return keccak(self, offset, self.length - offset) == keccak(other, otherOffset, other.length - otherOffset); + return keccak(self, offset, self.length - offset) + == keccak(other, otherOffset, other.length - otherOffset); } /* @@ -132,7 +156,15 @@ library BytesUtils { * @param other The second byte range to compare. * @return True if the byte ranges are equal, false otherwise. */ - function equals(bytes memory self, uint256 offset, bytes memory other) internal pure returns (bool) { + function equals( + bytes memory self, + uint256 offset, + bytes memory other + ) + internal + pure + returns (bool) + { return self.length >= offset + other.length && equals(self, offset, other, 0, other.length); } @@ -205,7 +237,10 @@ library BytesUtils { require(idx + 20 <= self.length); assembly { ret := - and(mload(add(add(self, 32), idx)), 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000) + and( + mload(add(add(self, 32), idx)), + 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000000 + ) } } @@ -216,7 +251,15 @@ library BytesUtils { * @param len The number of bytes. * @return The specified 32 bytes of the string. */ - function readBytesN(bytes memory self, uint256 idx, uint256 len) internal pure returns (bytes32 ret) { + function readBytesN( + bytes memory self, + uint256 idx, + uint256 len + ) + internal + pure + returns (bytes32 ret) + { require(len <= 32); require(idx + len <= self.length); assembly { @@ -256,7 +299,15 @@ library BytesUtils { * @param offset The offset to start copying at. * @param len The number of bytes to copy. */ - function substring(bytes memory self, uint256 offset, uint256 len) internal pure returns (bytes memory) { + function substring( + bytes memory self, + uint256 offset, + uint256 len + ) + internal + pure + returns (bytes memory) + { require(offset + len <= self.length); bytes memory ret = new bytes(len); @@ -284,7 +335,15 @@ library BytesUtils { * @param len Number of characters to decode. * @return The decoded data, left aligned. */ - function base32HexDecodeWord(bytes memory self, uint256 off, uint256 len) internal pure returns (bytes32) { + function base32HexDecodeWord( + bytes memory self, + uint256 off, + uint256 len + ) + internal + pure + returns (bytes32) + { require(len <= 52); uint256 ret = 0; diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol index cafb4fa7b9d..51f6a2816d3 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol @@ -24,7 +24,7 @@ import "./SHA1.sol"; along with this program. If not, see . Checked results with FIPS test vectors - https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss/186-2rsatestvectors.zip +https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-Validation-Program/documents/dss/186-2rsatestvectors.zip file SigVer15_186-3.rsp */ @@ -38,26 +38,73 @@ library RsaVerify { * @param _m is the modulus * @return true if success, false otherwise */ - function pkcs1Sha256(bytes32 _sha256, bytes memory _s, bytes memory _e, bytes memory _m) + function pkcs1Sha256( + bytes32 _sha256, + bytes memory _s, + bytes memory _e, + bytes memory _m + ) internal view returns (bool) { - uint8[17] memory sha256ExplicitNullParam = - [0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00]; - - uint8[15] memory sha256ImplicitNullParam = - [0x30, 0x2f, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01]; + uint8[17] memory sha256ExplicitNullParam = [ + 0x30, + 0x31, + 0x30, + 0x0d, + 0x06, + 0x09, + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x02, + 0x01, + 0x05, + 0x00 + ]; + + uint8[15] memory sha256ImplicitNullParam = [ + 0x30, + 0x2f, + 0x30, + 0x0b, + 0x06, + 0x09, + 0x60, + 0x86, + 0x48, + 0x01, + 0x65, + 0x03, + 0x04, + 0x02, + 0x01 + ]; // decipher - bytes memory input = bytes.concat(bytes32(_s.length), bytes32(_e.length), bytes32(_m.length), _s, _e, _m); + bytes memory input = + bytes.concat(bytes32(_s.length), bytes32(_e.length), bytes32(_m.length), _s, _e, _m); uint256 inputlen = input.length; uint256 decipherlen = _m.length; bytes memory decipher = new bytes(decipherlen); assembly { - pop(staticcall(sub(gas(), 2000), 5, add(input, 0x20), inputlen, add(decipher, 0x20), decipherlen)) + pop( + staticcall( + sub(gas(), 2000), + 5, + add(input, 0x20), + inputlen, + add(decipher, 0x20), + decipherlen + ) + ) } // Check that is well encoded: @@ -139,7 +186,12 @@ library RsaVerify { * @param _m is the modulus * @return 0 if success, >0 otherwise */ - function pkcs1Sha256Raw(bytes memory _data, bytes memory _s, bytes memory _e, bytes memory _m) + function pkcs1Sha256Raw( + bytes memory _data, + bytes memory _s, + bytes memory _e, + bytes memory _m + ) internal view returns (bool) @@ -155,18 +207,52 @@ library RsaVerify { * @param _m is the modulus * @return true if success, false otherwise */ - function pkcs1Sha1(bytes20 _sha1, bytes memory _s, bytes memory _e, bytes memory _m) internal view returns (bool) { - uint8[15] memory sha1Prefix = - [0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14]; + function pkcs1Sha1( + bytes20 _sha1, + bytes memory _s, + bytes memory _e, + bytes memory _m + ) + internal + view + returns (bool) + { + uint8[15] memory sha1Prefix = [ + 0x30, + 0x21, + 0x30, + 0x09, + 0x06, + 0x05, + 0x2b, + 0x0e, + 0x03, + 0x02, + 0x1a, + 0x05, + 0x00, + 0x04, + 0x14 + ]; // decipher - bytes memory input = bytes.concat(bytes32(_s.length), bytes32(_e.length), bytes32(_m.length), _s, _e, _m); + bytes memory input = + bytes.concat(bytes32(_s.length), bytes32(_e.length), bytes32(_m.length), _s, _e, _m); uint256 inputlen = input.length; uint256 decipherlen = _m.length; bytes memory decipher = new bytes(decipherlen); assembly { - pop(staticcall(sub(gas(), 2000), 5, add(input, 0x20), inputlen, add(decipher, 0x20), decipherlen)) + pop( + staticcall( + sub(gas(), 2000), + 5, + add(input, 0x20), + inputlen, + add(decipher, 0x20), + decipherlen + ) + ) } // Check that is well encoded: @@ -216,7 +302,12 @@ library RsaVerify { * @param _m is the modulus * @return 0 if success, >0 otherwise */ - function pkcs1Sha1Raw(bytes memory _data, bytes memory _s, bytes memory _e, bytes memory _m) + function pkcs1Sha1Raw( + bytes memory _data, + bytes memory _s, + bytes memory _e, + bytes memory _m + ) internal view returns (bool) diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol index cac01764a64..86cd534ce67 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol @@ -57,8 +57,14 @@ library SHA1 { ) temp := or( - and(mul(temp, 2), 0xFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFE), - and(div(temp, 0x80000000), 0x0000000100000001000000010000000100000001000000010000000100000001) + and( + mul(temp, 2), + 0xFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFEFFFFFFFE + ), + and( + div(temp, 0x80000000), + 0x0000000100000001000000010000000100000001000000010000000100000001 + ) ) mstore(add(scratch, j), temp) } @@ -70,8 +76,14 @@ library SHA1 { ) temp := or( - and(mul(temp, 4), 0xFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFC), - and(div(temp, 0x40000000), 0x0000000300000003000000030000000300000003000000030000000300000003) + and( + mul(temp, 4), + 0xFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFCFFFFFFFC + ), + and( + div(temp, 0x40000000), + 0x0000000300000003000000030000000300000003000000030000000300000003 + ) ) mstore(add(scratch, j), temp) } @@ -90,35 +102,62 @@ library SHA1 { } case 1 { // f = b xor c xor d - f := xor(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)) + f := + xor( + div(x, 0x1000000000000000000000000000000), + div(x, 0x100000000000000000000) + ) f := xor(div(x, 0x10000000000), f) k := 0x6ED9EBA1 } case 2 { // f = (b and c) or (d and (b or c)) - f := or(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)) + f := + or( + div(x, 0x1000000000000000000000000000000), + div(x, 0x100000000000000000000) + ) f := and(div(x, 0x10000000000), f) - f := or(and(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)), f) + f := + or( + and( + div(x, 0x1000000000000000000000000000000), + div(x, 0x100000000000000000000) + ), + f + ) k := 0x8F1BBCDC } case 3 { // f = b xor c xor d - f := xor(div(x, 0x1000000000000000000000000000000), div(x, 0x100000000000000000000)) + f := + xor( + div(x, 0x1000000000000000000000000000000), + div(x, 0x100000000000000000000) + ) f := xor(div(x, 0x10000000000), f) k := 0xCA62C1D6 } // temp = (a leftrotate 5) + f + e + k + w[i] let temp := and(div(x, 0x80000000000000000000000000000000000000000000000), 0x1F) - temp := or(and(div(x, 0x800000000000000000000000000000000000000), 0xFFFFFFE0), temp) + temp := + or(and(div(x, 0x800000000000000000000000000000000000000), 0xFFFFFFE0), temp) temp := add(f, temp) temp := add(and(x, 0xFFFFFFFF), temp) temp := add(k, temp) temp := add( - div(mload(add(scratch, mul(j, 4))), 0x100000000000000000000000000000000000000000000000000000000), + div( + mload(add(scratch, mul(j, 4))), + 0x100000000000000000000000000000000000000000000000000000000 + ), temp ) - x := or(div(x, 0x10000000000), mul(temp, 0x10000000000000000000000000000000000000000)) + x := + or( + div(x, 0x10000000000), + mul(temp, 0x10000000000000000000000000000000000000000) + ) x := or( and(x, 0xFFFFFFFF00FFFFFFFF000000000000FFFFFFFF00FFFFFFFF), diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol index 11814ae18bf..d9fc0e17f72 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol @@ -13,13 +13,19 @@ import "./BytesUtils.sol"; contract SigVerifyLib is ISigVerifyLib { using BytesUtils for bytes; + address private ES256VERIFIER; constructor(address es256Verifier) { ES256VERIFIER = es256Verifier; } - function verifyAttStmtSignature(bytes memory tbs, bytes memory signature, PublicKey memory publicKey, Algorithm alg) + function verifyAttStmtSignature( + bytes memory tbs, + bytes memory signature, + PublicKey memory publicKey, + Algorithm alg + ) public view returns (bool) @@ -49,7 +55,11 @@ contract SigVerifyLib is ISigVerifyLib { bytes memory signature, PublicKey memory publicKey, CertSigAlgorithm alg - ) public view returns (bool) { + ) + public + view + returns (bool) + { if (alg == CertSigAlgorithm.Sha256WithRSAEncryption) { if (publicKey.keyType != KeyType.RSA) { return false; @@ -65,7 +75,11 @@ contract SigVerifyLib is ISigVerifyLib { } } - function verifyRS256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + function verifyRS256Signature( + bytes memory tbs, + bytes memory signature, + bytes memory publicKey + ) public view returns (bool sigValid) @@ -78,7 +92,11 @@ contract SigVerifyLib is ISigVerifyLib { sigValid = RsaVerify.pkcs1Sha256Raw(tbs, signature, exponent, modulus); } - function verifyRS1Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + function verifyRS1Signature( + bytes memory tbs, + bytes memory signature, + bytes memory publicKey + ) public view returns (bool sigValid) @@ -91,7 +109,11 @@ contract SigVerifyLib is ISigVerifyLib { sigValid = RsaVerify.pkcs1Sha1Raw(tbs, signature, exponent, modulus); } - function verifyES256Signature(bytes memory tbs, bytes memory signature, bytes memory publicKey) + function verifyES256Signature( + bytes memory tbs, + bytes memory signature, + bytes memory publicKey + ) public view returns (bool sigValid) diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol b/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol index 26f53ee4239..f7ce2872ea6 100644 --- a/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol +++ b/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol @@ -29,7 +29,14 @@ library X509DateUtils { return toUnixTimestamp(yrs, mnths, dys, hrs, mins, secs); } - function toUnixTimestamp(uint16 year, uint8 month, uint8 day, uint8 hour, uint8 minute, uint8 second) + function toUnixTimestamp( + uint16 year, + uint8 month, + uint8 day, + uint8 hour, + uint8 minute, + uint8 second + ) internal pure returns (uint256) @@ -38,9 +45,9 @@ library X509DateUtils { for (uint16 i = 1970; i < year; i++) { if (isLeapYear(i)) { - timestamp += 31622400; // Leap year in seconds + timestamp += 31_622_400; // Leap year in seconds } else { - timestamp += 31536000; // Normal year in seconds + timestamp += 31_536_000; // Normal year in seconds } } @@ -48,10 +55,10 @@ library X509DateUtils { if (isLeapYear(year)) monthDays[1] = 29; for (uint8 i = 1; i < month; i++) { - timestamp += uint256(monthDays[i - 1]) * 86400; // Days in seconds + timestamp += uint256(monthDays[i - 1]) * 86_400; // Days in seconds } - timestamp += uint256(day - 1) * 86400; // Days in seconds + timestamp += uint256(day - 1) * 86_400; // Days in seconds timestamp += uint256(hour) * 3600; // Hours in seconds timestamp += uint256(minute) * 60; // Minutes in seconds timestamp += second; diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 4d7715eb89d..0d98fc3b406 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -24,7 +24,7 @@ abstract contract TaikoL1TestBase is TaikoTest { GuardianProver public gp; TaikoA6TierProvider public cp; Bridge public bridge; - + // For SGX remote attestation AutomataDcapV3Attestation attestation; SigVerifyLib sigVerifyLib; @@ -111,7 +111,7 @@ abstract contract TaikoL1TestBase is TaikoTest { setupGuardianProverMultisig(); setupAutomataOnChainRAUtils(); - + cp = TaikoA6TierProvider( deployProxy({ name: "tier_provider", @@ -175,7 +175,6 @@ abstract contract TaikoL1TestBase is TaikoTest { L1.init(address(addressManager), GENESIS_BLOCK_HASH); printVariables("init "); - } function proposeBlock( @@ -285,7 +284,7 @@ abstract contract TaikoL1TestBase is TaikoTest { } address newInstance; - + // Keep changing the pub key associated with an instance to avoid // attacks, // obviously just a mock due to 2 addresses changing all the time. diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index 901a234d6a6..58208251f0d 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -82,7 +82,8 @@ abstract contract TaikoTest is Test, DeployCapability, DcapTestUtils, V3JsonUtil address internal Zachary = randAddress(); address internal SGX_X_0 = vm.addr(0x4); address internal SGX_X_1 = vm.addr(0x5); - address internal SGX_Y = vm.addr(0x9b1bb8cb3bdb539d0d1f03951d27f167f2d5443e7ef0d7ce745cd4ec619d3dd7); + address internal SGX_Y = + vm.addr(0x9b1bb8cb3bdb539d0d1f03951d27f167f2d5443e7ef0d7ce745cd4ec619d3dd7); address internal SGX_Z = randAddress(); function randAddress() internal returns (address) { diff --git a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol index dca87fe4458..05b0892c40d 100644 --- a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol @@ -104,5 +104,4 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { //console.logBytes32(hash); assertEq(hash, 0xa27c4167ab139dffb020230b2ec856080d0e1af437b3a2c2beea1c9af17469bc); } - } From b5aa20965136f6841d1fa9f6d6cca5fca2136c2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Mon, 29 Jan 2024 14:44:10 +0530 Subject: [PATCH 24/44] fix set param --- packages/protocol/script/SetDcapParams.s.sol | 52 ++++++++++++++++---- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol index bdf8dbe0850..17e698e8dc9 100644 --- a/packages/protocol/script/SetDcapParams.s.sol +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -18,15 +18,18 @@ import "forge-std/Script.sol"; import "forge-std/console2.sol"; import "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; +import "../contracts/L1/verifiers/SgxVerifier.sol"; import "../test/onchainRA/utils/DcapTestUtils.t.sol"; +import "../test/onchainRA/utils/V3JsonUtils.t.sol"; -contract SetAddress is Script, DcapTestUtils { +contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { //@todo: Wand Yue -> after deployed with DeployOnL1, you have the parameters, fill in the proper // .env vars the the parameter files, and run this script. uint256 public ownerPrivateKey = vm.envUint("PRIVATE_KEY"); // Owner of the attestation contract address public dcapAttestationAddress = vm.envAddress("ATTESTATION_ADDRESS"); + address public sgxVerifier = vm.envAddress("SGX_VERIFIER_ADDRESS"); string public tcbInfoPath = vm.envString("TCB_INFO_PATH"); - string public idPath = vm.envString("TCB_ID_PATH"); + string public idPath = vm.envString("QEID_PATH"); string public v3QuotePath = vm.envString("V3_QUOTE_PATH"); bytes32 public mrEnclave = vm.envBytes32("MR_ENCLAVE"); bytes32 public mrSigner = vm.envBytes32("MR_SIGNER"); @@ -37,23 +40,52 @@ contract SetAddress is Script, DcapTestUtils { vm.startBroadcast(ownerPrivateKey); + // all in one + setMrEnclave(); + setMrSigner(); + configureQeIdentityJson(); + configureTcbInfoJson(); + registerSgxInstanceWithQuote(); + + vm.stopBroadcast(); + } + + function setMrEnclave() internal { AutomataDcapV3Attestation(dcapAttestationAddress).setMrEnclave(mrEnclave, true); + } + + function setMrSigner() internal { AutomataDcapV3Attestation(dcapAttestationAddress).setMrSigner(mrSigner, true); + } - string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + function configureQeIdentityJson() internal { string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); + console.log("qeIdParsedSuccess: %s", qeIdParsedSuccess); + } - string memory fmspc = "00606a000000"; + function configureTcbInfoJson() internal { + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = parseTcbInfoJson(tcbInfoJson); - require(tcbParsedSuccess, "tcb parsed failed"); + // string memory fmspc = "00606a000000"; + string memory fmspc = parsedTcbInfo.fmspc; AutomataDcapV3Attestation(dcapAttestationAddress).configureTcbInfoJson(fmspc, parsedTcbInfo); + console.log("tcbParsedSuccess: %s", tcbParsedSuccess); + } - (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - require(qeIdParsedSuccess, "qeid parsed failed"); - AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); + function registerSgxInstanceWithQuote() internal { + string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); + console.log("[LOG] v3QuoteJsonStr: %s", v3QuoteJsonStr); + bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); + console.logBytes(v3QuotePacked); - vm.stopBroadcast(); + (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); + console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); + console.logBytes(v3quote.localEnclaveReport.reportData); + uint256 ret = SgxVerifier(sgxVerifier).registerInstance(v3quote); + console.log("ret: %s", ret); } } From da73d6cd9b447db30ee26445f037d8ea90078bc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Mon, 29 Jan 2024 14:47:46 +0530 Subject: [PATCH 25/44] remove cached submodule --- packages/protocol/lib/automata-dcap-v3-attestation | 1 - 1 file changed, 1 deletion(-) delete mode 160000 packages/protocol/lib/automata-dcap-v3-attestation diff --git a/packages/protocol/lib/automata-dcap-v3-attestation b/packages/protocol/lib/automata-dcap-v3-attestation deleted file mode 160000 index 37369f1cf7b..00000000000 --- a/packages/protocol/lib/automata-dcap-v3-attestation +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 37369f1cf7b5af4ee58d0b8a93667386de56c37e From b06f34f801c31aa45bf715eb2a2193b87c7a2e91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Mon, 29 Jan 2024 22:09:28 +0530 Subject: [PATCH 26/44] PR findings and renamings --- .../contracts/L1/libs/LibProposing.sol | 6 +-- .../contracts/L1/provers/Guardians.sol | 5 ++- .../contracts/L1/verifiers/SgxVerifier.sol | 33 +++++++-------- packages/protocol/contracts/L2/TaikoL2.sol | 2 +- .../AutomataDcapV3Attestation.sol | 0 .../interfaces/IAttestation.sol | 0 .../interfaces/ISigVerifyLib.sol | 0 .../lib/EnclaveIdStruct.sol | 0 .../lib/PEMCertChainLib.sol | 0 .../lib/QuoteV3Auth/V3Parser.sol | 0 .../lib/QuoteV3Auth/V3Struct.sol | 0 .../lib/TCBInfoStruct.sol | 0 .../lib/interfaces/IPEMCertChainLib.sol | 0 .../utils/Asn1Decode.sol | 0 .../utils/BytesUtils.sol | 0 .../utils/RsaVerify.sol | 0 .../utils/SHA1.sol | 0 .../utils/SigVerifyLib.sol | 0 .../utils/X509DateUtils.sol | 0 packages/protocol/script/DeployOnL1.s.sol | 6 +-- packages/protocol/script/SetDcapParams.s.sol | 6 +-- packages/protocol/test/L1/SgxVerifier.t.sol | 40 +++++++++++++++++++ packages/protocol/test/L1/TaikoL1TestBase.sol | 36 ----------------- packages/protocol/test/TaikoTest.sol | 10 ++--- .../AutomataDcapV3AttestationTest.t.sol | 16 ++++---- .../assets/0923/identity.json | 0 .../assets/0923/tcbInfo.json | 0 .../assets/0923/v3quote.json | 0 .../assets/complex.json | 0 .../utils/DcapTestUtils.t.sol | 6 +-- .../utils/V3JsonUtils.t.sol | 2 +- 31 files changed, 84 insertions(+), 84 deletions(-) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/AutomataDcapV3Attestation.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/interfaces/IAttestation.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/interfaces/ISigVerifyLib.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/lib/EnclaveIdStruct.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/lib/PEMCertChainLib.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/lib/QuoteV3Auth/V3Parser.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/lib/QuoteV3Auth/V3Struct.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/lib/TCBInfoStruct.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/lib/interfaces/IPEMCertChainLib.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/utils/Asn1Decode.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/utils/BytesUtils.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/utils/RsaVerify.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/utils/SHA1.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/utils/SigVerifyLib.sol (100%) rename packages/protocol/contracts/thirdparty/{onchainRA => automata-attestation}/utils/X509DateUtils.sol (100%) rename packages/protocol/test/{onchainRA => automata-attestation}/AutomataDcapV3AttestationTest.t.sol (94%) rename packages/protocol/test/{onchainRA => automata-attestation}/assets/0923/identity.json (100%) rename packages/protocol/test/{onchainRA => automata-attestation}/assets/0923/tcbInfo.json (100%) rename packages/protocol/test/{onchainRA => automata-attestation}/assets/0923/v3quote.json (100%) rename packages/protocol/test/{onchainRA => automata-attestation}/assets/complex.json (100%) rename packages/protocol/test/{onchainRA => automata-attestation}/utils/DcapTestUtils.t.sol (97%) rename packages/protocol/test/{onchainRA => automata-attestation}/utils/V3JsonUtils.t.sol (98%) diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 36a880ccd25..5f454ca51a5 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -134,7 +134,7 @@ library LibProposing { if (params.blobHash != 0) { // We try to reuse an old blob - if (isBlobReusable(state, config, params.blobHash)) { + if (!isBlobReusable(state, config, params.blobHash)) { revert L1_BLOB_NOT_REUSEABLE(); } meta.blobHash = params.blobHash; @@ -193,9 +193,7 @@ library LibProposing { // of multiple Taiko blocks being proposed within a single // Ethereum block, we must introduce a salt to this random // number as the L2 mixHash. - unchecked { - meta.difficulty = meta.blobHash ^ bytes32(block.prevrandao * b.numBlocks * block.number); - } + meta.difficulty = keccak256(abi.encodePacked(block.prevrandao, b.numBlocks, block.number)); // Use the difficulty as a random number meta.minTier = ITierProvider(resolver.resolve("tier_provider", false)).getMinTier( diff --git a/packages/protocol/contracts/L1/provers/Guardians.sol b/packages/protocol/contracts/L1/provers/Guardians.sol index 560786ad1b6..832c3ec3184 100644 --- a/packages/protocol/contracts/L1/provers/Guardians.sol +++ b/packages/protocol/contracts/L1/provers/Guardians.sol @@ -94,8 +94,9 @@ abstract contract Guardians is EssentialContract { _approvals[version][hash] |= 1 << (id - 1); } - approved = isApproved(_approvals[version][hash]); - emit Approved(operationId, _approvals[version][hash], approved); + uint256 _approval = _approvals[version][hash]; + approved = isApproved(_approval); + emit Approved(operationId, _approval, approved); } function deleteApproval(bytes32 hash) internal { diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index f2ca455bc8f..7840ba11fdd 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -14,13 +14,14 @@ pragma solidity 0.8.20; + import "lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; import "../../common/EssentialContract.sol"; import "../../thirdparty/LibBytesUtils.sol"; +import "../../thirdparty/automata-attestation/interfaces/IAttestation.sol"; +import "../../thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; import "../ITaikoL1.sol"; import "./IVerifier.sol"; -import { IAttestation } from "../../thirdparty/onchainRA/interfaces/IAttestation.sol"; -import { V3Struct } from "../../thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; /// @title SgxVerifier /// @notice This contract is the implementation of verifying SGX signature @@ -90,25 +91,21 @@ contract SgxVerifier is EssentialContract, IVerifier { { address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); - // Still possible to be backward compatible and have the onlyOwner tpye of method - // registering instances. - if (automataDcapAttestation != address(0)) { - (bool verified,) = IAttestation(automataDcapAttestation).verifyParsedQuote(attestation); + if (automataDcapAttestation == address(0)) { + return type(uint256).max; + } - if (!verified) { - revert SGX_INVALID_ATTESTATION(); - } + // Still possible to be backward compatible and register instances by the owner. + (bool verified,) = IAttestation(automataDcapAttestation).verifyParsedQuote(attestation); - address[] memory _address = new address[](1); - _address[0] = address( - bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20)) - ); + if (!verified) revert SGX_INVALID_ATTESTATION(); - return _addInstances(_address)[0]; - } - // A special return variable, signaling that this method is not supported at the moment, - // because a contract with name "automata_dcap_attestation" not deployed. - return type(uint256).max; + address[] memory _address = new address[](1); + _address[0] = address( + bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20)) + ); + + return _addInstances(_address)[0]; } /// @inheritdoc IVerifier diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index f740a39a160..c024fd435c6 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -199,7 +199,7 @@ contract TaikoL2 is CrossChainOwned, TaikoL2Signer, ICrossChainSync { /// block id is greater than or equal to the current block number. function getBlockHash(uint64 blockId) public view returns (bytes32) { if (blockId >= block.number) return 0; - if (blockId >= block.number - 256) return blockhash(blockId); + if (blockId + 256 >= block.number) return blockhash(blockId); return l2Hashes[blockId]; } diff --git a/packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol b/packages/protocol/contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol b/packages/protocol/contracts/thirdparty/automata-attestation/interfaces/IAttestation.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/interfaces/IAttestation.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/interfaces/IAttestation.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol b/packages/protocol/contracts/thirdparty/automata-attestation/interfaces/ISigVerifyLib.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/interfaces/ISigVerifyLib.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/interfaces/ISigVerifyLib.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Parser.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Parser.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Parser.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/interfaces/IPEMCertChainLib.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/lib/interfaces/IPEMCertChainLib.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/lib/interfaces/IPEMCertChainLib.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/Asn1Decode.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/utils/Asn1Decode.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/utils/Asn1Decode.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/utils/BytesUtils.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/RsaVerify.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/utils/RsaVerify.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/utils/RsaVerify.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/SHA1.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/utils/SHA1.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/utils/SHA1.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol diff --git a/packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/X509DateUtils.sol similarity index 100% rename from packages/protocol/contracts/thirdparty/onchainRA/utils/X509DateUtils.sol rename to packages/protocol/contracts/thirdparty/automata-attestation/utils/X509DateUtils.sol diff --git a/packages/protocol/script/DeployOnL1.s.sol b/packages/protocol/script/DeployOnL1.s.sol index 2411046e0c9..6833621f123 100644 --- a/packages/protocol/script/DeployOnL1.s.sol +++ b/packages/protocol/script/DeployOnL1.s.sol @@ -36,9 +36,9 @@ import "../contracts/signal/SignalService.sol"; import "../contracts/test/erc20/FreeMintERC20.sol"; import "../contracts/test/erc20/MayFailFreeMintERC20.sol"; import "../test/DeployCapability.sol"; -import "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; -import "../contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol"; -import "../contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol"; +import "../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; +import "../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; +import "../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; // Actually this one is deployed already on mainnets, but we are now deploying our own (non vi-ir) // version. For mainnet, it is easier to go with either this: diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol index 17e698e8dc9..691f738f0e5 100644 --- a/packages/protocol/script/SetDcapParams.s.sol +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -17,10 +17,10 @@ pragma solidity 0.8.20; import "forge-std/Script.sol"; import "forge-std/console2.sol"; -import "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; +import "../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; import "../contracts/L1/verifiers/SgxVerifier.sol"; -import "../test/onchainRA/utils/DcapTestUtils.t.sol"; -import "../test/onchainRA/utils/V3JsonUtils.t.sol"; +import "../test/automata-attestation/utils/DcapTestUtils.t.sol"; +import "../test/automata-attestation/utils/V3JsonUtils.t.sol"; contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { //@todo: Wand Yue -> after deployed with DeployOnL1, you have the parameters, fill in the proper diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index a38c2918c8d..97e83d7ba8e 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -4,11 +4,51 @@ pragma solidity 0.8.20; import "./TaikoL1TestBase.sol"; contract TestSgxVerifier is TaikoL1TestBase { + + // For SGX remote attestation + AutomataDcapV3Attestation attestation; + SigVerifyLib sigVerifyLib; + P256Verifier p256Verifier; + PEMCertChainLib pemCertChainLib; + string internal constant tcbInfoPath = "/test/automata-attestation/assets/0923/tcbInfo.json"; + string internal constant idPath = "/test/automata-attestation/assets/0923/identity.json"; + string internal constant v3QuotePath = "/test/automata-attestation/assets/0923/v3quote.json"; + bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; + bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; + function deployTaikoL1() internal override returns (TaikoL1) { return TaikoL1(payable(deployProxy({ name: "taiko", impl: address(new TaikoL1()), data: "" }))); } + function setUp() public override { + // Call the TaikoL1TestBase setUp() + super.setUp(); + + p256Verifier = new P256Verifier(); + sigVerifyLib = new SigVerifyLib(address(p256Verifier)); + pemCertChainLib = new PEMCertChainLib(); + attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); + attestation.setMrEnclave(mrEnclave, true); + attestation.setMrSigner(mrSigner, true); + + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); + + string memory fmspc = "00606a000000"; + (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = + parseTcbInfoJson(tcbInfoJson); + require(tcbParsedSuccess, "tcb parsed failed"); + attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); + + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + require(qeIdParsedSuccess, "qeid parsed failed"); + attestation.configureQeIdentityJson(parsedEnclaveId); + + registerAddress("automata_dcap_attestation", address(attestation)); + } + function test_addInstancesByOwner() external { address[] memory _instances = new address[](3); _instances[0] = SGX_X_1; diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 0d98fc3b406..178da000c40 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -25,17 +25,6 @@ abstract contract TaikoL1TestBase is TaikoTest { TaikoA6TierProvider public cp; Bridge public bridge; - // For SGX remote attestation - AutomataDcapV3Attestation attestation; - SigVerifyLib sigVerifyLib; - P256Verifier p256Verifier; - PEMCertChainLib pemCertChainLib; - string internal constant tcbInfoPath = "/test/onchainRA/assets/0923/tcbInfo.json"; - string internal constant idPath = "/test/onchainRA/assets/0923/identity.json"; - string internal constant v3QuotePath = "/test/onchainRA/assets/0923/v3quote.json"; - bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; - bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; - bytes32 public GENESIS_BLOCK_HASH = keccak256("GENESIS_BLOCK_HASH"); address public L2SS = randAddress(); @@ -110,7 +99,6 @@ abstract contract TaikoL1TestBase is TaikoTest { ); setupGuardianProverMultisig(); - setupAutomataOnChainRAUtils(); cp = TaikoA6TierProvider( deployProxy({ @@ -148,7 +136,6 @@ abstract contract TaikoL1TestBase is TaikoTest { registerAddress("tier_provider", address(cp)); registerAddress("signal_service", address(ss)); registerAddress("guardian_prover", address(gp)); - registerAddress("automata_dcap_attestation", address(attestation)); registerAddress("bridge", address(bridge)); registerL2Address("taiko", address(L2)); registerL2Address("signal_service", address(L2SS)); @@ -356,29 +343,6 @@ abstract contract TaikoL1TestBase is TaikoTest { gp.setGuardians(initMultiSig, 3); } - function setupAutomataOnChainRAUtils() internal { - p256Verifier = new P256Verifier(); - sigVerifyLib = new SigVerifyLib(address(p256Verifier)); - pemCertChainLib = new PEMCertChainLib(); - attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); - attestation.setMrEnclave(mrEnclave, true); - attestation.setMrSigner(mrSigner, true); - - string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); - string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); - - string memory fmspc = "00606a000000"; - (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = - parseTcbInfoJson(tcbInfoJson); - require(tcbParsedSuccess, "tcb parsed failed"); - attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); - - (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - require(qeIdParsedSuccess, "qeid parsed failed"); - attestation.configureQeIdentityJson(parsedEnclaveId); - } - function registerAddress(bytes32 nameHash, address addr) internal { addressManager.setAddress(uint64(block.chainid), nameHash, addr); console2.log(block.chainid, uint256(nameHash), unicode"→", addr); diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index 58208251f0d..09dc99b9824 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -44,13 +44,13 @@ import "./HelperContracts.sol"; // For SGX remote attestation import { AutomataDcapV3Attestation } from - "../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; + "../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; import { P256Verifier } from "../lib/p256-verifier/src/P256Verifier.sol"; -import { SigVerifyLib } from "../contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol"; -import { PEMCertChainLib } from "../contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol"; +import { SigVerifyLib } from "../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from "../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; -import "./onchainRA/utils/DcapTestUtils.t.sol"; -import "./onchainRA/utils/V3JsonUtils.t.sol"; +import "./automata-attestation/utils/DcapTestUtils.t.sol"; +import "./automata-attestation/utils/V3JsonUtils.t.sol"; abstract contract TaikoTest is Test, DeployCapability, DcapTestUtils, V3JsonUtils { uint256 private _seed = 0x12345678; diff --git a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol similarity index 94% rename from packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol rename to packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol index 05b0892c40d..0823338e3fd 100644 --- a/packages/protocol/test/onchainRA/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol @@ -5,12 +5,12 @@ import "forge-std/Test.sol"; import "forge-std/console.sol"; import "forge-std/StdJson.sol"; import { AutomataDcapV3Attestation } from - "../../contracts/thirdparty/onchainRA/AutomataDcapV3Attestation.sol"; + "../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; import { P256Verifier } from "../../lib/p256-verifier/src/P256Verifier.sol"; -import { SigVerifyLib } from "../../contracts/thirdparty/onchainRA/utils/SigVerifyLib.sol"; -import { PEMCertChainLib } from "../../contracts/thirdparty/onchainRA/lib/PEMCertChainLib.sol"; -import { V3Struct } from "../../contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; -import { BytesUtils } from "../../contracts/thirdparty/onchainRA/utils/BytesUtils.sol"; +import { SigVerifyLib } from "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; +import { V3Struct } from "../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; +import { BytesUtils } from "../../contracts/thirdparty/automata-attestation/utils/BytesUtils.sol"; import { Base64 } from "../../lib/solady/src/utils/Base64.sol"; import "./utils/DcapTestUtils.t.sol"; import "./utils/V3JsonUtils.t.sol"; @@ -26,9 +26,9 @@ contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { // use a network that where the P256Verifier contract exists // ref: https://github.com/daimo-eth/p256-verifier //string internal rpcUrl = vm.envString("RPC_URL"); - string internal constant tcbInfoPath = "/test/onchainRA/assets/0923/tcbInfo.json"; - string internal constant idPath = "/test/onchainRA/assets/0923/identity.json"; - string internal constant v3QuotePath = "/test/onchainRA/assets/0923/v3quote.json"; + string internal constant tcbInfoPath = "/test/automata-attestation/assets/0923/tcbInfo.json"; + string internal constant idPath = "/test/automata-attestation/assets/0923/identity.json"; + string internal constant v3QuotePath = "/test/automata-attestation/assets/0923/v3quote.json"; address constant admin = address(1); address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; diff --git a/packages/protocol/test/onchainRA/assets/0923/identity.json b/packages/protocol/test/automata-attestation/assets/0923/identity.json similarity index 100% rename from packages/protocol/test/onchainRA/assets/0923/identity.json rename to packages/protocol/test/automata-attestation/assets/0923/identity.json diff --git a/packages/protocol/test/onchainRA/assets/0923/tcbInfo.json b/packages/protocol/test/automata-attestation/assets/0923/tcbInfo.json similarity index 100% rename from packages/protocol/test/onchainRA/assets/0923/tcbInfo.json rename to packages/protocol/test/automata-attestation/assets/0923/tcbInfo.json diff --git a/packages/protocol/test/onchainRA/assets/0923/v3quote.json b/packages/protocol/test/automata-attestation/assets/0923/v3quote.json similarity index 100% rename from packages/protocol/test/onchainRA/assets/0923/v3quote.json rename to packages/protocol/test/automata-attestation/assets/0923/v3quote.json diff --git a/packages/protocol/test/onchainRA/assets/complex.json b/packages/protocol/test/automata-attestation/assets/complex.json similarity index 100% rename from packages/protocol/test/onchainRA/assets/complex.json rename to packages/protocol/test/automata-attestation/assets/complex.json diff --git a/packages/protocol/test/onchainRA/utils/DcapTestUtils.t.sol b/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol similarity index 97% rename from packages/protocol/test/onchainRA/utils/DcapTestUtils.t.sol rename to packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol index b45f7520385..9a113f31b72 100644 --- a/packages/protocol/test/onchainRA/utils/DcapTestUtils.t.sol +++ b/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol @@ -1,9 +1,9 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import { TCBInfoStruct } from "../../../contracts/thirdparty/onchainRA/lib/TCBInfoStruct.sol"; -import { EnclaveIdStruct } from "../../../contracts/thirdparty/onchainRA/lib/EnclaveIdStruct.sol"; -import { V3Struct } from "../../../contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; +import { TCBInfoStruct } from "../../../contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol"; +import { EnclaveIdStruct } from "../../../contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol"; +import { V3Struct } from "../../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; import { JSONParserLib } from "../../../lib/solady/src/utils/JSONParserLib.sol"; import { LibString } from "../../../lib/solady/src/utils/LibString.sol"; diff --git a/packages/protocol/test/onchainRA/utils/V3JsonUtils.t.sol b/packages/protocol/test/automata-attestation/utils/V3JsonUtils.t.sol similarity index 98% rename from packages/protocol/test/onchainRA/utils/V3JsonUtils.t.sol rename to packages/protocol/test/automata-attestation/utils/V3JsonUtils.t.sol index 4861679af52..dfcab2d573f 100644 --- a/packages/protocol/test/onchainRA/utils/V3JsonUtils.t.sol +++ b/packages/protocol/test/automata-attestation/utils/V3JsonUtils.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import { V3Struct } from "../../../contracts/thirdparty/onchainRA/lib/QuoteV3Auth/V3Struct.sol"; +import { V3Struct } from "../../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; import { JSONParserLib } from "../../../lib/solady/src/utils/JSONParserLib.sol"; import { LibString } from "../../../lib/solady/src/utils/LibString.sol"; From ab74e40acebfe0782e6370ed0956c09ade17fb29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 09:32:05 +0530 Subject: [PATCH 27/44] changes --- .gitmodules | 3 --- .../contracts/4844/IBlobHashReader.sol | 2 +- packages/protocol/contracts/4844/Lib4844.sol | 2 +- packages/protocol/contracts/L1/ITaikoL1.sol | 2 +- packages/protocol/contracts/L1/TaikoData.sol | 2 +- .../protocol/contracts/L1/TaikoErrors.sol | 2 +- .../protocol/contracts/L1/TaikoEvents.sol | 2 +- packages/protocol/contracts/L1/TaikoL1.sol | 2 +- packages/protocol/contracts/L1/TaikoToken.sol | 2 +- .../contracts/L1/gov/TaikoGovernor.sol | 2 +- .../L1/gov/TaikoTimelockController.sol | 2 +- .../contracts/L1/hooks/AssignmentHook.sol | 2 +- .../protocol/contracts/L1/hooks/IHook.sol | 2 +- .../contracts/L1/libs/LibDepositing.sol | 2 +- .../contracts/L1/libs/LibProposing.sol | 2 +- .../protocol/contracts/L1/libs/LibProving.sol | 2 +- .../contracts/L1/libs/LibProvingAlt.sol | 2 +- .../protocol/contracts/L1/libs/LibUtils.sol | 2 +- .../contracts/L1/libs/LibVerifying.sol | 2 +- .../contracts/L1/provers/GuardianProver.sol | 2 +- .../contracts/L1/provers/Guardians.sol | 2 +- .../contracts/L1/tiers/ITierProvider.sol | 2 +- .../L1/tiers/TaikoA6TierProvider.sol | 2 +- .../L1/verifiers/GuardianVerifier.sol | 2 +- .../contracts/L1/verifiers/IVerifier.sol | 2 +- .../contracts/L1/verifiers/PseZkVerifier.sol | 2 +- .../L1/verifiers/SgxAndZkVerifier.sol | 2 +- .../contracts/L1/verifiers/SgxVerifier.sol | 2 +- .../protocol/contracts/L2/CrossChainOwned.sol | 2 +- .../protocol/contracts/L2/Lib1559Math.sol | 2 +- packages/protocol/contracts/L2/TaikoL2.sol | 2 +- .../L2/TaikoL2EIP1559Configurable.sol | 2 +- .../protocol/contracts/L2/TaikoL2Signer.sol | 2 +- packages/protocol/contracts/bridge/Bridge.sol | 15 ++++++++++++--- .../protocol/contracts/bridge/IBridge.sol | 2 +- .../contracts/common/AddressManager.sol | 2 +- .../contracts/common/AddressResolver.sol | 2 +- .../contracts/common/AuthorizableContract.sol | 2 +- .../contracts/common/EssentialContract.sol | 2 +- .../contracts/common/ICrossChainSync.sol | 2 +- .../contracts/common/OwnerUUPSUpgradable.sol | 2 +- .../protocol/contracts/libs/LibAddress.sol | 2 +- .../protocol/contracts/libs/LibDeploy.sol | 2 +- packages/protocol/contracts/libs/LibMath.sol | 2 +- .../contracts/signal/ISignalService.sol | 2 +- .../contracts/signal/SignalService.sol | 2 +- .../contracts/team/TimelockTokenPool.sol | 4 ++-- .../contracts/team/airdrop/ERC20Airdrop.sol | 2 +- .../contracts/team/airdrop/ERC20Airdrop2.sol | 6 +++--- .../contracts/team/airdrop/ERC721Airdrop.sol | 16 +++++++--------- .../team/airdrop/MerkleClaimable.sol | 2 +- .../contracts/test/erc20/FreeMintERC20.sol | 2 +- .../test/erc20/MayFailFreeMintERC20.sol | 2 +- .../contracts/test/erc20/RegularERC20.sol | 2 +- .../contracts/thirdparty/LibBytesUtils.sol | 2 +- .../thirdparty/LibFixedPointMath.sol | 2 +- .../contracts/thirdparty/LibMerkleTrie.sol | 2 +- .../contracts/thirdparty/LibRLPReader.sol | 2 +- .../thirdparty/LibSecureMerkleTrie.sol | 2 +- .../contracts/thirdparty/LibUint512Math.sol | 2 +- .../AutomataDcapV3Attestation.sol | 2 +- .../lib/EnclaveIdStruct.sol | 2 +- .../lib/PEMCertChainLib.sol | 2 +- .../lib/QuoteV3Auth/V3Parser.sol | 2 +- .../lib/QuoteV3Auth/V3Struct.sol | 2 +- .../lib/TCBInfoStruct.sol | 2 +- .../automata-attestation/utils/Asn1Decode.sol | 2 +- .../automata-attestation/utils/BytesUtils.sol | 2 +- .../automata-attestation/utils/RsaVerify.sol | 2 +- .../automata-attestation/utils/SHA1.sol | 2 +- .../utils/SigVerifyLib.sol | 2 +- .../utils/X509DateUtils.sol | 2 +- .../contracts/tokenvault/BaseNFTVault.sol | 2 +- .../contracts/tokenvault/BaseVault.sol | 2 +- .../contracts/tokenvault/BridgedERC1155.sol | 2 +- .../contracts/tokenvault/BridgedERC20.sol | 2 +- .../contracts/tokenvault/BridgedERC20Base.sol | 2 +- .../contracts/tokenvault/BridgedERC721.sol | 2 +- .../contracts/tokenvault/ERC1155Vault.sol | 2 +- .../contracts/tokenvault/ERC20Vault.sol | 19 ++++++++++++------- .../contracts/tokenvault/ERC721Vault.sol | 2 +- .../contracts/tokenvault/IBridgedERC20.sol | 2 +- .../contracts/tokenvault/LibBridgedToken.sol | 2 +- .../tokenvault/adaptors/USDCAdaptor.sol | 2 +- packages/protocol/foundry.toml | 2 +- .../protocol/genesis/GenerateGenesis.g.sol | 2 +- packages/protocol/lib/p256-verifier | 2 +- .../script/AddSGXVerifierInstances.s.sol | 2 +- .../AuthorizeRemoteTaikoProtocols.s.sol | 2 +- packages/protocol/script/DeployOnL1.s.sol | 2 +- .../protocol/script/DeployUSDCAdaptor.s.sol | 2 +- packages/protocol/script/SetAddress.s.sol | 2 +- packages/protocol/script/SetDcapParams.s.sol | 4 +--- .../script/SetRemoteBridgeSuites.s.sol | 2 +- .../upgrade/UpgradeAddressManager.s.sol | 2 +- .../upgrade/UpgradeAssignmentHook.s.sol | 2 +- .../script/upgrade/UpgradeBridge.s.sol | 2 +- .../script/upgrade/UpgradeERC1155Vault.s.sol | 2 +- .../script/upgrade/UpgradeERC20Vault.s.sol | 2 +- .../script/upgrade/UpgradeERC721Vault.s.sol | 2 +- .../upgrade/UpgradeGuardianProver.s.sol | 2 +- .../script/upgrade/UpgradeScript.s.sol | 2 +- .../script/upgrade/UpgradeSignalService.s.sol | 2 +- .../script/upgrade/UpgradeTaikoGovernor.s.sol | 2 +- .../script/upgrade/UpgradeTaikoL1.s.sol | 2 +- .../upgrade/UpgradeTimelockController.s.sol | 2 +- packages/protocol/test/DeployCapability.sol | 2 +- packages/protocol/test/HelperContracts.sol | 2 +- packages/protocol/test/L1/Guardians.t.sol | 2 +- packages/protocol/test/L1/SgxVerifier.t.sol | 12 +++++++++++- packages/protocol/test/L1/TaikoL1.t.sol | 2 +- .../test/L1/TaikoL1LibProvingWithTiers.t.sol | 4 ++-- packages/protocol/test/L1/TaikoL1TestBase.sol | 2 +- packages/protocol/test/L2/Lib1559Math.t.sol | 2 +- packages/protocol/test/L2/TaikoL2.t.sol | 2 +- packages/protocol/test/TaikoTest.sol | 12 +----------- .../AutomataDcapV3AttestationTest.t.sol | 2 +- packages/protocol/test/bridge/Bridge.t.sol | 2 +- .../test/common/EssentialContract.t.sol | 2 +- .../test/libs/LibFixedPointMath.t.sol | 2 +- .../protocol/test/signal/SignalService.t.sol | 2 +- .../test/team/TimelockTokenPool.t.sol | 2 +- .../test/team/airdrop/MerkleClaimable.t.sol | 2 +- .../test/tokenvault/BridgedERC20.t.sol | 2 +- .../test/tokenvault/ERC1155Vault.t.sol | 2 +- .../protocol/test/tokenvault/ERC20Vault.t.sol | 2 +- .../test/tokenvault/ERC721Vault.t.sol | 2 +- 127 files changed, 168 insertions(+), 161 deletions(-) diff --git a/.gitmodules b/.gitmodules index 13907426c32..88b307ed84c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,6 +17,3 @@ [submodule "packages/protocol/lib/solady"] path = packages/protocol/lib/solady url = https://github.com/Vectorized/solady -[submodule "packages/protocol/lib/p256-verifier"] - path = packages/protocol/lib/p256-verifier - url = https://github.com/taikoxyz/p256-verifier diff --git a/packages/protocol/contracts/4844/IBlobHashReader.sol b/packages/protocol/contracts/4844/IBlobHashReader.sol index 202c11bfe28..0173b588855 100644 --- a/packages/protocol/contracts/4844/IBlobHashReader.sol +++ b/packages/protocol/contracts/4844/IBlobHashReader.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title IBlobHashReader /// @dev Labeled in AddressResolver as "blob_hash_reader" diff --git a/packages/protocol/contracts/4844/Lib4844.sol b/packages/protocol/contracts/4844/Lib4844.sol index a070f55858e..e81c9288329 100644 --- a/packages/protocol/contracts/4844/Lib4844.sol +++ b/packages/protocol/contracts/4844/Lib4844.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title Lib4844 /// @notice A library for handling EIP-4844 blobs diff --git a/packages/protocol/contracts/L1/ITaikoL1.sol b/packages/protocol/contracts/L1/ITaikoL1.sol index df94d42190e..c846688f364 100644 --- a/packages/protocol/contracts/L1/ITaikoL1.sol +++ b/packages/protocol/contracts/L1/ITaikoL1.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./TaikoData.sol"; diff --git a/packages/protocol/contracts/L1/TaikoData.sol b/packages/protocol/contracts/L1/TaikoData.sol index 95d27ce31ec..e1ddb52e61b 100644 --- a/packages/protocol/contracts/L1/TaikoData.sol +++ b/packages/protocol/contracts/L1/TaikoData.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title TaikoData /// @notice This library defines various data structures used in the Taiko diff --git a/packages/protocol/contracts/L1/TaikoErrors.sol b/packages/protocol/contracts/L1/TaikoErrors.sol index 6c515fa252e..dcd64681a34 100644 --- a/packages/protocol/contracts/L1/TaikoErrors.sol +++ b/packages/protocol/contracts/L1/TaikoErrors.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title TaikoErrors /// @notice This abstract contract provides custom error declartions used in diff --git a/packages/protocol/contracts/L1/TaikoEvents.sol b/packages/protocol/contracts/L1/TaikoEvents.sol index 4185e56a049..8c4ef52b320 100644 --- a/packages/protocol/contracts/L1/TaikoEvents.sol +++ b/packages/protocol/contracts/L1/TaikoEvents.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./TaikoData.sol"; diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 16b7fad5d65..2fb39f0623d 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../common/EssentialContract.sol"; import "./libs/LibDepositing.sol"; diff --git a/packages/protocol/contracts/L1/TaikoToken.sol b/packages/protocol/contracts/L1/TaikoToken.sol index 5c06bc856b7..fcfbdd9c017 100644 --- a/packages/protocol/contracts/L1/TaikoToken.sol +++ b/packages/protocol/contracts/L1/TaikoToken.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; import diff --git a/packages/protocol/contracts/L1/gov/TaikoGovernor.sol b/packages/protocol/contracts/L1/gov/TaikoGovernor.sol index 8688d42dfee..0f0b8549e09 100644 --- a/packages/protocol/contracts/L1/gov/TaikoGovernor.sol +++ b/packages/protocol/contracts/L1/gov/TaikoGovernor.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/governance/GovernorUpgradeable.sol"; import diff --git a/packages/protocol/contracts/L1/gov/TaikoTimelockController.sol b/packages/protocol/contracts/L1/gov/TaikoTimelockController.sol index e1457b55ea8..73a6592df1c 100644 --- a/packages/protocol/contracts/L1/gov/TaikoTimelockController.sol +++ b/packages/protocol/contracts/L1/gov/TaikoTimelockController.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/governance/TimelockControllerUpgradeable.sol"; diff --git a/packages/protocol/contracts/L1/hooks/AssignmentHook.sol b/packages/protocol/contracts/L1/hooks/AssignmentHook.sol index 297f824b869..91e2c481b67 100644 --- a/packages/protocol/contracts/L1/hooks/AssignmentHook.sol +++ b/packages/protocol/contracts/L1/hooks/AssignmentHook.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/packages/protocol/contracts/L1/hooks/IHook.sol b/packages/protocol/contracts/L1/hooks/IHook.sol index d0c403e64c2..715907e25a7 100644 --- a/packages/protocol/contracts/L1/hooks/IHook.sol +++ b/packages/protocol/contracts/L1/hooks/IHook.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoData.sol"; diff --git a/packages/protocol/contracts/L1/libs/LibDepositing.sol b/packages/protocol/contracts/L1/libs/LibDepositing.sol index f816035d36c..e7a2bfac55f 100644 --- a/packages/protocol/contracts/L1/libs/LibDepositing.sol +++ b/packages/protocol/contracts/L1/libs/LibDepositing.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../common/AddressResolver.sol"; import "../../libs/LibAddress.sol"; diff --git a/packages/protocol/contracts/L1/libs/LibProposing.sol b/packages/protocol/contracts/L1/libs/LibProposing.sol index 5f454ca51a5..6e07a33e400 100644 --- a/packages/protocol/contracts/L1/libs/LibProposing.sol +++ b/packages/protocol/contracts/L1/libs/LibProposing.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../4844/IBlobHashReader.sol"; diff --git a/packages/protocol/contracts/L1/libs/LibProving.sol b/packages/protocol/contracts/L1/libs/LibProving.sol index dea23c4058b..19af30ea1e2 100644 --- a/packages/protocol/contracts/L1/libs/LibProving.sol +++ b/packages/protocol/contracts/L1/libs/LibProving.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../common/AddressResolver.sol"; diff --git a/packages/protocol/contracts/L1/libs/LibProvingAlt.sol b/packages/protocol/contracts/L1/libs/LibProvingAlt.sol index 600d4303248..84532d4a305 100644 --- a/packages/protocol/contracts/L1/libs/LibProvingAlt.sol +++ b/packages/protocol/contracts/L1/libs/LibProvingAlt.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../common/AddressResolver.sol"; diff --git a/packages/protocol/contracts/L1/libs/LibUtils.sol b/packages/protocol/contracts/L1/libs/LibUtils.sol index 9dc9d3ec5a6..37ee670eabe 100644 --- a/packages/protocol/contracts/L1/libs/LibUtils.sol +++ b/packages/protocol/contracts/L1/libs/LibUtils.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../common/ICrossChainSync.sol"; import "../TaikoData.sol"; diff --git a/packages/protocol/contracts/L1/libs/LibVerifying.sol b/packages/protocol/contracts/L1/libs/LibVerifying.sol index fb8a349f7b1..b1ef7aa99e3 100644 --- a/packages/protocol/contracts/L1/libs/LibVerifying.sol +++ b/packages/protocol/contracts/L1/libs/LibVerifying.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../common/AddressResolver.sol"; diff --git a/packages/protocol/contracts/L1/provers/GuardianProver.sol b/packages/protocol/contracts/L1/provers/GuardianProver.sol index 70db9454b04..301dd38e82e 100644 --- a/packages/protocol/contracts/L1/provers/GuardianProver.sol +++ b/packages/protocol/contracts/L1/provers/GuardianProver.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../tiers/ITierProvider.sol"; import "../ITaikoL1.sol"; diff --git a/packages/protocol/contracts/L1/provers/Guardians.sol b/packages/protocol/contracts/L1/provers/Guardians.sol index 832c3ec3184..72a4ae75aae 100644 --- a/packages/protocol/contracts/L1/provers/Guardians.sol +++ b/packages/protocol/contracts/L1/provers/Guardians.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../common/EssentialContract.sol"; import "../TaikoData.sol"; diff --git a/packages/protocol/contracts/L1/tiers/ITierProvider.sol b/packages/protocol/contracts/L1/tiers/ITierProvider.sol index baaf312dad3..dc0412302e3 100644 --- a/packages/protocol/contracts/L1/tiers/ITierProvider.sol +++ b/packages/protocol/contracts/L1/tiers/ITierProvider.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title ITierProvider /// @notice Defines interface to return tier configuration. diff --git a/packages/protocol/contracts/L1/tiers/TaikoA6TierProvider.sol b/packages/protocol/contracts/L1/tiers/TaikoA6TierProvider.sol index e2dc81de045..6c8bc809b9f 100644 --- a/packages/protocol/contracts/L1/tiers/TaikoA6TierProvider.sol +++ b/packages/protocol/contracts/L1/tiers/TaikoA6TierProvider.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../common/EssentialContract.sol"; import "./ITierProvider.sol"; diff --git a/packages/protocol/contracts/L1/verifiers/GuardianVerifier.sol b/packages/protocol/contracts/L1/verifiers/GuardianVerifier.sol index 19278f452d7..7b80df3f209 100644 --- a/packages/protocol/contracts/L1/verifiers/GuardianVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/GuardianVerifier.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../common/EssentialContract.sol"; import "../TaikoData.sol"; diff --git a/packages/protocol/contracts/L1/verifiers/IVerifier.sol b/packages/protocol/contracts/L1/verifiers/IVerifier.sol index 409f55914b1..00392ac9d3f 100644 --- a/packages/protocol/contracts/L1/verifiers/IVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/IVerifier.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoData.sol"; diff --git a/packages/protocol/contracts/L1/verifiers/PseZkVerifier.sol b/packages/protocol/contracts/L1/verifiers/PseZkVerifier.sol index a289cfd76f1..6d821055084 100644 --- a/packages/protocol/contracts/L1/verifiers/PseZkVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/PseZkVerifier.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../4844/Lib4844.sol"; import "../../common/EssentialContract.sol"; diff --git a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol index e22c5dca41e..f7bab4fbb58 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxAndZkVerifier.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../common/EssentialContract.sol"; import "../../thirdparty/LibBytesUtils.sol"; diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 7840ba11fdd..82d84740c53 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; diff --git a/packages/protocol/contracts/L2/CrossChainOwned.sol b/packages/protocol/contracts/L2/CrossChainOwned.sol index d561fcc8cee..19eba080b2f 100644 --- a/packages/protocol/contracts/L2/CrossChainOwned.sol +++ b/packages/protocol/contracts/L2/CrossChainOwned.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; diff --git a/packages/protocol/contracts/L2/Lib1559Math.sol b/packages/protocol/contracts/L2/Lib1559Math.sol index bc183f26830..2c0516ecb80 100644 --- a/packages/protocol/contracts/L2/Lib1559Math.sol +++ b/packages/protocol/contracts/L2/Lib1559Math.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../thirdparty/LibFixedPointMath.sol"; diff --git a/packages/protocol/contracts/L2/TaikoL2.sol b/packages/protocol/contracts/L2/TaikoL2.sol index c024fd435c6..b0e3c01a6c4 100644 --- a/packages/protocol/contracts/L2/TaikoL2.sol +++ b/packages/protocol/contracts/L2/TaikoL2.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; diff --git a/packages/protocol/contracts/L2/TaikoL2EIP1559Configurable.sol b/packages/protocol/contracts/L2/TaikoL2EIP1559Configurable.sol index 5f3dc7e7127..4302e1e7212 100644 --- a/packages/protocol/contracts/L2/TaikoL2EIP1559Configurable.sol +++ b/packages/protocol/contracts/L2/TaikoL2EIP1559Configurable.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./TaikoL2.sol"; diff --git a/packages/protocol/contracts/L2/TaikoL2Signer.sol b/packages/protocol/contracts/L2/TaikoL2Signer.sol index 7a960a441a0..21a323673d1 100644 --- a/packages/protocol/contracts/L2/TaikoL2Signer.sol +++ b/packages/protocol/contracts/L2/TaikoL2Signer.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../thirdparty/LibUint512Math.sol"; diff --git a/packages/protocol/contracts/bridge/Bridge.sol b/packages/protocol/contracts/bridge/Bridge.sol index 571a7b8656a..efd8539ae29 100644 --- a/packages/protocol/contracts/bridge/Bridge.sol +++ b/packages/protocol/contracts/bridge/Bridge.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../common/EssentialContract.sol"; import "../libs/LibAddress.sol"; @@ -40,17 +40,20 @@ contract Bridge is EssentialContract, IBridge { mapping(bytes32 msgHash => bool recalled) public isMessageRecalled; mapping(bytes32 msgHash => Status) public messageStatus; // slot 3 Context private _ctx; // // slot 4,5,6pnpm - uint256[44] private __gap; + mapping(address => bool) public addressBanned; + uint256[43] private __gap; event SignalSent(address indexed sender, bytes32 msgHash); event MessageSent(bytes32 indexed msgHash, Message message); event MessageRecalled(bytes32 indexed msgHash); event DestChainEnabled(uint64 indexed chainId, bool enabled); event MessageStatusChanged(bytes32 indexed msgHash, Status status); + event AddressBanned(address indexed addr, bool banned); error B_INVALID_CHAINID(); error B_INVALID_CONTEXT(); error B_INVALID_GAS_LIMIT(); + error B_INVALID_STATUS(); error B_INVALID_USER(); error B_INVALID_VALUE(); error B_MESSAGE_NOT_SENT(); @@ -75,6 +78,12 @@ contract Bridge is EssentialContract, IBridge { _ctx.msgHash == bytes32(PLACEHOLDER); } + function banAddress(address addr, bool toBan) external onlyOwner nonReentrant { + if (addressBanned[addr] == toBan) revert B_INVALID_STATUS(); + addressBanned[addr] = toBan; + emit AddressBanned(addr, toBan); + } + /// @notice Sends a message to the destination chain and takes custody /// of Ether required in this contract. All extra Ether will be refunded. /// @inheritdoc IBridge @@ -207,7 +216,7 @@ contract Bridge is EssentialContract, IBridge { // Process message differently based on the target address if ( message.to == address(0) || message.to == address(this) - || message.to == address(signalService) + || message.to == address(signalService) || addressBanned[message.to] ) { // Handle special addresses that don't require actual invocation but // mark message as DONE diff --git a/packages/protocol/contracts/bridge/IBridge.sol b/packages/protocol/contracts/bridge/IBridge.sol index 91a721a26d7..0a4a6c5e3a0 100644 --- a/packages/protocol/contracts/bridge/IBridge.sol +++ b/packages/protocol/contracts/bridge/IBridge.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title IBridge /// @notice The bridge used in conjunction with the {ISignalService}. diff --git a/packages/protocol/contracts/common/AddressManager.sol b/packages/protocol/contracts/common/AddressManager.sol index 32511a4d7e2..955e83eaeb5 100644 --- a/packages/protocol/contracts/common/AddressManager.sol +++ b/packages/protocol/contracts/common/AddressManager.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./OwnerUUPSUpgradable.sol"; diff --git a/packages/protocol/contracts/common/AddressResolver.sol b/packages/protocol/contracts/common/AddressResolver.sol index 03a26ef79bd..3fd7617970a 100644 --- a/packages/protocol/contracts/common/AddressResolver.sol +++ b/packages/protocol/contracts/common/AddressResolver.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/Strings.sol"; import "./AddressManager.sol"; diff --git a/packages/protocol/contracts/common/AuthorizableContract.sol b/packages/protocol/contracts/common/AuthorizableContract.sol index 78615d9547e..3ccb0fb4d04 100644 --- a/packages/protocol/contracts/common/AuthorizableContract.sol +++ b/packages/protocol/contracts/common/AuthorizableContract.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../common/EssentialContract.sol"; diff --git a/packages/protocol/contracts/common/EssentialContract.sol b/packages/protocol/contracts/common/EssentialContract.sol index bfdfd115e59..0ac00c7e106 100644 --- a/packages/protocol/contracts/common/EssentialContract.sol +++ b/packages/protocol/contracts/common/EssentialContract.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./AddressResolver.sol"; import "./OwnerUUPSUpgradable.sol"; diff --git a/packages/protocol/contracts/common/ICrossChainSync.sol b/packages/protocol/contracts/common/ICrossChainSync.sol index c6ecf8e0293..4b58484be69 100644 --- a/packages/protocol/contracts/common/ICrossChainSync.sol +++ b/packages/protocol/contracts/common/ICrossChainSync.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title ICrossChainSync /// @dev This interface is implemented by both the TaikoL1 and TaikoL2 diff --git a/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol b/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol index a3d92b288c0..7fdd2c285c8 100644 --- a/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol +++ b/packages/protocol/contracts/common/OwnerUUPSUpgradable.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol"; import "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol"; diff --git a/packages/protocol/contracts/libs/LibAddress.sol b/packages/protocol/contracts/libs/LibAddress.sol index 5e3ed81a4c8..aea82ba773c 100644 --- a/packages/protocol/contracts/libs/LibAddress.sol +++ b/packages/protocol/contracts/libs/LibAddress.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/Address.sol"; import "lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; diff --git a/packages/protocol/contracts/libs/LibDeploy.sol b/packages/protocol/contracts/libs/LibDeploy.sol index 1a6158c13fa..81a80f3e97e 100644 --- a/packages/protocol/contracts/libs/LibDeploy.sol +++ b/packages/protocol/contracts/libs/LibDeploy.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol"; diff --git a/packages/protocol/contracts/libs/LibMath.sol b/packages/protocol/contracts/libs/LibMath.sol index 453d2868ffd..19dc7400b39 100644 --- a/packages/protocol/contracts/libs/LibMath.sol +++ b/packages/protocol/contracts/libs/LibMath.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title LibMath /// @dev This library offers additional math functions for uint256. diff --git a/packages/protocol/contracts/signal/ISignalService.sol b/packages/protocol/contracts/signal/ISignalService.sol index 389c70113e8..b307c083b02 100644 --- a/packages/protocol/contracts/signal/ISignalService.sol +++ b/packages/protocol/contracts/signal/ISignalService.sol @@ -5,7 +5,7 @@ // | |/ _` | | / / _ \ | |__/ _` | '_ (_-< // |_|\__,_|_|_\_\___/ |____\__,_|_.__/__/ -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title ISignalService /// @notice The SignalService contract serves as a secure cross-chain message diff --git a/packages/protocol/contracts/signal/SignalService.sol b/packages/protocol/contracts/signal/SignalService.sol index 29083708bf5..b4406c65fce 100644 --- a/packages/protocol/contracts/signal/SignalService.sol +++ b/packages/protocol/contracts/signal/SignalService.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/math/SafeCast.sol"; import "../common/AuthorizableContract.sol"; diff --git a/packages/protocol/contracts/team/TimelockTokenPool.sol b/packages/protocol/contracts/team/TimelockTokenPool.sol index b4bcf12fae2..2786e4bd4d8 100644 --- a/packages/protocol/contracts/team/TimelockTokenPool.sol +++ b/packages/protocol/contracts/team/TimelockTokenPool.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol"; import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; @@ -186,7 +186,7 @@ contract TimelockTokenPool is EssentialContract { totalCostPaid += costToWithdraw; IERC20(taikoToken).transferFrom(sharedVault, to, amountToWithdraw); - IERC20(costToken).transferFrom(recipient, sharedVault, costToWithdraw); + IERC20(costToken).safeTransferFrom(recipient, sharedVault, costToWithdraw); emit Withdrawn(recipient, to, amountToWithdraw, costToWithdraw); } diff --git a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol index 89ccafec042..9ae29a7fb37 100644 --- a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol +++ b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; import "./MerkleClaimable.sol"; diff --git a/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol b/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol index dcaeb0a9792..788c786fa85 100644 --- a/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol +++ b/packages/protocol/contracts/team/airdrop/ERC20Airdrop2.sol @@ -12,9 +12,9 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; -import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; +import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "../../libs/LibMath.sol"; import "./MerkleClaimable.sol"; @@ -71,7 +71,7 @@ contract ERC20Airdrop2 is MerkleClaimable { function withdraw(address user) external ongoingWithdrawals { (, uint256 amount) = getBalance(user); withdrawnAmount[user] += amount; - IERC20Upgradeable(token).transferFrom(vault, user, amount); + IERC20(token).transferFrom(vault, user, amount); emit Withdrawn(user, amount); } diff --git a/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol b/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol index 6e43dbba96a..488eb80e4a5 100644 --- a/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol +++ b/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol @@ -12,13 +12,14 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; -import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol"; +import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "./MerkleClaimable.sol"; -/// @title ERC721Airdrop -contract ERC721Airdrop is MerkleClaimable { +/// @title ERC20Airdrop +/// Contract for managing Taiko token airdrop for eligible users +contract ERC20Airdrop is MerkleClaimable { address public token; address public vault; uint256[48] private __gap; @@ -41,10 +42,7 @@ contract ERC721Airdrop is MerkleClaimable { } function _claimWithData(bytes calldata data) internal override { - (address user, uint256[] memory tokenIds) = abi.decode(data, (address, uint256[])); - - for (uint256 i; i < tokenIds.length; ++i) { - IERC721Upgradeable(token).safeTransferFrom(vault, user, tokenIds[i]); - } + (address user, uint256 amount) = abi.decode(data, (address, uint256)); + IERC20(token).transferFrom(vault, user, amount); } } diff --git a/packages/protocol/contracts/team/airdrop/MerkleClaimable.sol b/packages/protocol/contracts/team/airdrop/MerkleClaimable.sol index 56489811500..58e257687b8 100644 --- a/packages/protocol/contracts/team/airdrop/MerkleClaimable.sol +++ b/packages/protocol/contracts/team/airdrop/MerkleClaimable.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import { MerkleProofUpgradeable } from "lib/openzeppelin-contracts-upgradeable/contracts/utils/cryptography/MerkleProofUpgradeable.sol"; diff --git a/packages/protocol/contracts/test/erc20/FreeMintERC20.sol b/packages/protocol/contracts/test/erc20/FreeMintERC20.sol index 38f7c080829..b6183d7e754 100644 --- a/packages/protocol/contracts/test/erc20/FreeMintERC20.sol +++ b/packages/protocol/contracts/test/erc20/FreeMintERC20.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; diff --git a/packages/protocol/contracts/test/erc20/MayFailFreeMintERC20.sol b/packages/protocol/contracts/test/erc20/MayFailFreeMintERC20.sol index c0427076219..cdcaa87e328 100644 --- a/packages/protocol/contracts/test/erc20/MayFailFreeMintERC20.sol +++ b/packages/protocol/contracts/test/erc20/MayFailFreeMintERC20.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; diff --git a/packages/protocol/contracts/test/erc20/RegularERC20.sol b/packages/protocol/contracts/test/erc20/RegularERC20.sol index 3e057462ab5..623babc9b08 100644 --- a/packages/protocol/contracts/test/erc20/RegularERC20.sol +++ b/packages/protocol/contracts/test/erc20/RegularERC20.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; diff --git a/packages/protocol/contracts/thirdparty/LibBytesUtils.sol b/packages/protocol/contracts/thirdparty/LibBytesUtils.sol index ce13f3ef897..66608c3f8d5 100644 --- a/packages/protocol/contracts/thirdparty/LibBytesUtils.sol +++ b/packages/protocol/contracts/thirdparty/LibBytesUtils.sol @@ -25,7 +25,7 @@ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -pragma solidity 0.8.20; +pragma solidity 0.8.24; /** * @title LibBytesUtils diff --git a/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol b/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol index 943a0c8353c..13e0e2b0af3 100644 --- a/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol +++ b/packages/protocol/contracts/thirdparty/LibFixedPointMath.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Taken from the contract below, expWad() function tailored to Taiko's need // https://github.com/transmissions11/solmate/blob/v7/src/utils/FixedPointMathLib.sol -pragma solidity 0.8.20; +pragma solidity 0.8.24; library LibFixedPointMath { uint128 public constant MAX_EXP_INPUT = 135_305_999_368_893_231_588; diff --git a/packages/protocol/contracts/thirdparty/LibMerkleTrie.sol b/packages/protocol/contracts/thirdparty/LibMerkleTrie.sol index d124b56c6be..c2cfbe718e8 100644 --- a/packages/protocol/contracts/thirdparty/LibMerkleTrie.sol +++ b/packages/protocol/contracts/thirdparty/LibMerkleTrie.sol @@ -25,7 +25,7 @@ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -pragma solidity 0.8.20; +pragma solidity 0.8.24; /* Library Imports */ import "./LibBytesUtils.sol"; diff --git a/packages/protocol/contracts/thirdparty/LibRLPReader.sol b/packages/protocol/contracts/thirdparty/LibRLPReader.sol index 89b2eb0bc27..68bdbf2fe92 100644 --- a/packages/protocol/contracts/thirdparty/LibRLPReader.sol +++ b/packages/protocol/contracts/thirdparty/LibRLPReader.sol @@ -25,7 +25,7 @@ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -pragma solidity 0.8.20; +pragma solidity 0.8.24; /** * @title LibRLPReader diff --git a/packages/protocol/contracts/thirdparty/LibSecureMerkleTrie.sol b/packages/protocol/contracts/thirdparty/LibSecureMerkleTrie.sol index 07e28bfc307..52a27c0645f 100644 --- a/packages/protocol/contracts/thirdparty/LibSecureMerkleTrie.sol +++ b/packages/protocol/contracts/thirdparty/LibSecureMerkleTrie.sol @@ -25,7 +25,7 @@ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -pragma solidity 0.8.20; +pragma solidity 0.8.24; /* Library Imports */ import "./LibMerkleTrie.sol"; diff --git a/packages/protocol/contracts/thirdparty/LibUint512Math.sol b/packages/protocol/contracts/thirdparty/LibUint512Math.sol index d22f06cdddb..b7f5178d99b 100644 --- a/packages/protocol/contracts/thirdparty/LibUint512Math.sol +++ b/packages/protocol/contracts/thirdparty/LibUint512Math.sol @@ -23,7 +23,7 @@ // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title LibUint512Math library LibUint512Math { diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol b/packages/protocol/contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol index e476101a55f..37be5772190 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.24; import { V3Struct } from "./lib/QuoteV3Auth/V3Struct.sol"; import { V3Parser } from "./lib/QuoteV3Auth/V3Parser.sol"; diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol index 47d3c7d2d22..fe20f2f1054 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.24; library EnclaveIdStruct { struct EnclaveId { diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol index 7baebcaf06d..e35ee5f46fe 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.24; import { LibString } from "../../../../lib/solady/src/utils/LibString.sol"; import { Asn1Decode, NodePtr } from "../utils/Asn1Decode.sol"; diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Parser.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Parser.sol index 653786c97f1..c594f843817 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Parser.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Parser.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.24; import { BytesUtils } from "../../utils/BytesUtils.sol"; import { V3Struct } from "./V3Struct.sol"; diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol index 33b6b0c4f1d..25b2ea503d4 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.24; library V3Struct { struct Header { diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol b/packages/protocol/contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol index bb79029a2d5..b0a463909d6 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol @@ -1,5 +1,5 @@ //SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.24; library TCBInfoStruct { struct TCBInfo { diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/utils/Asn1Decode.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/Asn1Decode.sol index f0708f76fa2..844a0545231 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/utils/Asn1Decode.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/utils/Asn1Decode.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // Original source: https://github.com/JonahGroendal/asn1-decode -pragma solidity ^0.8.0; +pragma solidity 0.8.24; // Inspired by PufferFinance/rave - Apache-2.0 license // https://github.com/JonahGroendal/asn1-decode/blob/5c2d1469fc678513753786acb441e597969192ec/contracts/Asn1Decode.sol diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol index 8f88a60edd3..92b7dcfee5a 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: BSD 2-Clause License -pragma solidity ^0.8.0; +pragma solidity 0.8.24; // Inspired by ensdomains/dnssec-oracle - BSD-2-Clause license // https://github.com/ensdomains/dnssec-oracle/blob/master/contracts/BytesUtils.sol diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/utils/RsaVerify.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/RsaVerify.sol index 51f6a2816d3..65db8ef7f86 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/utils/RsaVerify.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/utils/RsaVerify.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.0; +pragma solidity 0.8.24; import "./SHA1.sol"; diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/utils/SHA1.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/SHA1.sol index 86cd534ce67..c0ae73dd035 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/utils/SHA1.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/utils/SHA1.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: BSD 2-Clause License -pragma solidity ^0.8.0; +pragma solidity 0.8.24; // Inspired by ensdomains/solsha1 - BSD 2-Clause License // https://github.com/ensdomains/solsha1/blob/master/contracts/SHA1.sol diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol index d9fc0e17f72..6e5486879a5 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: GPL-3.0 -pragma solidity ^0.8.0; +pragma solidity 0.8.24; import "../interfaces/ISigVerifyLib.sol"; import "./RsaVerify.sol"; diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/utils/X509DateUtils.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/X509DateUtils.sol index f7ce2872ea6..b9b27ac8435 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/utils/X509DateUtils.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/utils/X509DateUtils.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity 0.8.24; library X509DateUtils { function toTimestamp(bytes memory x509Time) internal pure returns (uint256) { diff --git a/packages/protocol/contracts/tokenvault/BaseNFTVault.sol b/packages/protocol/contracts/tokenvault/BaseNFTVault.sol index f4c06d88d22..57e38fb763b 100644 --- a/packages/protocol/contracts/tokenvault/BaseNFTVault.sol +++ b/packages/protocol/contracts/tokenvault/BaseNFTVault.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./BaseVault.sol"; diff --git a/packages/protocol/contracts/tokenvault/BaseVault.sol b/packages/protocol/contracts/tokenvault/BaseVault.sol index 84d6fb6fa5c..1733dec2e23 100644 --- a/packages/protocol/contracts/tokenvault/BaseVault.sol +++ b/packages/protocol/contracts/tokenvault/BaseVault.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/utils/introspection/IERC165Upgradeable.sol"; import "../bridge/IBridge.sol"; diff --git a/packages/protocol/contracts/tokenvault/BridgedERC1155.sol b/packages/protocol/contracts/tokenvault/BridgedERC1155.sol index 38638103b50..86d60b09568 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC1155.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC1155.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/Strings.sol"; import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC1155/ERC1155Upgradeable.sol"; diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20.sol b/packages/protocol/contracts/tokenvault/BridgedERC20.sol index 2cce97472ea..bd7d8792c4c 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; diff --git a/packages/protocol/contracts/tokenvault/BridgedERC20Base.sol b/packages/protocol/contracts/tokenvault/BridgedERC20Base.sol index 5c8210e01a2..664c6484ed7 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC20Base.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC20Base.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; import "../common/EssentialContract.sol"; diff --git a/packages/protocol/contracts/tokenvault/BridgedERC721.sol b/packages/protocol/contracts/tokenvault/BridgedERC721.sol index 141e4ffe7b4..880ff200495 100644 --- a/packages/protocol/contracts/tokenvault/BridgedERC721.sol +++ b/packages/protocol/contracts/tokenvault/BridgedERC721.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol"; import "lib/openzeppelin-contracts/contracts/utils/Strings.sol"; diff --git a/packages/protocol/contracts/tokenvault/ERC1155Vault.sol b/packages/protocol/contracts/tokenvault/ERC1155Vault.sol index d7328a26d47..51f891f8f73 100644 --- a/packages/protocol/contracts/tokenvault/ERC1155Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC1155Vault.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol"; import diff --git a/packages/protocol/contracts/tokenvault/ERC20Vault.sol b/packages/protocol/contracts/tokenvault/ERC20Vault.sol index c3f517a739d..6cf02b7f6a9 100644 --- a/packages/protocol/contracts/tokenvault/ERC20Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC20Vault.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; import "lib/openzeppelin-contracts/contracts/token/ERC20/utils/SafeERC20.sol"; @@ -256,22 +256,27 @@ contract ERC20Vault is BaseVault { { checkRecallMessageContext(); - (, address token,, uint256 amount) = + (CanonicalERC20 memory ctoken,,, uint256 amount) = abi.decode(message.data[4:], (CanonicalERC20, address, address, uint256)); - if (token == address(0)) revert VAULT_INVALID_TOKEN(); + if (ctoken.addr == address(0)) revert VAULT_INVALID_TOKEN(); if (amount > 0) { - if (bridgedToCanonical[token].addr != address(0)) { - IBridgedERC20(token).mint(message.owner, amount); + if (bridgedToCanonical[ctoken.addr].addr != address(0)) { + IBridgedERC20(ctoken.addr).mint(message.owner, amount); } else { - ERC20(token).safeTransfer(message.owner, amount); + ERC20(ctoken.addr).safeTransfer(message.owner, amount); } } message.owner.sendEther(message.value); - emit TokenReleased({ msgHash: msgHash, from: message.owner, token: token, amount: amount }); + emit TokenReleased({ + msgHash: msgHash, + from: message.owner, + token: ctoken.addr, + amount: amount + }); } function name() public pure override returns (bytes32) { diff --git a/packages/protocol/contracts/tokenvault/ERC721Vault.sol b/packages/protocol/contracts/tokenvault/ERC721Vault.sol index 856422bff45..298f8237694 100644 --- a/packages/protocol/contracts/tokenvault/ERC721Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC721Vault.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol"; import diff --git a/packages/protocol/contracts/tokenvault/IBridgedERC20.sol b/packages/protocol/contracts/tokenvault/IBridgedERC20.sol index 5c92e8e2fc0..fa00ee8e75c 100644 --- a/packages/protocol/contracts/tokenvault/IBridgedERC20.sol +++ b/packages/protocol/contracts/tokenvault/IBridgedERC20.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; /// @title IBridgedERC20 /// @notice Interface for all bridged tokens. diff --git a/packages/protocol/contracts/tokenvault/LibBridgedToken.sol b/packages/protocol/contracts/tokenvault/LibBridgedToken.sol index a8b0b422741..2e2ba18de52 100644 --- a/packages/protocol/contracts/tokenvault/LibBridgedToken.sol +++ b/packages/protocol/contracts/tokenvault/LibBridgedToken.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/Strings.sol"; diff --git a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol index fa4851d7571..e8ed5d2092e 100644 --- a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol +++ b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../BridgedERC20Base.sol"; diff --git a/packages/protocol/foundry.toml b/packages/protocol/foundry.toml index 124a3b98dbf..004920fe3e9 100644 --- a/packages/protocol/foundry.toml +++ b/packages/protocol/foundry.toml @@ -1,6 +1,6 @@ # See more config options https://github.com/foundry-rs/foundry/tree/master/config [profile.default] -solc-version = "0.8.20" +solc-version = "0.8.24" src = 'contracts' out = 'out' test = 'test' diff --git a/packages/protocol/genesis/GenerateGenesis.g.sol b/packages/protocol/genesis/GenerateGenesis.g.sol index 3f8ab297f28..4b6905357db 100644 --- a/packages/protocol/genesis/GenerateGenesis.g.sol +++ b/packages/protocol/genesis/GenerateGenesis.g.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "forge-std/console2.sol"; import "forge-std/StdJson.sol"; diff --git a/packages/protocol/lib/p256-verifier b/packages/protocol/lib/p256-verifier index c8210cd99f9..29475ae300e 160000 --- a/packages/protocol/lib/p256-verifier +++ b/packages/protocol/lib/p256-verifier @@ -1 +1 @@ -Subproject commit c8210cd99f9f81a58e25a6a8afdb992fefbd9748 +Subproject commit 29475ae300ec95d98d5c7cc34c094846f0aa2dcd diff --git a/packages/protocol/script/AddSGXVerifierInstances.s.sol b/packages/protocol/script/AddSGXVerifierInstances.s.sol index 90cb08ed82d..6a61cf62666 100644 --- a/packages/protocol/script/AddSGXVerifierInstances.s.sol +++ b/packages/protocol/script/AddSGXVerifierInstances.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../test/DeployCapability.sol"; import "../contracts/L1/gov/TaikoTimelockController.sol"; diff --git a/packages/protocol/script/AuthorizeRemoteTaikoProtocols.s.sol b/packages/protocol/script/AuthorizeRemoteTaikoProtocols.s.sol index 0e2a77672fc..dccf825a541 100644 --- a/packages/protocol/script/AuthorizeRemoteTaikoProtocols.s.sol +++ b/packages/protocol/script/AuthorizeRemoteTaikoProtocols.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/DeployOnL1.s.sol b/packages/protocol/script/DeployOnL1.s.sol index 6833621f123..461165e4f87 100644 --- a/packages/protocol/script/DeployOnL1.s.sol +++ b/packages/protocol/script/DeployOnL1.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/utils/Strings.sol"; diff --git a/packages/protocol/script/DeployUSDCAdaptor.s.sol b/packages/protocol/script/DeployUSDCAdaptor.s.sol index 0f9b0926013..570d1b62f79 100644 --- a/packages/protocol/script/DeployUSDCAdaptor.s.sol +++ b/packages/protocol/script/DeployUSDCAdaptor.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../contracts/tokenvault/adaptors/USDCAdaptor.sol"; import "../contracts/tokenvault/ERC20Vault.sol"; diff --git a/packages/protocol/script/SetAddress.s.sol b/packages/protocol/script/SetAddress.s.sol index 568fbd7c317..12fb96263f3 100644 --- a/packages/protocol/script/SetAddress.s.sol +++ b/packages/protocol/script/SetAddress.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol index 691f738f0e5..9e688aa0369 100644 --- a/packages/protocol/script/SetDcapParams.s.sol +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; @@ -23,8 +23,6 @@ import "../test/automata-attestation/utils/DcapTestUtils.t.sol"; import "../test/automata-attestation/utils/V3JsonUtils.t.sol"; contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { - //@todo: Wand Yue -> after deployed with DeployOnL1, you have the parameters, fill in the proper - // .env vars the the parameter files, and run this script. uint256 public ownerPrivateKey = vm.envUint("PRIVATE_KEY"); // Owner of the attestation contract address public dcapAttestationAddress = vm.envAddress("ATTESTATION_ADDRESS"); address public sgxVerifier = vm.envAddress("SGX_VERIFIER_ADDRESS"); diff --git a/packages/protocol/script/SetRemoteBridgeSuites.s.sol b/packages/protocol/script/SetRemoteBridgeSuites.s.sol index 750bfdbd719..150739225f1 100644 --- a/packages/protocol/script/SetRemoteBridgeSuites.s.sol +++ b/packages/protocol/script/SetRemoteBridgeSuites.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../test/DeployCapability.sol"; import "../contracts/L1/gov/TaikoTimelockController.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeAddressManager.s.sol b/packages/protocol/script/upgrade/UpgradeAddressManager.s.sol index 714ab15b630..3405d7ef555 100644 --- a/packages/protocol/script/upgrade/UpgradeAddressManager.s.sol +++ b/packages/protocol/script/upgrade/UpgradeAddressManager.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeAssignmentHook.s.sol b/packages/protocol/script/upgrade/UpgradeAssignmentHook.s.sol index e0eacb0b11e..21ebcfd11f3 100644 --- a/packages/protocol/script/upgrade/UpgradeAssignmentHook.s.sol +++ b/packages/protocol/script/upgrade/UpgradeAssignmentHook.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeBridge.s.sol b/packages/protocol/script/upgrade/UpgradeBridge.s.sol index 15ce65cdcca..fc70da3664e 100644 --- a/packages/protocol/script/upgrade/UpgradeBridge.s.sol +++ b/packages/protocol/script/upgrade/UpgradeBridge.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeERC1155Vault.s.sol b/packages/protocol/script/upgrade/UpgradeERC1155Vault.s.sol index c6342e11aad..f937bb3fb19 100644 --- a/packages/protocol/script/upgrade/UpgradeERC1155Vault.s.sol +++ b/packages/protocol/script/upgrade/UpgradeERC1155Vault.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeERC20Vault.s.sol b/packages/protocol/script/upgrade/UpgradeERC20Vault.s.sol index 39c4316d2e7..0aa24567d8c 100644 --- a/packages/protocol/script/upgrade/UpgradeERC20Vault.s.sol +++ b/packages/protocol/script/upgrade/UpgradeERC20Vault.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeERC721Vault.s.sol b/packages/protocol/script/upgrade/UpgradeERC721Vault.s.sol index f778447af50..3502cf76315 100644 --- a/packages/protocol/script/upgrade/UpgradeERC721Vault.s.sol +++ b/packages/protocol/script/upgrade/UpgradeERC721Vault.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeGuardianProver.s.sol b/packages/protocol/script/upgrade/UpgradeGuardianProver.s.sol index af5ffc94ecf..6bfc16b4535 100644 --- a/packages/protocol/script/upgrade/UpgradeGuardianProver.s.sol +++ b/packages/protocol/script/upgrade/UpgradeGuardianProver.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeScript.s.sol b/packages/protocol/script/upgrade/UpgradeScript.s.sol index 95b76e69899..62da90ca5f0 100644 --- a/packages/protocol/script/upgrade/UpgradeScript.s.sol +++ b/packages/protocol/script/upgrade/UpgradeScript.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../contracts/L1/gov/TaikoTimelockController.sol"; import "lib/openzeppelin-contracts/contracts/proxy/utils/UUPSUpgradeable.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeSignalService.s.sol b/packages/protocol/script/upgrade/UpgradeSignalService.s.sol index 6350235e979..28ad4fc2a0e 100644 --- a/packages/protocol/script/upgrade/UpgradeSignalService.s.sol +++ b/packages/protocol/script/upgrade/UpgradeSignalService.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeTaikoGovernor.s.sol b/packages/protocol/script/upgrade/UpgradeTaikoGovernor.s.sol index 539ae3e1c25..d482a6d37bb 100644 --- a/packages/protocol/script/upgrade/UpgradeTaikoGovernor.s.sol +++ b/packages/protocol/script/upgrade/UpgradeTaikoGovernor.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeTaikoL1.s.sol b/packages/protocol/script/upgrade/UpgradeTaikoL1.s.sol index c8ddc342a10..3649ca34d64 100644 --- a/packages/protocol/script/upgrade/UpgradeTaikoL1.s.sol +++ b/packages/protocol/script/upgrade/UpgradeTaikoL1.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/script/upgrade/UpgradeTimelockController.s.sol b/packages/protocol/script/upgrade/UpgradeTimelockController.s.sol index fc909830dae..8c61cdd0010 100644 --- a/packages/protocol/script/upgrade/UpgradeTimelockController.s.sol +++ b/packages/protocol/script/upgrade/UpgradeTimelockController.s.sol @@ -12,7 +12,7 @@ // Blog: https://mirror.xyz/labs.taiko.eth // Youtube: https://www.youtube.com/@taikoxyz -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; diff --git a/packages/protocol/test/DeployCapability.sol b/packages/protocol/test/DeployCapability.sol index a726337d38b..6c7ed706c0e 100644 --- a/packages/protocol/test/DeployCapability.sol +++ b/packages/protocol/test/DeployCapability.sol @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/proxy/ERC1967/ERC1967Proxy.sol"; import "lib/openzeppelin-contracts-upgradeable/contracts/access/OwnableUpgradeable.sol"; diff --git a/packages/protocol/test/HelperContracts.sol b/packages/protocol/test/HelperContracts.sol index b027d4595e5..ea401f3b1e1 100644 --- a/packages/protocol/test/HelperContracts.sol +++ b/packages/protocol/test/HelperContracts.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../contracts/bridge/Bridge.sol"; import "../contracts/signal/SignalService.sol"; diff --git a/packages/protocol/test/L1/Guardians.t.sol b/packages/protocol/test/L1/Guardians.t.sol index 92e780ae195..ad5e074d6dd 100644 --- a/packages/protocol/test/L1/Guardians.t.sol +++ b/packages/protocol/test/L1/Guardians.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index 97e83d7ba8e..3259ecda832 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -1,8 +1,18 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./TaikoL1TestBase.sol"; +// For SGX remote attestation +import { AutomataDcapV3Attestation } from + "../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; +import { P256Verifier } from "../../lib/p256-verifier/src/P256Verifier.sol"; +import { SigVerifyLib } from "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; + +import "../automata-attestation/utils/DcapTestUtils.t.sol"; +import "../automata-attestation/utils/V3JsonUtils.t.sol"; + contract TestSgxVerifier is TaikoL1TestBase { // For SGX remote attestation diff --git a/packages/protocol/test/L1/TaikoL1.t.sol b/packages/protocol/test/L1/TaikoL1.t.sol index af11cdb9662..4c2c659c8e8 100644 --- a/packages/protocol/test/L1/TaikoL1.t.sol +++ b/packages/protocol/test/L1/TaikoL1.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./TaikoL1TestBase.sol"; diff --git a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol index 0b8da110073..92940f9c222 100644 --- a/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol +++ b/packages/protocol/test/L1/TaikoL1LibProvingWithTiers.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "./TaikoL1TestBase.sol"; @@ -172,9 +172,9 @@ contract TaikoL1LibProvingWithTiers is TaikoL1TestBase { // This proof cannot be verified obviously because of // signalRoot instead of blockHash uint16 minTier = meta.minTier; - proveBlock(Bob, Bob, meta, parentHash, signalRoot, signalRoot, minTier, ""); + // Try to contest proveBlock(Carol, Carol, meta, parentHash, blockHash, signalRoot, minTier, ""); vm.roll(block.number + 15 * 12); diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 178da000c40..b48e253ec53 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/L2/Lib1559Math.t.sol b/packages/protocol/test/L2/Lib1559Math.t.sol index fb24af5dba1..9689d37e675 100644 --- a/packages/protocol/test/L2/Lib1559Math.t.sol +++ b/packages/protocol/test/L2/Lib1559Math.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/L2/TaikoL2.t.sol b/packages/protocol/test/L2/TaikoL2.t.sol index aa351aaa9ea..3f91015452a 100644 --- a/packages/protocol/test/L2/TaikoL2.t.sol +++ b/packages/protocol/test/L2/TaikoL2.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index 09dc99b9824..2f674daa518 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "forge-std/Test.sol"; import "forge-std/console2.sol"; @@ -42,16 +42,6 @@ import "../contracts/test/erc20/FreeMintERC20.sol"; import "./DeployCapability.sol"; import "./HelperContracts.sol"; -// For SGX remote attestation -import { AutomataDcapV3Attestation } from - "../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; -import { P256Verifier } from "../lib/p256-verifier/src/P256Verifier.sol"; -import { SigVerifyLib } from "../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; -import { PEMCertChainLib } from "../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; - -import "./automata-attestation/utils/DcapTestUtils.t.sol"; -import "./automata-attestation/utils/V3JsonUtils.t.sol"; - abstract contract TaikoTest is Test, DeployCapability, DcapTestUtils, V3JsonUtils { uint256 private _seed = 0x12345678; address internal Alice = vm.addr(0x1); diff --git a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol index 0823338e3fd..c857cddd597 100644 --- a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: UNLICENSED -pragma solidity ^0.8.20; +pragma solidity 0.8.24; import "forge-std/Test.sol"; import "forge-std/console.sol"; diff --git a/packages/protocol/test/bridge/Bridge.t.sol b/packages/protocol/test/bridge/Bridge.t.sol index 7ea132752b6..3e5f01c95bd 100644 --- a/packages/protocol/test/bridge/Bridge.t.sol +++ b/packages/protocol/test/bridge/Bridge.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/common/EssentialContract.t.sol b/packages/protocol/test/common/EssentialContract.t.sol index 2b4d48ace6a..db68fe03815 100644 --- a/packages/protocol/test/common/EssentialContract.t.sol +++ b/packages/protocol/test/common/EssentialContract.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/libs/LibFixedPointMath.t.sol b/packages/protocol/test/libs/LibFixedPointMath.t.sol index aecedeb027a..b66828ca26e 100644 --- a/packages/protocol/test/libs/LibFixedPointMath.t.sol +++ b/packages/protocol/test/libs/LibFixedPointMath.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: UNLICENSED // Some of the tests are taken from: // https://github.com/recmo/experiment-solexp/blob/main/src/test/FixedPointMathLib.t.sol -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/signal/SignalService.t.sol b/packages/protocol/test/signal/SignalService.t.sol index dc8b97db94d..2b81f2d08c7 100644 --- a/packages/protocol/test/signal/SignalService.t.sol +++ b/packages/protocol/test/signal/SignalService.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/team/TimelockTokenPool.t.sol b/packages/protocol/test/team/TimelockTokenPool.t.sol index 9b20efb5dce..521b3bdc400 100644 --- a/packages/protocol/test/team/TimelockTokenPool.t.sol +++ b/packages/protocol/test/team/TimelockTokenPool.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/team/airdrop/MerkleClaimable.t.sol b/packages/protocol/test/team/airdrop/MerkleClaimable.t.sol index a7afe7e11bf..21d3e949e6a 100644 --- a/packages/protocol/test/team/airdrop/MerkleClaimable.t.sol +++ b/packages/protocol/test/team/airdrop/MerkleClaimable.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../../TaikoTest.sol"; diff --git a/packages/protocol/test/tokenvault/BridgedERC20.t.sol b/packages/protocol/test/tokenvault/BridgedERC20.t.sol index 26691947ade..34cbbe1a9a7 100644 --- a/packages/protocol/test/tokenvault/BridgedERC20.t.sol +++ b/packages/protocol/test/tokenvault/BridgedERC20.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/tokenvault/ERC1155Vault.t.sol b/packages/protocol/test/tokenvault/ERC1155Vault.t.sol index 8e1f2623c98..6d0dc4a3356 100644 --- a/packages/protocol/test/tokenvault/ERC1155Vault.t.sol +++ b/packages/protocol/test/tokenvault/ERC1155Vault.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC1155/ERC1155.sol"; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/tokenvault/ERC20Vault.t.sol b/packages/protocol/test/tokenvault/ERC20Vault.t.sol index 44b0ac7603f..864c66aee78 100644 --- a/packages/protocol/test/tokenvault/ERC20Vault.t.sol +++ b/packages/protocol/test/tokenvault/ERC20Vault.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "../TaikoTest.sol"; diff --git a/packages/protocol/test/tokenvault/ERC721Vault.t.sol b/packages/protocol/test/tokenvault/ERC721Vault.t.sol index dc25777b94c..7e96f4aabba 100644 --- a/packages/protocol/test/tokenvault/ERC721Vault.t.sol +++ b/packages/protocol/test/tokenvault/ERC721Vault.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.20; +pragma solidity 0.8.24; import "lib/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol"; import "../TaikoTest.sol"; From 27c2683cb64d86053f3277ae99fefdb4ce4c53c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 09:33:08 +0530 Subject: [PATCH 28/44] delete old submodule --- packages/protocol/lib/p256-verifier | 1 - 1 file changed, 1 deletion(-) delete mode 160000 packages/protocol/lib/p256-verifier diff --git a/packages/protocol/lib/p256-verifier b/packages/protocol/lib/p256-verifier deleted file mode 160000 index 29475ae300e..00000000000 --- a/packages/protocol/lib/p256-verifier +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 29475ae300ec95d98d5c7cc34c094846f0aa2dcd From 69680a639c3b2206625414a15872d9fecf367211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 09:47:44 +0530 Subject: [PATCH 29/44] Tests and 0.8.24 conform submodule --- .gitmodules | 4 ++++ packages/protocol/lib/p256-verifier | 1 + packages/protocol/test/L1/SgxVerifier.t.sol | 4 +++- packages/protocol/test/L1/TaikoL1TestBase.sol | 2 -- packages/protocol/test/TaikoTest.sol | 2 +- 5 files changed, 9 insertions(+), 4 deletions(-) create mode 160000 packages/protocol/lib/p256-verifier diff --git a/.gitmodules b/.gitmodules index 88b307ed84c..05b317fb278 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,7 @@ [submodule "packages/protocol/lib/solady"] path = packages/protocol/lib/solady url = https://github.com/Vectorized/solady +[submodule "packages/protocol/lib/p256-verifier"] + path = packages/protocol/lib/p256-verifier + url = https://github.com/taikoxyz/p256-verifier + branch = use_at_taiko diff --git a/packages/protocol/lib/p256-verifier b/packages/protocol/lib/p256-verifier new file mode 160000 index 00000000000..6ef45b11764 --- /dev/null +++ b/packages/protocol/lib/p256-verifier @@ -0,0 +1 @@ +Subproject commit 6ef45b117642786b08a37b4c37c6a6ce151166da diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index 3259ecda832..d8e39d1c6a8 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -13,7 +13,7 @@ import { PEMCertChainLib } from "../../contracts/thirdparty/automata-attestation import "../automata-attestation/utils/DcapTestUtils.t.sol"; import "../automata-attestation/utils/V3JsonUtils.t.sol"; -contract TestSgxVerifier is TaikoL1TestBase { +contract TestSgxVerifier is TaikoL1TestBase, DcapTestUtils, V3JsonUtils { // For SGX remote attestation AutomataDcapV3Attestation attestation; @@ -35,6 +35,8 @@ contract TestSgxVerifier is TaikoL1TestBase { // Call the TaikoL1TestBase setUp() super.setUp(); + vm.warp(1_695_435_682); + p256Verifier = new P256Verifier(); sigVerifyLib = new SigVerifyLib(address(p256Verifier)); pemCertChainLib = new PEMCertChainLib(); diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index b48e253ec53..6c51b5f7830 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -68,8 +68,6 @@ abstract contract TaikoL1TestBase is TaikoTest { }) ); - vm.warp(1_695_435_682); - address[] memory initSgxInstances = new address[](1); initSgxInstances[0] = SGX_X_0; sv.addInstances(initSgxInstances); diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index 2f674daa518..024f379630c 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -42,7 +42,7 @@ import "../contracts/test/erc20/FreeMintERC20.sol"; import "./DeployCapability.sol"; import "./HelperContracts.sol"; -abstract contract TaikoTest is Test, DeployCapability, DcapTestUtils, V3JsonUtils { +abstract contract TaikoTest is Test, DeployCapability { uint256 private _seed = 0x12345678; address internal Alice = vm.addr(0x1); address internal Bob = vm.addr(0x2); From bdba41d668f6938f70c96c51e07be28c65040254 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 10:08:24 +0530 Subject: [PATCH 30/44] adaptor and erc721 vault --- packages/protocol/contracts/tokenvault/ERC721Vault.sol | 2 +- packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/tokenvault/ERC721Vault.sol b/packages/protocol/contracts/tokenvault/ERC721Vault.sol index 298f8237694..ef1b57d73b7 100644 --- a/packages/protocol/contracts/tokenvault/ERC721Vault.sol +++ b/packages/protocol/contracts/tokenvault/ERC721Vault.sol @@ -234,7 +234,7 @@ contract ERC721Vault is BaseNFTVault, IERC721ReceiverUpgradeable { }); for (uint256 i; i < op.tokenIds.length; ++i) { - t.transferFrom(user, address(this), op.tokenIds[i]); + t.safeTransferFrom(user, address(this), op.tokenIds[i]); } } } diff --git a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol index e8ed5d2092e..8735d6643ea 100644 --- a/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol +++ b/packages/protocol/contracts/tokenvault/adaptors/USDCAdaptor.sol @@ -19,7 +19,7 @@ import "../BridgedERC20Base.sol"; interface IUSDC { function burn(uint256 amount) external; function mint(address to, uint256 amount) external; - function transferFrom(address from, address to, uint256 amount) external; + function transferFrom(address from, address to, uint256 value) external returns (bool); } /// @title USDCAdaptor From 75d22231dc63e949a53cc2a69f2ef9a9faaba433 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 13:33:05 +0530 Subject: [PATCH 31/44] Use alpha6 for erc20 and nft ad --- .../contracts/team/airdrop/ERC20Airdrop.sol | 4 ++-- .../contracts/team/airdrop/ERC721Airdrop.sol | 14 ++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol index 9ae29a7fb37..488eb80e4a5 100644 --- a/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol +++ b/packages/protocol/contracts/team/airdrop/ERC20Airdrop.sol @@ -14,7 +14,7 @@ pragma solidity 0.8.24; -import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC20/ERC20Upgradeable.sol"; +import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import "./MerkleClaimable.sol"; /// @title ERC20Airdrop @@ -43,6 +43,6 @@ contract ERC20Airdrop is MerkleClaimable { function _claimWithData(bytes calldata data) internal override { (address user, uint256 amount) = abi.decode(data, (address, uint256)); - IERC20Upgradeable(token).transferFrom(vault, user, amount); + IERC20(token).transferFrom(vault, user, amount); } } diff --git a/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol b/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol index 488eb80e4a5..8bb7201af18 100644 --- a/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol +++ b/packages/protocol/contracts/team/airdrop/ERC721Airdrop.sol @@ -14,12 +14,11 @@ pragma solidity 0.8.24; -import "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; +import "lib/openzeppelin-contracts-upgradeable/contracts/token/ERC721/ERC721Upgradeable.sol"; import "./MerkleClaimable.sol"; -/// @title ERC20Airdrop -/// Contract for managing Taiko token airdrop for eligible users -contract ERC20Airdrop is MerkleClaimable { +/// @title ERC721Airdrop +contract ERC721Airdrop is MerkleClaimable { address public token; address public vault; uint256[48] private __gap; @@ -42,7 +41,10 @@ contract ERC20Airdrop is MerkleClaimable { } function _claimWithData(bytes calldata data) internal override { - (address user, uint256 amount) = abi.decode(data, (address, uint256)); - IERC20(token).transferFrom(vault, user, amount); + (address user, uint256[] memory tokenIds) = abi.decode(data, (address, uint256[])); + + for (uint256 i; i < tokenIds.length; ++i) { + IERC721Upgradeable(token).safeTransferFrom(vault, user, tokenIds[i]); + } } } From 66f337b16e4fe3313226902f3c73e654c2b33330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 13:50:29 +0530 Subject: [PATCH 32/44] forge fmt and move some test vars --- packages/protocol/contracts/L1/TaikoL1.sol | 2 +- .../protocol/contracts/L1/verifiers/SgxVerifier.sol | 5 ++--- packages/protocol/test/L1/SgxVerifier.t.sol | 12 ++++++++---- packages/protocol/test/L1/TaikoL1TestBase.sol | 3 +++ packages/protocol/test/TaikoTest.sol | 5 ----- .../AutomataDcapV3AttestationTest.t.sol | 9 ++++++--- .../automata-attestation/utils/DcapTestUtils.t.sol | 9 ++++++--- .../automata-attestation/utils/V3JsonUtils.t.sol | 3 ++- 8 files changed, 28 insertions(+), 20 deletions(-) diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 2fb39f0623d..47dcc45e9ff 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -248,7 +248,7 @@ contract TaikoL1 is return LibVerifying.isConfigValid(getConfig()); } - function _authorizePause(address) internal override { + function _authorizePause(address) internal view override { if (msg.sender != owner() && msg.sender != resolve("rollup_watchdog", true)) { revert L1_UNAUTHORIZED(); } diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index cbd874b22d8..9b9431f3dfe 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -100,9 +100,8 @@ contract SgxVerifier is EssentialContract, IVerifier { if (!verified) revert SGX_INVALID_ATTESTATION(); address[] memory _address = new address[](1); - _address[0] = address( - bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20)) - ); + _address[0] = + address(bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20))); return _addInstances(_address)[0]; } diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index d8e39d1c6a8..f8a6a912512 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -7,14 +7,18 @@ import "./TaikoL1TestBase.sol"; import { AutomataDcapV3Attestation } from "../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; import { P256Verifier } from "../../lib/p256-verifier/src/P256Verifier.sol"; -import { SigVerifyLib } from "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; -import { PEMCertChainLib } from "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; +import { SigVerifyLib } from + "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from + "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; import "../automata-attestation/utils/DcapTestUtils.t.sol"; import "../automata-attestation/utils/V3JsonUtils.t.sol"; -contract TestSgxVerifier is TaikoL1TestBase, DcapTestUtils, V3JsonUtils { - +contract TestSgxVerifier is TaikoL1TestBase, DcapTestUtils, V3JsonUtils { + address internal SGX_Y = + vm.addr(0x9b1bb8cb3bdb539d0d1f03951d27f167f2d5443e7ef0d7ce745cd4ec619d3dd7); + address internal SGX_Z = randAddress(); // For SGX remote attestation AutomataDcapV3Attestation attestation; SigVerifyLib sigVerifyLib; diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 6c51b5f7830..7dd97a7b81c 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -29,6 +29,9 @@ abstract contract TaikoL1TestBase is TaikoTest { address public L2SS = randAddress(); address public L2 = randAddress(); + // Bootstrapped SGX instances (by owner) + address internal SGX_X_0 = vm.addr(0x4); + address internal SGX_X_1 = vm.addr(0x5); function deployTaikoL1() internal virtual returns (TaikoL1 taikoL1); diff --git a/packages/protocol/test/TaikoTest.sol b/packages/protocol/test/TaikoTest.sol index 024f379630c..44d227c0e4a 100644 --- a/packages/protocol/test/TaikoTest.sol +++ b/packages/protocol/test/TaikoTest.sol @@ -70,11 +70,6 @@ abstract contract TaikoTest is Test, DeployCapability { address internal Xavier = randAddress(); address internal Yasmine = randAddress(); address internal Zachary = randAddress(); - address internal SGX_X_0 = vm.addr(0x4); - address internal SGX_X_1 = vm.addr(0x5); - address internal SGX_Y = - vm.addr(0x9b1bb8cb3bdb539d0d1f03951d27f167f2d5443e7ef0d7ce745cd4ec619d3dd7); - address internal SGX_Z = randAddress(); function randAddress() internal returns (address) { bytes32 randomHash = keccak256(abi.encodePacked("address", _seed++)); diff --git a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol index c857cddd597..01185aaf37c 100644 --- a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol @@ -7,9 +7,12 @@ import "forge-std/StdJson.sol"; import { AutomataDcapV3Attestation } from "../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; import { P256Verifier } from "../../lib/p256-verifier/src/P256Verifier.sol"; -import { SigVerifyLib } from "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; -import { PEMCertChainLib } from "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; -import { V3Struct } from "../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; +import { SigVerifyLib } from + "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from + "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; +import { V3Struct } from + "../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; import { BytesUtils } from "../../contracts/thirdparty/automata-attestation/utils/BytesUtils.sol"; import { Base64 } from "../../lib/solady/src/utils/Base64.sol"; import "./utils/DcapTestUtils.t.sol"; diff --git a/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol b/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol index 9a113f31b72..35efb52bfea 100644 --- a/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol +++ b/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol @@ -1,9 +1,12 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import { TCBInfoStruct } from "../../../contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol"; -import { EnclaveIdStruct } from "../../../contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol"; -import { V3Struct } from "../../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; +import { TCBInfoStruct } from + "../../../contracts/thirdparty/automata-attestation/lib/TCBInfoStruct.sol"; +import { EnclaveIdStruct } from + "../../../contracts/thirdparty/automata-attestation/lib/EnclaveIdStruct.sol"; +import { V3Struct } from + "../../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; import { JSONParserLib } from "../../../lib/solady/src/utils/JSONParserLib.sol"; import { LibString } from "../../../lib/solady/src/utils/LibString.sol"; diff --git a/packages/protocol/test/automata-attestation/utils/V3JsonUtils.t.sol b/packages/protocol/test/automata-attestation/utils/V3JsonUtils.t.sol index dfcab2d573f..ff0e337f143 100644 --- a/packages/protocol/test/automata-attestation/utils/V3JsonUtils.t.sol +++ b/packages/protocol/test/automata-attestation/utils/V3JsonUtils.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.13; -import { V3Struct } from "../../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; +import { V3Struct } from + "../../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; import { JSONParserLib } from "../../../lib/solady/src/utils/JSONParserLib.sol"; import { LibString } from "../../../lib/solady/src/utils/LibString.sol"; From 4e6bff2d2cd4d7419abd2d538d38c758b1dd7269 Mon Sep 17 00:00:00 2001 From: smtmfft <99081233+smtmfft@users.noreply.github.com> Date: Tue, 30 Jan 2024 17:18:00 +0800 Subject: [PATCH 33/44] fix(protocol): remove useless env params (#15611) Signed-off-by: smtmfft --- .../script/config_dcap_sgx_verifier.sh | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/packages/protocol/script/config_dcap_sgx_verifier.sh b/packages/protocol/script/config_dcap_sgx_verifier.sh index 2e64a2ff827..7f4ba758aeb 100755 --- a/packages/protocol/script/config_dcap_sgx_verifier.sh +++ b/packages/protocol/script/config_dcap_sgx_verifier.sh @@ -1,25 +1,14 @@ +# for foundry test only! PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ -PROPOSER=0x0000000000000000000000000000000000000000 \ -PROPOSER_ONE=0x0000000000000000000000000000000000000000 \ -GUARDIAN_PROVERS="0x1000777700000000000000000000000000000001,0x1000777700000000000000000000000000000002,0x1000777700000000000000000000000000000003,0x1000777700000000000000000000000000000004,0x1000777700000000000000000000000000000005" \ -MIN_GUARDIANS=3 \ -TAIKO_L2_ADDRESS=0x1000777700000000000000000000000000000001 \ -L2_SIGNAL_SERVICE=0x1000777700000000000000000000000000000007 \ -SECURITY_COUNCIL=0x60997970C51812dc3A010C7d01b50e0d17dc79C8 \ -TAIKO_TOKEN_PREMINT_RECIPIENT=0xa0Ee7A142d267C1f36714E4a8F75612F20a79720 \ -TAIKO_TOKEN_NAME="Taiko Token Katla" \ -TAIKO_TOKEN_SYMBOL=TTKOk \ -SHARED_ADDRESS_MANAGER=0x0000000000000000000000000000000000000000 \ -L2_GENESIS_HASH=0xee1950562d42f0da28bd4550d88886bc90894c77c9c9eaefef775d4c8223f259 \ ETHERSCAN_API_KEY=ABC123ABC123ABC123ABC123ABC123ABC1 \ LOG_LEVEL=DEBUG \ REPORT_GAS=true \ SGX_VERIFIER_ADDRESS=0x1fA02b2d6A771842690194Cf62D91bdd92BfE28d \ TIMELOCK_ADDRESS=0xB2b580ce436E6F77A5713D80887e14788Ef49c9A \ ATTESTATION_ADDRESS=0xC9a43158891282A2B1475592D5719c001986Aaec \ -TCB_INFO_PATH=/test/onchainRA/assets/0923/tcbInfo.json \ -QEID_PATH=/test/onchainRA/assets/0923/identity.json \ -V3_QUOTE_PATH=/test/onchainRA/assets/0923/v3quote.json \ +TCB_INFO_PATH=/test/automata-attestation/assets/0923/tcbInfo.json \ +QEID_PATH=/test/automata-attestation/assets/0923/identity.json \ +V3_QUOTE_PATH=/test/automata-attestation/assets/0923/v3quote.json \ MR_ENCLAVE=0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef \ MR_SIGNER=0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef \ forge script script/SetDcapParams.s.sol:SetDcapParams \ @@ -27,5 +16,5 @@ forge script script/SetDcapParams.s.sol:SetDcapParams \ --broadcast \ --ffi \ -vvvv \ - --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ + --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 \ #foundry test key --block-gas-limit 100000000 \ No newline at end of file From 3dba5dac8d0d673ae68a08720f71c4df893e81a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 15:05:55 +0530 Subject: [PATCH 34/44] remove permissions as redundant --- packages/protocol/foundry.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/protocol/foundry.toml b/packages/protocol/foundry.toml index 06f044268e3..2f5082ea097 100644 --- a/packages/protocol/foundry.toml +++ b/packages/protocol/foundry.toml @@ -22,7 +22,6 @@ fs_permissions = [ { access = "read-write", path = "./deployments" }, { access = "read", path = "./test" }, { access = "read", path = "./genesis" }, - { access = "read", path = "./test/onchainRA/assets/0923"}, ] fuzz = { runs = 256 } From 2af905fcf5c1fb1209c465d24f75b82e31ba33b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Tue, 30 Jan 2024 21:23:05 +0530 Subject: [PATCH 35/44] reference thirdparty --- packages/protocol/contracts/thirdparty/README.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 packages/protocol/contracts/thirdparty/README.md diff --git a/packages/protocol/contracts/thirdparty/README.md b/packages/protocol/contracts/thirdparty/README.md new file mode 100644 index 00000000000..56f55636d20 --- /dev/null +++ b/packages/protocol/contracts/thirdparty/README.md @@ -0,0 +1 @@ +/automata-attestation: original code (main branch) forked from https://github.com/automata-network/automata-dcap-v3-attestation and applied some gas optimizations here: https://github.com/smtmfft/automata-dcap-v3-attestation/tree/optimize-gas, which then got merged into taiko-mono. \ No newline at end of file From 5c4ec04fc60f0e885075c266cda0a086b4b2cf78 Mon Sep 17 00:00:00 2001 From: Daniel Wang <99078276+dantaik@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:18:15 +0800 Subject: [PATCH 36/44] Update SgxVerifier.sol --- packages/protocol/contracts/L1/verifiers/SgxVerifier.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index b4a823ccb99..05496e55576 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -101,7 +101,7 @@ contract SgxVerifier is EssentialContract, IVerifier { address[] memory _address = new address[](1); _address[0] = - address(bytes20(LibBytesUtils.slice(attestation.localEnclaveReport.reportData, 0, 20))); + address(bytes20(Bytes.slice(attestation.localEnclaveReport.reportData, 0, 20))); return _addInstances(_address)[0]; } From b15bd179ce8e004f4bf8d720686469f62a6ed043 Mon Sep 17 00:00:00 2001 From: Daniel Wang <99078276+dantaik@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:29:46 +0800 Subject: [PATCH 37/44] Update TaikoL1.sol --- packages/protocol/contracts/L1/TaikoL1.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/protocol/contracts/L1/TaikoL1.sol b/packages/protocol/contracts/L1/TaikoL1.sol index 4fbc825b0c7..297d76e4d18 100644 --- a/packages/protocol/contracts/L1/TaikoL1.sol +++ b/packages/protocol/contracts/L1/TaikoL1.sol @@ -248,7 +248,7 @@ contract TaikoL1 is return LibVerifying.isConfigValid(getConfig()); } - function _authorizePause(address) internal view override { + function _authorizePause(address) internal override { if (msg.sender != owner() && msg.sender != resolve("rollup_watchdog", true)) { revert L1_UNAUTHORIZED(); } From a2b06df1bd2411785f9fd29b8ef77168541e64a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Wed, 31 Jan 2024 23:10:45 +0530 Subject: [PATCH 38/44] Brecht comments --- .../contracts/L1/verifiers/SgxVerifier.sol | 50 ++++++++++--- .../automata-attestation/utils/BytesUtils.sol | 31 +------- packages/protocol/script/SetDcapParams.s.sol | 4 +- packages/protocol/test/L1/SgxVerifier.t.sol | 63 +++++----------- packages/protocol/test/L1/TaikoL1TestBase.sol | 2 +- .../AutomataDcapV3AttestationTest.t.sol | 69 +---------------- .../common/AttestationTestBase.t.sol | 75 +++++++++++++++++++ .../utils/DcapTestUtils.t.sol | 8 +- 8 files changed, 146 insertions(+), 156 deletions(-) create mode 100644 packages/protocol/test/automata-attestation/common/AttestationTestBase.t.sol diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 05496e55576..174186b1134 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -34,10 +34,14 @@ contract SgxVerifier is EssentialContract, IVerifier { /// bootstrapping the network with trustworthy instances. struct Instance { address addr; - uint64 addedAt; // We can calculate if expired + uint64 addedAt; // We can calculate if expired or not yet valid + bool checkValidityCoolTime; // Owner added sgx instances not needed to have a cooldown for + // validity } uint256 public constant INSTANCE_EXPIRY = 180 days; + // A security feature, to enable device + uint256 public constant INSTANCE_VALIDITY_DELAY = 1 days; /// @dev For gas savings, we shall assign each SGX instance with an id /// so that when we need to set a new pub key, just write storage once. @@ -56,12 +60,14 @@ contract SgxVerifier is EssentialContract, IVerifier { event InstanceAdded( uint256 indexed id, address indexed instance, address replaced, uint256 timstamp ); + event InstanceDeleted(uint256 indexed id, address indexed instance); error SGX_INVALID_ATTESTATION(); error SGX_INVALID_INSTANCE(); error SGX_INVALID_INSTANCES(); error SGX_INVALID_PROOF(); error SGX_MISSING_ATTESTATION(); + error SGX_RA_NOT_SUPPORTED(); /// @notice Initializes the contract with the provided address manager. /// @param _addressManager The address of the address manager contract. @@ -78,7 +84,20 @@ contract SgxVerifier is EssentialContract, IVerifier { returns (uint256[] memory ids) { if (_instances.length == 0) revert SGX_INVALID_INSTANCES(); - ids = _addInstances(_instances); + ids = _addInstances(_instances, false); + } + + /// @notice Deletes SGX instances from the registry. + /// @param _ids The ids array of SGX instances. + function deleteInstances(uint256[] calldata _ids) external onlyOwner { + if (_ids.length == 0) revert SGX_INVALID_INSTANCES(); + for (uint256 i; i < _ids.length; ++i) { + if (instances[_ids[i]].addr == address(0)) revert SGX_INVALID_INSTANCE(); + + emit InstanceDeleted(_ids[i], instances[_ids[i]].addr); + + delete instances[i]; + } } /// @notice Adds an SGX instance after the attestation is verified @@ -91,19 +110,17 @@ contract SgxVerifier is EssentialContract, IVerifier { address automataDcapAttestation = (resolve("automata_dcap_attestation", true)); if (automataDcapAttestation == address(0)) { - return type(uint256).max; + revert SGX_RA_NOT_SUPPORTED(); } - // Still possible to be backward compatible and register instances by the owner. (bool verified,) = IAttestation(automataDcapAttestation).verifyParsedQuote(attestation); if (!verified) revert SGX_INVALID_ATTESTATION(); address[] memory _address = new address[](1); - _address[0] = - address(bytes20(Bytes.slice(attestation.localEnclaveReport.reportData, 0, 20))); + _address[0] = address(bytes20(attestation.localEnclaveReport.reportData)); - return _addInstances(_address)[0]; + return _addInstances(_address, true)[0]; } /// @inheritdoc IVerifier @@ -157,13 +174,20 @@ contract SgxVerifier is EssentialContract, IVerifier { ); } - function _addInstances(address[] memory _instances) private returns (uint256[] memory ids) { + function _addInstances( + address[] memory _instances, + bool validityCooldownRequired + ) + private + returns (uint256[] memory ids) + { ids = new uint256[](_instances.length); for (uint256 i; i < _instances.length; ++i) { if (_instances[i] == address(0)) revert SGX_INVALID_INSTANCE(); - instances[nextInstanceId] = Instance(_instances[i], uint64(block.timestamp)); + instances[nextInstanceId] = + Instance(_instances[i], uint64(block.timestamp), validityCooldownRequired); ids[i] = nextInstanceId; emit InstanceAdded(nextInstanceId, _instances[i], address(0), block.timestamp); @@ -173,13 +197,19 @@ contract SgxVerifier is EssentialContract, IVerifier { } function _replaceInstance(uint256 id, address oldInstance, address newInstance) private { - instances[id] = Instance(newInstance, uint64(block.timestamp)); + // Replacing an instance means, it went through a cooldwon (if added by on-chain RA) so no + // need to have a cooldown + instances[id] = Instance(newInstance, uint64(block.timestamp), false); emit InstanceAdded(id, newInstance, oldInstance, block.timestamp); } function _isInstanceValid(uint256 id, address instance) private view returns (bool) { if (instance == address(0)) return false; if (instance != instances[id].addr) return false; + if ( + instances[id].checkValidityCoolTime == true + && instances[id].addedAt + INSTANCE_VALIDITY_DELAY < block.timestamp + ) return false; return instances[id].addedAt + INSTANCE_EXPIRY > block.timestamp; } } diff --git a/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol b/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol index 92b7dcfee5a..22f3f3f77dc 100644 --- a/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol +++ b/packages/protocol/contracts/thirdparty/automata-attestation/utils/BytesUtils.sol @@ -269,27 +269,8 @@ library BytesUtils { } function memcpy(uint256 dest, uint256 src, uint256 len) private pure { - // Copy word-length chunks while possible - for (; len >= 32; len -= 32) { - assembly { - mstore(dest, mload(src)) - } - dest += 32; - src += 32; - } - - // Copy remaining bytes - uint256 mask; - if (len == 0) { - mask = type(uint256).max; // Set to maximum value of uint256 - } else { - mask = 256 ** (32 - len) - 1; - } - assembly { - let srcpart := and(mload(src), not(mask)) - let destpart := and(mload(dest), mask) - mstore(dest, or(destpart, srcpart)) + mcopy(dest, src, len) } } @@ -387,14 +368,6 @@ library BytesUtils { } function compareBytes(bytes memory a, bytes memory b) internal pure returns (bool) { - if (a.length != b.length) { - return false; - } - for (uint256 i = 0; i < a.length; i++) { - if (a[i] != b[i]) { - return false; - } - } - return true; + return keccak256(a) == keccak256(b); } } diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol index 9e688aa0369..76975a9fb6c 100644 --- a/packages/protocol/script/SetDcapParams.s.sol +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -38,7 +38,8 @@ contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { vm.startBroadcast(ownerPrivateKey); - // all in one + // all in one, means sets MrEnclave, MrSigner, configures identitiy json and tcb info, + // register sgx instance setMrEnclave(); setMrSigner(); configureQeIdentityJson(); @@ -68,7 +69,6 @@ contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = parseTcbInfoJson(tcbInfoJson); - // string memory fmspc = "00606a000000"; string memory fmspc = parsedTcbInfo.fmspc; AutomataDcapV3Attestation(dcapAttestationAddress).configureTcbInfoJson(fmspc, parsedTcbInfo); console.log("tcbParsedSuccess: %s", tcbParsedSuccess); diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index f8a6a912512..b2e86cd7862 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -2,33 +2,12 @@ pragma solidity 0.8.24; import "./TaikoL1TestBase.sol"; +import "../automata-attestation/common/AttestationTestBase.t.sol"; -// For SGX remote attestation -import { AutomataDcapV3Attestation } from - "../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; -import { P256Verifier } from "../../lib/p256-verifier/src/P256Verifier.sol"; -import { SigVerifyLib } from - "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; -import { PEMCertChainLib } from - "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; - -import "../automata-attestation/utils/DcapTestUtils.t.sol"; -import "../automata-attestation/utils/V3JsonUtils.t.sol"; - -contract TestSgxVerifier is TaikoL1TestBase, DcapTestUtils, V3JsonUtils { +contract TestSgxVerifier is TaikoL1TestBase, AttestationTestBase { address internal SGX_Y = vm.addr(0x9b1bb8cb3bdb539d0d1f03951d27f167f2d5443e7ef0d7ce745cd4ec619d3dd7); address internal SGX_Z = randAddress(); - // For SGX remote attestation - AutomataDcapV3Attestation attestation; - SigVerifyLib sigVerifyLib; - P256Verifier p256Verifier; - PEMCertChainLib pemCertChainLib; - string internal constant tcbInfoPath = "/test/automata-attestation/assets/0923/tcbInfo.json"; - string internal constant idPath = "/test/automata-attestation/assets/0923/identity.json"; - string internal constant v3QuotePath = "/test/automata-attestation/assets/0923/v3quote.json"; - bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; - bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; function deployTaikoL1() internal override returns (TaikoL1) { return @@ -39,28 +18,8 @@ contract TestSgxVerifier is TaikoL1TestBase, DcapTestUtils, V3JsonUtils { // Call the TaikoL1TestBase setUp() super.setUp(); - vm.warp(1_695_435_682); - - p256Verifier = new P256Verifier(); - sigVerifyLib = new SigVerifyLib(address(p256Verifier)); - pemCertChainLib = new PEMCertChainLib(); - attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); - attestation.setMrEnclave(mrEnclave, true); - attestation.setMrSigner(mrSigner, true); - - string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); - string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); - - string memory fmspc = "00606a000000"; - (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = - parseTcbInfoJson(tcbInfoJson); - require(tcbParsedSuccess, "tcb parsed failed"); - attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); - - (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - require(qeIdParsedSuccess, "qeid parsed failed"); - attestation.configureQeIdentityJson(parsedEnclaveId); + // Call the AttestationTestBase init setup + super.intialSetup(); registerAddress("automata_dcap_attestation", address(attestation)); } @@ -84,6 +43,20 @@ contract TestSgxVerifier is TaikoL1TestBase, DcapTestUtils, V3JsonUtils { sv.addInstances(_instances); } + function test_deleteInstancesByOwner() external { + uint256[] memory _ids = new uint[](1); + _ids[0] = 0; + + address instance; + (instance,,) = sv.instances(0); + assertEq(instance, SGX_X_0); + + sv.deleteInstances(_ids); + + (instance,,) = sv.instances(0); + assertEq(instance, address(0)); + } + function test_registerInstanceWithAttestation() external { string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 7dd97a7b81c..2ff47a856ac 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -276,7 +276,7 @@ abstract contract TaikoL1TestBase is TaikoTest { // Keep changing the pub key associated with an instance to avoid // attacks, // obviously just a mock due to 2 addresses changing all the time. - (newInstance,) = sv.instances(0); + (newInstance,,) = sv.instances(0); if (newInstance == SGX_X_0) { newInstance = SGX_X_1; } else { diff --git a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol index 01185aaf37c..5254ae67f33 100644 --- a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol @@ -4,76 +4,15 @@ pragma solidity 0.8.24; import "forge-std/Test.sol"; import "forge-std/console.sol"; import "forge-std/StdJson.sol"; -import { AutomataDcapV3Attestation } from - "../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; -import { P256Verifier } from "../../lib/p256-verifier/src/P256Verifier.sol"; -import { SigVerifyLib } from - "../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; -import { PEMCertChainLib } from - "../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; -import { V3Struct } from - "../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; -import { BytesUtils } from "../../contracts/thirdparty/automata-attestation/utils/BytesUtils.sol"; -import { Base64 } from "../../lib/solady/src/utils/Base64.sol"; -import "./utils/DcapTestUtils.t.sol"; -import "./utils/V3JsonUtils.t.sol"; +import "./common/AttestationTestBase.t.sol"; -contract AutomataDcapV3AttestationTest is Test, DcapTestUtils, V3JsonUtils { +contract AutomataDcapV3AttestationTest is Test, AttestationTestBase { using BytesUtils for bytes; using stdJson for string; - AutomataDcapV3Attestation attestation; - SigVerifyLib sigVerifyLib; - P256Verifier p256Verifier; - PEMCertChainLib pemCertChainLib; - // use a network that where the P256Verifier contract exists - // ref: https://github.com/daimo-eth/p256-verifier - //string internal rpcUrl = vm.envString("RPC_URL"); - string internal constant tcbInfoPath = "/test/automata-attestation/assets/0923/tcbInfo.json"; - string internal constant idPath = "/test/automata-attestation/assets/0923/identity.json"; - string internal constant v3QuotePath = "/test/automata-attestation/assets/0923/v3quote.json"; - address constant admin = address(1); - address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; - bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; - bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; - - bytes sampleQuote = - hex"030002000000000009000e00939a7233f79c4ca9940a0db3957f0607ccb12a326354d33986ff47365f17ad4c000000000c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000e70000000000000046049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a00000000000000000000000000000000000000000000000000000000000000000ef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca10000084af1f392be216944059f3fa05bf91e1b4e9b513c67493521eb4488af35f49c8f300d57955afc1df97d423c8718ed5b0af82f71047a229df221faa6817ad5daa44131b5c2ed877295959f7333543ba3f17994d767da194a27ba7a4e8a71940118a138dce8499572433c2cc4e4312f92e7144b26f84c59022bfc9aea59967f00d0c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf00000000000000000000000000000000000000000000000000000000000000008c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a654bcd78ffaa5cfc888fc90cbc24fb7f6e19bc8661671f1e3b2cc947db3b6340000000000000000000000000000000000000000000000000000000000000000839adce904d2aec1fc021ad0ec370c7176942d4b64939b95a2e1e1d3e09bf2e57093231f4308b64e8f53b81cd6ae36fc52f202e66ac77b93b13307ee577be36b2000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0500620e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494945386a4343424a696741774942416749554b6e314f2b2b58517264456161433535634a4c307470464867336b77436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a4d774f4449304d6a45304d444d775768634e4d7a41774f4449304d6a45304d444d770a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d34394177454841304941424e47520a727a716c416d4a66617756324b67656a39576e774a736666457868445631756847396e6d57377430505a646e6276732f6c677872584255625657436d5043456f0a4f49587768563673736d6e6b6b48462b576d536a67674d4f4d494944436a416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c33597a4c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f424259454641337234524b62476e54316e584c775a5a7272515559410a4a6b776c4d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f77594a4b6f5a496876684e415130420a424949434c444343416967774867594b4b6f5a496876684e415130424151515179753373424e6d7632566643337932772f445344627a434341575547436971470a534962345451454e41514977676746564d42414743797147534962345451454e415149424167454d4d42414743797147534962345451454e415149434167454d0a4d42414743797147534962345451454e41514944416745444d42414743797147534962345451454e41514945416745444d42454743797147534962345451454e0a41514946416749412f7a415242677371686b69472b4530424451454342674943415038774541594c4b6f5a496876684e4151304241676343415145774541594c0a4b6f5a496876684e4151304241676743415141774541594c4b6f5a496876684e4151304241676b43415141774541594c4b6f5a496876684e4151304241676f430a415141774541594c4b6f5a496876684e4151304241677343415141774541594c4b6f5a496876684e4151304241677743415141774541594c4b6f5a496876684e0a4151304241673043415141774541594c4b6f5a496876684e4151304241673443415141774541594c4b6f5a496876684e4151304241673843415141774541594c0a4b6f5a496876684e4151304241684143415141774541594c4b6f5a496876684e4151304241684543415130774877594c4b6f5a496876684e41513042416849450a4541774d4177502f2f7745414141414141414141414141774541594b4b6f5a496876684e4151304241775143414141774641594b4b6f5a496876684e415130420a4241514741474271414141414d41384743697147534962345451454e4151554b415145774867594b4b6f5a496876684e415130424267515136657645326f42790a6f684e362f30727741346d642b6a424542676f71686b69472b453042445145484d4459774541594c4b6f5a496876684e4151304242774542416638774541594c0a4b6f5a496876684e4151304242774942415141774541594c4b6f5a496876684e4151304242774d4241514177436759494b6f5a497a6a304541774944534141770a52514967522b344377346437476a73684848436c7a394c6269785a4a45632f31666c7a734449504d5451437a2b43304349514430516e6d514c2b4e6b4e374a7a0a655a666c5078644734687a374b652b3443595366744b416a48545a7539413d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a00"; - function setUp() public { - // uint256 fork = vm.createFork(rpcUrl); - // vm.selectFork(fork); - - // pinned September 23rd, 2023, 0221 UTC - // comment this line out if you are replacing sampleQuote with your own - // this line is needed to bypass expiry reverts for stale quotes - vm.warp(1_695_435_682); - - vm.deal(admin, 100 ether); - - vm.startPrank(admin); - p256Verifier = new P256Verifier(); - sigVerifyLib = new SigVerifyLib(address(p256Verifier)); - pemCertChainLib = new PEMCertChainLib(); - attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); - attestation.setMrEnclave(mrEnclave, true); - attestation.setMrSigner(mrSigner, true); - - string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); - string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); - - string memory fmspc = "00606a000000"; - (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = - parseTcbInfoJson(tcbInfoJson); - require(tcbParsedSuccess, "tcb parsed failed"); - attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); - - (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - require(qeIdParsedSuccess, "qeid parsed failed"); - attestation.configureQeIdentityJson(parsedEnclaveId); - - vm.stopPrank(); + // Call the AttestationTestBase init setup + super.intialSetup(); } function testAttestation() public { diff --git a/packages/protocol/test/automata-attestation/common/AttestationTestBase.t.sol b/packages/protocol/test/automata-attestation/common/AttestationTestBase.t.sol new file mode 100644 index 00000000000..4e7b4dd2878 --- /dev/null +++ b/packages/protocol/test/automata-attestation/common/AttestationTestBase.t.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.24; + +import "forge-std/Test.sol"; +import "forge-std/console.sol"; +import "forge-std/StdJson.sol"; +import { AutomataDcapV3Attestation } from + "../../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; +import { P256Verifier } from "../../../lib/p256-verifier/src/P256Verifier.sol"; +import { SigVerifyLib } from + "../../../contracts/thirdparty/automata-attestation/utils/SigVerifyLib.sol"; +import { PEMCertChainLib } from + "../../../contracts/thirdparty/automata-attestation/lib/PEMCertChainLib.sol"; +import { V3Struct } from + "../../../contracts/thirdparty/automata-attestation/lib/QuoteV3Auth/V3Struct.sol"; +import { BytesUtils } from "../../../contracts/thirdparty/automata-attestation/utils/BytesUtils.sol"; +import { Base64 } from "../../../lib/solady/src/utils/Base64.sol"; +import "../utils/DcapTestUtils.t.sol"; +import "../utils/V3JsonUtils.t.sol"; + +contract AttestationTestBase is Test, DcapTestUtils, V3JsonUtils { + using BytesUtils for bytes; + using stdJson for string; + + AutomataDcapV3Attestation attestation; + SigVerifyLib sigVerifyLib; + P256Verifier p256Verifier; + PEMCertChainLib pemCertChainLib; + // use a network that where the P256Verifier contract exists + // ref: https://github.com/daimo-eth/p256-verifier + //string internal rpcUrl = vm.envString("RPC_URL"); + string internal constant tcbInfoPath = "/test/automata-attestation/assets/0923/tcbInfo.json"; + string internal constant idPath = "/test/automata-attestation/assets/0923/identity.json"; + string internal constant v3QuotePath = "/test/automata-attestation/assets/0923/v3quote.json"; + address constant admin = address(1); + address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; + bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; + bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; + + bytes sampleQuote = + hex"030002000000000009000e00939a7233f79c4ca9940a0db3957f0607ccb12a326354d33986ff47365f17ad4c000000000c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000e70000000000000046049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a00000000000000000000000000000000000000000000000000000000000000000ef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca10000084af1f392be216944059f3fa05bf91e1b4e9b513c67493521eb4488af35f49c8f300d57955afc1df97d423c8718ed5b0af82f71047a229df221faa6817ad5daa44131b5c2ed877295959f7333543ba3f17994d767da194a27ba7a4e8a71940118a138dce8499572433c2cc4e4312f92e7144b26f84c59022bfc9aea59967f00d0c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf00000000000000000000000000000000000000000000000000000000000000008c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a654bcd78ffaa5cfc888fc90cbc24fb7f6e19bc8661671f1e3b2cc947db3b6340000000000000000000000000000000000000000000000000000000000000000839adce904d2aec1fc021ad0ec370c7176942d4b64939b95a2e1e1d3e09bf2e57093231f4308b64e8f53b81cd6ae36fc52f202e66ac77b93b13307ee577be36b2000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0500620e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494945386a4343424a696741774942416749554b6e314f2b2b58517264456161433535634a4c307470464867336b77436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a4d774f4449304d6a45304d444d775768634e4d7a41774f4449304d6a45304d444d770a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d34394177454841304941424e47520a727a716c416d4a66617756324b67656a39576e774a736666457868445631756847396e6d57377430505a646e6276732f6c677872584255625657436d5043456f0a4f49587768563673736d6e6b6b48462b576d536a67674d4f4d494944436a416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c33597a4c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f424259454641337234524b62476e54316e584c775a5a7272515559410a4a6b776c4d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f77594a4b6f5a496876684e415130420a424949434c444343416967774867594b4b6f5a496876684e415130424151515179753373424e6d7632566643337932772f445344627a434341575547436971470a534962345451454e41514977676746564d42414743797147534962345451454e415149424167454d4d42414743797147534962345451454e415149434167454d0a4d42414743797147534962345451454e41514944416745444d42414743797147534962345451454e41514945416745444d42454743797147534962345451454e0a41514946416749412f7a415242677371686b69472b4530424451454342674943415038774541594c4b6f5a496876684e4151304241676343415145774541594c0a4b6f5a496876684e4151304241676743415141774541594c4b6f5a496876684e4151304241676b43415141774541594c4b6f5a496876684e4151304241676f430a415141774541594c4b6f5a496876684e4151304241677343415141774541594c4b6f5a496876684e4151304241677743415141774541594c4b6f5a496876684e0a4151304241673043415141774541594c4b6f5a496876684e4151304241673443415141774541594c4b6f5a496876684e4151304241673843415141774541594c0a4b6f5a496876684e4151304241684143415141774541594c4b6f5a496876684e4151304241684543415130774877594c4b6f5a496876684e41513042416849450a4541774d4177502f2f7745414141414141414141414141774541594b4b6f5a496876684e4151304241775143414141774641594b4b6f5a496876684e415130420a4241514741474271414141414d41384743697147534962345451454e4151554b415145774867594b4b6f5a496876684e415130424267515136657645326f42790a6f684e362f30727741346d642b6a424542676f71686b69472b453042445145484d4459774541594c4b6f5a496876684e4151304242774542416638774541594c0a4b6f5a496876684e4151304242774942415141774541594c4b6f5a496876684e4151304242774d4241514177436759494b6f5a497a6a304541774944534141770a52514967522b344377346437476a73684848436c7a394c6269785a4a45632f31666c7a734449504d5451437a2b43304349514430516e6d514c2b4e6b4e374a7a0a655a666c5078644734687a374b652b3443595366744b416a48545a7539413d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a00"; + + function intialSetup() public { + // pinned September 23rd, 2023, 0221 UTC + // comment this line out if you are replacing sampleQuote with your own + // this line is needed to bypass expiry reverts for stale quotes + vm.warp(1_695_435_682); + + vm.deal(admin, 100 ether); + + vm.startPrank(admin); + p256Verifier = new P256Verifier(); + sigVerifyLib = new SigVerifyLib(address(p256Verifier)); + pemCertChainLib = new PEMCertChainLib(); + attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); + attestation.setMrEnclave(mrEnclave, true); + attestation.setMrSigner(mrSigner, true); + + string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); + string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); + + string memory fmspc = "00606a000000"; + (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = + parseTcbInfoJson(tcbInfoJson); + require(tcbParsedSuccess, "tcb parsed failed"); + attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); + + (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = + parseEnclaveIdentityJson(enclaveIdJson); + require(qeIdParsedSuccess, "qeid parsed failed"); + attestation.configureQeIdentityJson(parsedEnclaveId); + + vm.stopPrank(); + } +} diff --git a/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol b/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol index 35efb52bfea..ed32e29dcc5 100644 --- a/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol +++ b/packages/protocol/test/automata-attestation/utils/DcapTestUtils.t.sol @@ -27,11 +27,11 @@ contract DcapTestUtils { uint256 tcbInfoIndex = INDEX_ERROR; - for (uint256 x = 0; x < root.size(); x++) { - string memory decodedKey = JSONParserLib.decodeString(children[x].key()); + for (uint256 i; i < root.size(); ++i) { + string memory decodedKey = JSONParserLib.decodeString(children[i].key()); if (decodedKey.eq("tcbInfo")) { - tcbInfoObj = children[x].children(); - tcbInfoIndex = x; + tcbInfoObj = children[i].children(); + tcbInfoIndex = i; } } From 424203cd07e8e312b3aa47430b5c0b45270c02c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 1 Feb 2024 09:43:54 +0530 Subject: [PATCH 39/44] Brechts findings nr2 --- .../contracts/L1/verifiers/SgxVerifier.sol | 47 ++++++++------ packages/protocol/script/SetDcapParams.s.sol | 64 ++++--------------- packages/protocol/test/L1/SgxVerifier.t.sol | 10 +-- packages/protocol/test/L1/TaikoL1TestBase.sol | 2 +- .../AutomataDcapV3AttestationTest.t.sol | 6 +- ...onTestBase.t.sol => AttestationBase.t.sol} | 57 +++++++++++++---- 6 files changed, 96 insertions(+), 90 deletions(-) rename packages/protocol/test/automata-attestation/common/{AttestationTestBase.t.sol => AttestationBase.t.sol} (82%) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 174186b1134..0e1997752d0 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -34,14 +34,12 @@ contract SgxVerifier is EssentialContract, IVerifier { /// bootstrapping the network with trustworthy instances. struct Instance { address addr; - uint64 addedAt; // We can calculate if expired or not yet valid - bool checkValidityCoolTime; // Owner added sgx instances not needed to have a cooldown for - // validity + uint64 validFrom; } - uint256 public constant INSTANCE_EXPIRY = 180 days; - // A security feature, to enable device - uint256 public constant INSTANCE_VALIDITY_DELAY = 1 days; + uint64 public constant INSTANCE_EXPIRY = 180 days; + // A security feature, a delay until an instanace is enabled when using onchain RA verification + uint64 public constant INSTANCE_VALIDITY_DELAY = 1 days; /// @dev For gas savings, we shall assign each SGX instance with an id /// so that when we need to set a new pub key, just write storage once. @@ -62,6 +60,7 @@ contract SgxVerifier is EssentialContract, IVerifier { ); event InstanceDeleted(uint256 indexed id, address indexed instance); + error SGX_DELETE_NOT_AUTHORIZED(); error SGX_INVALID_ATTESTATION(); error SGX_INVALID_INSTANCE(); error SGX_INVALID_INSTANCES(); @@ -69,6 +68,13 @@ contract SgxVerifier is EssentialContract, IVerifier { error SGX_MISSING_ATTESTATION(); error SGX_RA_NOT_SUPPORTED(); + modifier onlyAuthorized() { + if (msg.sender != owner() && msg.sender != resolve("rollup_watchdog", true)) { + revert SGX_DELETE_NOT_AUTHORIZED(); + } + _; + } + /// @notice Initializes the contract with the provided address manager. /// @param _addressManager The address of the address manager contract. function init(address _addressManager) external initializer { @@ -84,19 +90,19 @@ contract SgxVerifier is EssentialContract, IVerifier { returns (uint256[] memory ids) { if (_instances.length == 0) revert SGX_INVALID_INSTANCES(); - ids = _addInstances(_instances, false); + ids = _addInstances(_instances, true); } /// @notice Deletes SGX instances from the registry. /// @param _ids The ids array of SGX instances. - function deleteInstances(uint256[] calldata _ids) external onlyOwner { + function deleteInstances(uint256[] calldata _ids) external onlyAuthorized { if (_ids.length == 0) revert SGX_INVALID_INSTANCES(); for (uint256 i; i < _ids.length; ++i) { if (instances[_ids[i]].addr == address(0)) revert SGX_INVALID_INSTANCE(); emit InstanceDeleted(_ids[i], instances[_ids[i]].addr); - delete instances[i]; + delete instances[_ids[i]]; } } @@ -120,7 +126,7 @@ contract SgxVerifier is EssentialContract, IVerifier { address[] memory _address = new address[](1); _address[0] = address(bytes20(attestation.localEnclaveReport.reportData)); - return _addInstances(_address, true)[0]; + return _addInstances(_address, false)[0]; } /// @inheritdoc IVerifier @@ -176,18 +182,24 @@ contract SgxVerifier is EssentialContract, IVerifier { function _addInstances( address[] memory _instances, - bool validityCooldownRequired + bool instantValid ) private returns (uint256[] memory ids) { ids = new uint256[](_instances.length); + uint64 validFrom = uint64(block.timestamp); + + if(!instantValid) { + validFrom += INSTANCE_VALIDITY_DELAY; + } + for (uint256 i; i < _instances.length; ++i) { if (_instances[i] == address(0)) revert SGX_INVALID_INSTANCE(); instances[nextInstanceId] = - Instance(_instances[i], uint64(block.timestamp), validityCooldownRequired); + Instance(_instances[i], validFrom); ids[i] = nextInstanceId; emit InstanceAdded(nextInstanceId, _instances[i], address(0), block.timestamp); @@ -197,19 +209,16 @@ contract SgxVerifier is EssentialContract, IVerifier { } function _replaceInstance(uint256 id, address oldInstance, address newInstance) private { - // Replacing an instance means, it went through a cooldwon (if added by on-chain RA) so no + // Replacing an instance means, it went through a cooldown (if added by on-chain RA) so no // need to have a cooldown - instances[id] = Instance(newInstance, uint64(block.timestamp), false); + instances[id] = Instance(newInstance, uint64(block.timestamp)); emit InstanceAdded(id, newInstance, oldInstance, block.timestamp); } function _isInstanceValid(uint256 id, address instance) private view returns (bool) { if (instance == address(0)) return false; if (instance != instances[id].addr) return false; - if ( - instances[id].checkValidityCoolTime == true - && instances[id].addedAt + INSTANCE_VALIDITY_DELAY < block.timestamp - ) return false; - return instances[id].addedAt + INSTANCE_EXPIRY > block.timestamp; + if (instances[id].validFrom > block.timestamp) return false; + return instances[id].validFrom + INSTANCE_EXPIRY > block.timestamp; } } diff --git a/packages/protocol/script/SetDcapParams.s.sol b/packages/protocol/script/SetDcapParams.s.sol index 76975a9fb6c..59100c2e1f6 100644 --- a/packages/protocol/script/SetDcapParams.s.sol +++ b/packages/protocol/script/SetDcapParams.s.sol @@ -17,73 +17,37 @@ pragma solidity 0.8.24; import "forge-std/Script.sol"; import "forge-std/console2.sol"; -import "../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; -import "../contracts/L1/verifiers/SgxVerifier.sol"; -import "../test/automata-attestation/utils/DcapTestUtils.t.sol"; -import "../test/automata-attestation/utils/V3JsonUtils.t.sol"; +import "../test/automata-attestation/common/AttestationBase.t.sol"; -contract SetDcapParams is Script, DcapTestUtils, V3JsonUtils { +contract SetDcapParams is Script, AttestationBase { uint256 public ownerPrivateKey = vm.envUint("PRIVATE_KEY"); // Owner of the attestation contract address public dcapAttestationAddress = vm.envAddress("ATTESTATION_ADDRESS"); address public sgxVerifier = vm.envAddress("SGX_VERIFIER_ADDRESS"); - string public tcbInfoPath = vm.envString("TCB_INFO_PATH"); - string public idPath = vm.envString("QEID_PATH"); - string public v3QuotePath = vm.envString("V3_QUOTE_PATH"); - bytes32 public mrEnclave = vm.envBytes32("MR_ENCLAVE"); - bytes32 public mrSigner = vm.envBytes32("MR_SIGNER"); function run() external { + tcbInfoPath = vm.envString("TCB_INFO_PATH"); + idPath = vm.envString("QEID_PATH"); + v3QuotePath = vm.envString("V3_QUOTE_PATH"); + mrEnclave = vm.envBytes32("MR_ENCLAVE"); + mrSigner = vm.envBytes32("MR_SIGNER"); + require(ownerPrivateKey != 0, "PRIVATE_KEY not set"); require(dcapAttestationAddress != address(0), "ATTESTATION_ADDRESS not set"); vm.startBroadcast(ownerPrivateKey); - // all in one, means sets MrEnclave, MrSigner, configures identitiy json and tcb info, - // register sgx instance - setMrEnclave(); - setMrSigner(); - configureQeIdentityJson(); - configureTcbInfoJson(); - registerSgxInstanceWithQuote(); - - vm.stopBroadcast(); - } - - function setMrEnclave() internal { - AutomataDcapV3Attestation(dcapAttestationAddress).setMrEnclave(mrEnclave, true); - } + setMrEnclave(dcapAttestationAddress, mrEnclave); + setMrSigner(dcapAttestationAddress, mrSigner); - function setMrSigner() internal { - AutomataDcapV3Attestation(dcapAttestationAddress).setMrSigner(mrSigner, true); - } - - function configureQeIdentityJson() internal { string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); - (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - AutomataDcapV3Attestation(dcapAttestationAddress).configureQeIdentityJson(parsedEnclaveId); - console.log("qeIdParsedSuccess: %s", qeIdParsedSuccess); - } + configureQeIdentityJson(dcapAttestationAddress, enclaveIdJson); - function configureTcbInfoJson() internal { string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); - (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = - parseTcbInfoJson(tcbInfoJson); - string memory fmspc = parsedTcbInfo.fmspc; - AutomataDcapV3Attestation(dcapAttestationAddress).configureTcbInfoJson(fmspc, parsedTcbInfo); - console.log("tcbParsedSuccess: %s", tcbParsedSuccess); - } + configureTcbInfoJson(dcapAttestationAddress, tcbInfoJson); - function registerSgxInstanceWithQuote() internal { string memory v3QuoteJsonStr = vm.readFile(string.concat(vm.projectRoot(), v3QuotePath)); - console.log("[LOG] v3QuoteJsonStr: %s", v3QuoteJsonStr); - bytes memory v3QuotePacked = vm.parseJson(v3QuoteJsonStr); - console.logBytes(v3QuotePacked); + registerSgxInstanceWithQuote(sgxVerifier, v3QuoteJsonStr); - (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); - console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); - console.logBytes(v3quote.localEnclaveReport.reportData); - uint256 ret = SgxVerifier(sgxVerifier).registerInstance(v3quote); - console.log("ret: %s", ret); + vm.stopBroadcast(); } } diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index b2e86cd7862..16623f80235 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.24; import "./TaikoL1TestBase.sol"; -import "../automata-attestation/common/AttestationTestBase.t.sol"; +import "../automata-attestation/common/AttestationBase.t.sol"; -contract TestSgxVerifier is TaikoL1TestBase, AttestationTestBase { +contract TestSgxVerifier is TaikoL1TestBase, AttestationBase { address internal SGX_Y = vm.addr(0x9b1bb8cb3bdb539d0d1f03951d27f167f2d5443e7ef0d7ce745cd4ec619d3dd7); address internal SGX_Z = randAddress(); @@ -18,7 +18,7 @@ contract TestSgxVerifier is TaikoL1TestBase, AttestationTestBase { // Call the TaikoL1TestBase setUp() super.setUp(); - // Call the AttestationTestBase init setup + // Call the AttestationBase init setup super.intialSetup(); registerAddress("automata_dcap_attestation", address(attestation)); @@ -48,12 +48,12 @@ contract TestSgxVerifier is TaikoL1TestBase, AttestationTestBase { _ids[0] = 0; address instance; - (instance,,) = sv.instances(0); + (instance,) = sv.instances(0); assertEq(instance, SGX_X_0); sv.deleteInstances(_ids); - (instance,,) = sv.instances(0); + (instance,) = sv.instances(0); assertEq(instance, address(0)); } diff --git a/packages/protocol/test/L1/TaikoL1TestBase.sol b/packages/protocol/test/L1/TaikoL1TestBase.sol index 2ff47a856ac..7dd97a7b81c 100644 --- a/packages/protocol/test/L1/TaikoL1TestBase.sol +++ b/packages/protocol/test/L1/TaikoL1TestBase.sol @@ -276,7 +276,7 @@ abstract contract TaikoL1TestBase is TaikoTest { // Keep changing the pub key associated with an instance to avoid // attacks, // obviously just a mock due to 2 addresses changing all the time. - (newInstance,,) = sv.instances(0); + (newInstance,) = sv.instances(0); if (newInstance == SGX_X_0) { newInstance = SGX_X_1; } else { diff --git a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol index 5254ae67f33..9150e0cdcbe 100644 --- a/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol +++ b/packages/protocol/test/automata-attestation/AutomataDcapV3AttestationTest.t.sol @@ -4,14 +4,14 @@ pragma solidity 0.8.24; import "forge-std/Test.sol"; import "forge-std/console.sol"; import "forge-std/StdJson.sol"; -import "./common/AttestationTestBase.t.sol"; +import "./common/AttestationBase.t.sol"; -contract AutomataDcapV3AttestationTest is Test, AttestationTestBase { +contract AutomataDcapV3AttestationTest is Test, AttestationBase { using BytesUtils for bytes; using stdJson for string; function setUp() public { - // Call the AttestationTestBase init setup + // Call the AttestationBase init setup super.intialSetup(); } diff --git a/packages/protocol/test/automata-attestation/common/AttestationTestBase.t.sol b/packages/protocol/test/automata-attestation/common/AttestationBase.t.sol similarity index 82% rename from packages/protocol/test/automata-attestation/common/AttestationTestBase.t.sol rename to packages/protocol/test/automata-attestation/common/AttestationBase.t.sol index 4e7b4dd2878..e30f59e789e 100644 --- a/packages/protocol/test/automata-attestation/common/AttestationTestBase.t.sol +++ b/packages/protocol/test/automata-attestation/common/AttestationBase.t.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.24; import "forge-std/Test.sol"; import "forge-std/console.sol"; import "forge-std/StdJson.sol"; +import "../../../contracts/L1/verifiers/SgxVerifier.sol"; import { AutomataDcapV3Attestation } from "../../../contracts/thirdparty/automata-attestation/AutomataDcapV3Attestation.sol"; import { P256Verifier } from "../../../lib/p256-verifier/src/P256Verifier.sol"; @@ -18,7 +19,7 @@ import { Base64 } from "../../../lib/solady/src/utils/Base64.sol"; import "../utils/DcapTestUtils.t.sol"; import "../utils/V3JsonUtils.t.sol"; -contract AttestationTestBase is Test, DcapTestUtils, V3JsonUtils { +contract AttestationBase is Test, DcapTestUtils, V3JsonUtils { using BytesUtils for bytes; using stdJson for string; @@ -29,13 +30,13 @@ contract AttestationTestBase is Test, DcapTestUtils, V3JsonUtils { // use a network that where the P256Verifier contract exists // ref: https://github.com/daimo-eth/p256-verifier //string internal rpcUrl = vm.envString("RPC_URL"); - string internal constant tcbInfoPath = "/test/automata-attestation/assets/0923/tcbInfo.json"; - string internal constant idPath = "/test/automata-attestation/assets/0923/identity.json"; - string internal constant v3QuotePath = "/test/automata-attestation/assets/0923/v3quote.json"; + string internal tcbInfoPath = "/test/automata-attestation/assets/0923/tcbInfo.json"; + string internal idPath = "/test/automata-attestation/assets/0923/identity.json"; + string internal v3QuotePath = "/test/automata-attestation/assets/0923/v3quote.json"; address constant admin = address(1); address constant user = 0x0926b716f6aEF52F9F3C3474A2846e1Bf1ACedf6; - bytes32 constant mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; - bytes32 constant mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; + bytes32 mrEnclave = 0x46049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a0; + bytes32 mrSigner = 0xef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd9; bytes sampleQuote = hex"030002000000000009000e00939a7233f79c4ca9940a0db3957f0607ccb12a326354d33986ff47365f17ad4c000000000c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000e70000000000000046049af725ec3986eeb788693df7bc5f14d3f2705106a19cd09b9d89237db1a00000000000000000000000000000000000000000000000000000000000000000ef69011f29043f084e99ce420bfebdfa410aee1e132014e7ceff29efa9659bd90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ca10000084af1f392be216944059f3fa05bf91e1b4e9b513c67493521eb4488af35f49c8f300d57955afc1df97d423c8718ed5b0af82f71047a229df221faa6817ad5daa44131b5c2ed877295959f7333543ba3f17994d767da194a27ba7a4e8a71940118a138dce8499572433c2cc4e4312f92e7144b26f84c59022bfc9aea59967f00d0c0c100fffff0100000000000000000000000000000000000000000000000000000000000000000000000000000000001500000000000000e700000000000000192aa50ce1c0cef03ccf89e7b5b16b0d7978f5c2b1edcf774d87702e8154d8bf00000000000000000000000000000000000000000000000000000000000000008c4f5775d796503e96137f77c68a829a0056ac8ded70140b081b094490c57bff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a654bcd78ffaa5cfc888fc90cbc24fb7f6e19bc8661671f1e3b2cc947db3b6340000000000000000000000000000000000000000000000000000000000000000839adce904d2aec1fc021ad0ec370c7176942d4b64939b95a2e1e1d3e09bf2e57093231f4308b64e8f53b81cd6ae36fc52f202e66ac77b93b13307ee577be36b2000000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f0500620e00002d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d494945386a4343424a696741774942416749554b6e314f2b2b58517264456161433535634a4c307470464867336b77436759494b6f5a497a6a3045417749770a634445694d434147413155454177775a535735305a577767553064594946424453794251624746305a6d397962534244515445614d42674741315545436777520a535735305a577767513239796347397959585270623234784644415342674e564241634d43314e68626e526849454e7359584a684d51737743515944565151490a44414a445154454c4d416b474131554542684d4356564d774868634e4d6a4d774f4449304d6a45304d444d775768634e4d7a41774f4449304d6a45304d444d770a576a42774d534977494159445651514444426c4a626e526c624342545231676755454e4c49454e6c636e52705a6d6c6a5958526c4d526f77474159445651514b0a4442464a626e526c6243424462334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e560a4241674d416b4e424d517377435159445651514745774a56557a425a4d424d4742797147534d34394167454743437147534d34394177454841304941424e47520a727a716c416d4a66617756324b67656a39576e774a736666457868445631756847396e6d57377430505a646e6276732f6c677872584255625657436d5043456f0a4f49587768563673736d6e6b6b48462b576d536a67674d4f4d494944436a416642674e5648534d4547444157674253566231334e765276683655424a796454300a4d383442567776655644427242674e56485238455a4442694d47436758714263686c706f64485277637a6f764c32467761533530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c334e6e6543396a5a584a3061575a7059324630615739754c33597a4c33426a61324e796244396a595431770a624746305a6d397962535a6c626d4e765a476c755a7a316b5a584977485159445652304f424259454641337234524b62476e54316e584c775a5a7272515559410a4a6b776c4d41344741315564447745422f775145417749477744414d42674e5648524d4241663845416a41414d4949434f77594a4b6f5a496876684e415130420a424949434c444343416967774867594b4b6f5a496876684e415130424151515179753373424e6d7632566643337932772f445344627a434341575547436971470a534962345451454e41514977676746564d42414743797147534962345451454e415149424167454d4d42414743797147534962345451454e415149434167454d0a4d42414743797147534962345451454e41514944416745444d42414743797147534962345451454e41514945416745444d42454743797147534962345451454e0a41514946416749412f7a415242677371686b69472b4530424451454342674943415038774541594c4b6f5a496876684e4151304241676343415145774541594c0a4b6f5a496876684e4151304241676743415141774541594c4b6f5a496876684e4151304241676b43415141774541594c4b6f5a496876684e4151304241676f430a415141774541594c4b6f5a496876684e4151304241677343415141774541594c4b6f5a496876684e4151304241677743415141774541594c4b6f5a496876684e0a4151304241673043415141774541594c4b6f5a496876684e4151304241673443415141774541594c4b6f5a496876684e4151304241673843415141774541594c0a4b6f5a496876684e4151304241684143415141774541594c4b6f5a496876684e4151304241684543415130774877594c4b6f5a496876684e41513042416849450a4541774d4177502f2f7745414141414141414141414141774541594b4b6f5a496876684e4151304241775143414141774641594b4b6f5a496876684e415130420a4241514741474271414141414d41384743697147534962345451454e4151554b415145774867594b4b6f5a496876684e415130424267515136657645326f42790a6f684e362f30727741346d642b6a424542676f71686b69472b453042445145484d4459774541594c4b6f5a496876684e4151304242774542416638774541594c0a4b6f5a496876684e4151304242774942415141774541594c4b6f5a496876684e4151304242774d4241514177436759494b6f5a497a6a304541774944534141770a52514967522b344377346437476a73684848436c7a394c6269785a4a45632f31666c7a734449504d5451437a2b43304349514430516e6d514c2b4e6b4e374a7a0a655a666c5078644734687a374b652b3443595366744b416a48545a7539413d3d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436c6a4343416a32674177494241674956414a567658633239472b487051456e4a3150517a7a674658433935554d416f4743437147534d343942414d430a4d476778476a415942674e5642414d4d45556c756447567349464e48574342536232393049454e424d526f77474159445651514b4442464a626e526c624342440a62334a7762334a6864476c76626a45554d424947413155454277774c553246756447456751327868636d4578437a414a42674e564241674d416b4e424d5173770a435159445651514745774a56557a4165467730784f4441314d6a45784d4455774d5442614677307a4d7a41314d6a45784d4455774d5442614d484178496a41670a42674e5642414d4d47556c756447567349464e4857434251513073675547786864475a76636d306751304578476a415942674e5642416f4d45556c75644756730a49454e76636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b474131554543417743513045780a437a414a42674e5642415954416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a304441516344516741454e53422f377432316c58534f0a3243757a7078773734654a423732457944476757357258437478327456544c7136684b6b367a2b5569525a436e71523770734f766771466553786c6d546c4a6c0a65546d693257597a33714f42757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f536347724442530a42674e5648523845537a424a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b633256790a646d6c6a5a584d75615735305a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e5648513445466751556c5739640a7a62306234656c4153636e553944504f4156634c336c517744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159420a4166384341514177436759494b6f5a497a6a30454177494452774177524149675873566b6930772b6936565947573355462f32327561586530594a446a3155650a6e412b546a44316169356343494359623153416d4435786b66545670766f34556f79695359787244574c6d5552344349394e4b7966504e2b0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a2d2d2d2d2d424547494e2043455254494649434154452d2d2d2d2d0a4d4949436a7a4343416a53674177494241674955496d554d316c71644e496e7a6737535655723951477a6b6e42717777436759494b6f5a497a6a3045417749770a614445614d4267474131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e760a636e4276636d4630615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a0a42674e5642415954416c56544d423458445445344d4455794d5445774e4455784d466f58445451354d54497a4d54497a4e546b314f566f77614445614d4267470a4131554541777752535735305a5777675530645949464a766233516751304578476a415942674e5642416f4d45556c756447567349454e76636e4276636d46300a615739754d5251774567594456515148444174545957353059534244624746795954454c4d416b47413155454341774351304578437a414a42674e56424159540a416c56544d466b77457759484b6f5a497a6a3043415159494b6f5a497a6a3044415163445167414543366e45774d4449595a4f6a2f69505773437a61454b69370a314f694f534c52466857476a626e42564a66566e6b59347533496a6b4459594c304d784f346d717379596a6c42616c54565978465032734a424b357a6c4b4f420a757a43427544416642674e5648534d4547444157674251695a517a575770303069664f44744a5653763141624f5363477244425342674e5648523845537a424a0a4d45656752614244686b466f64485277637a6f764c324e6c636e52705a6d6c6a5958526c63793530636e567a6447566b63325679646d6c6a5a584d75615735300a5a577775593239744c306c756447567355306459556d397664454e424c6d526c636a416442674e564851344546675155496d554d316c71644e496e7a673753560a55723951477a6b6e4271777744675944565230504151482f42415144416745474d42494741315564457745422f7751494d4159424166384341514577436759490a4b6f5a497a6a3045417749445351417752674968414f572f35516b522b533943695344634e6f6f774c7550524c735747662f59693747535839344267775477670a41694541344a306c72486f4d732b586f356f2f7358364f39515778485241765a55474f6452513763767152586171493d0a2d2d2d2d2d454e442043455254494649434154452d2d2d2d2d0a00"; @@ -53,8 +54,9 @@ contract AttestationTestBase is Test, DcapTestUtils, V3JsonUtils { sigVerifyLib = new SigVerifyLib(address(p256Verifier)); pemCertChainLib = new PEMCertChainLib(); attestation = new AutomataDcapV3Attestation(address(sigVerifyLib), address(pemCertChainLib)); - attestation.setMrEnclave(mrEnclave, true); - attestation.setMrSigner(mrSigner, true); + + setMrEnclave(address(attestation), mrEnclave); + setMrSigner(address(attestation), mrSigner); string memory tcbInfoJson = vm.readFile(string.concat(vm.projectRoot(), tcbInfoPath)); string memory enclaveIdJson = vm.readFile(string.concat(vm.projectRoot(), idPath)); @@ -65,11 +67,42 @@ contract AttestationTestBase is Test, DcapTestUtils, V3JsonUtils { require(tcbParsedSuccess, "tcb parsed failed"); attestation.configureTcbInfoJson(fmspc, parsedTcbInfo); + configureQeIdentityJson(address(attestation), enclaveIdJson); + vm.stopPrank(); + } + + function setMrEnclave(address _attestationAddress, bytes32 _mrEnclave) internal { + AutomataDcapV3Attestation(_attestationAddress).setMrEnclave(_mrEnclave, true); + } + + function setMrSigner(address _attestationAddress, bytes32 _mrSigner) internal { + AutomataDcapV3Attestation(_attestationAddress).setMrSigner(_mrSigner, true); + } + + function configureQeIdentityJson(address _attestationAddress, string memory _enclaveIdJson ) internal { (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = - parseEnclaveIdentityJson(enclaveIdJson); - require(qeIdParsedSuccess, "qeid parsed failed"); - attestation.configureQeIdentityJson(parsedEnclaveId); + parseEnclaveIdentityJson(_enclaveIdJson); + AutomataDcapV3Attestation(_attestationAddress).configureQeIdentityJson(parsedEnclaveId); + console.log("qeIdParsedSuccess: %s", qeIdParsedSuccess); + } - vm.stopPrank(); + function configureTcbInfoJson(address _attestationAddress, string memory _tcbInfoJson) internal { + (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = + parseTcbInfoJson(_tcbInfoJson); + string memory fmspc = parsedTcbInfo.fmspc; + AutomataDcapV3Attestation(_attestationAddress).configureTcbInfoJson(fmspc, parsedTcbInfo); + console.log("tcbParsedSuccess: %s", tcbParsedSuccess); + } + + function registerSgxInstanceWithQuote(address _sgxVerifier, string memory _v3QuoteJsonStr) internal { + console.log("[LOG] v3QuoteJsonStr: %s", _v3QuoteJsonStr); + bytes memory v3QuotePacked = vm.parseJson(_v3QuoteJsonStr); + console.logBytes(v3QuotePacked); + + (, V3Struct.ParsedV3QuoteStruct memory v3quote) = parseV3QuoteJson(v3QuotePacked); + console.log("v3quote.header.userData = %s", address(v3quote.header.userData)); + console.logBytes(v3quote.localEnclaveReport.reportData); + uint256 ret = SgxVerifier(_sgxVerifier).registerInstance(v3quote); + console.log("ret: %s", ret); } } From 43a6406592108aa019083f62c109b68ad11f5d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 1 Feb 2024 11:40:10 +0530 Subject: [PATCH 40/44] onlyFromOwnerOrNamed --- packages/protocol/contracts/L1/verifiers/SgxVerifier.sol | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 0e1997752d0..a96ec0a14a3 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -68,13 +68,6 @@ contract SgxVerifier is EssentialContract, IVerifier { error SGX_MISSING_ATTESTATION(); error SGX_RA_NOT_SUPPORTED(); - modifier onlyAuthorized() { - if (msg.sender != owner() && msg.sender != resolve("rollup_watchdog", true)) { - revert SGX_DELETE_NOT_AUTHORIZED(); - } - _; - } - /// @notice Initializes the contract with the provided address manager. /// @param _addressManager The address of the address manager contract. function init(address _addressManager) external initializer { @@ -86,7 +79,7 @@ contract SgxVerifier is EssentialContract, IVerifier { /// @return ids The respective instanceId array per addresses. function addInstances(address[] calldata _instances) external - onlyOwner + onlyFromOwnerOrNamed("rollup_watchdog") returns (uint256[] memory ids) { if (_instances.length == 0) revert SGX_INVALID_INSTANCES(); From 63be18200bd2906ca2949c42a58b0723fe14073e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 1 Feb 2024 11:44:47 +0530 Subject: [PATCH 41/44] fix rollup_watchdog and forge fmt --- .../contracts/L1/verifiers/SgxVerifier.sol | 12 ++++++----- packages/protocol/test/L1/SgxVerifier.t.sol | 4 ++-- .../common/AttestationBase.t.sol | 21 ++++++++++++++++--- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index a96ec0a14a3..c1dcefc1973 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -79,7 +79,7 @@ contract SgxVerifier is EssentialContract, IVerifier { /// @return ids The respective instanceId array per addresses. function addInstances(address[] calldata _instances) external - onlyFromOwnerOrNamed("rollup_watchdog") + onlyOwner returns (uint256[] memory ids) { if (_instances.length == 0) revert SGX_INVALID_INSTANCES(); @@ -88,7 +88,10 @@ contract SgxVerifier is EssentialContract, IVerifier { /// @notice Deletes SGX instances from the registry. /// @param _ids The ids array of SGX instances. - function deleteInstances(uint256[] calldata _ids) external onlyAuthorized { + function deleteInstances(uint256[] calldata _ids) + external + onlyFromOwnerOrNamed("rollup_watchdog") + { if (_ids.length == 0) revert SGX_INVALID_INSTANCES(); for (uint256 i; i < _ids.length; ++i) { if (instances[_ids[i]].addr == address(0)) revert SGX_INVALID_INSTANCE(); @@ -184,15 +187,14 @@ contract SgxVerifier is EssentialContract, IVerifier { uint64 validFrom = uint64(block.timestamp); - if(!instantValid) { + if (!instantValid) { validFrom += INSTANCE_VALIDITY_DELAY; } for (uint256 i; i < _instances.length; ++i) { if (_instances[i] == address(0)) revert SGX_INVALID_INSTANCE(); - instances[nextInstanceId] = - Instance(_instances[i], validFrom); + instances[nextInstanceId] = Instance(_instances[i], validFrom); ids[i] = nextInstanceId; emit InstanceAdded(nextInstanceId, _instances[i], address(0), block.timestamp); diff --git a/packages/protocol/test/L1/SgxVerifier.t.sol b/packages/protocol/test/L1/SgxVerifier.t.sol index 16623f80235..e84192c20fa 100644 --- a/packages/protocol/test/L1/SgxVerifier.t.sol +++ b/packages/protocol/test/L1/SgxVerifier.t.sol @@ -44,9 +44,9 @@ contract TestSgxVerifier is TaikoL1TestBase, AttestationBase { } function test_deleteInstancesByOwner() external { - uint256[] memory _ids = new uint[](1); + uint256[] memory _ids = new uint256[](1); _ids[0] = 0; - + address instance; (instance,) = sv.instances(0); assertEq(instance, SGX_X_0); diff --git a/packages/protocol/test/automata-attestation/common/AttestationBase.t.sol b/packages/protocol/test/automata-attestation/common/AttestationBase.t.sol index e30f59e789e..0fae1abbd8f 100644 --- a/packages/protocol/test/automata-attestation/common/AttestationBase.t.sol +++ b/packages/protocol/test/automata-attestation/common/AttestationBase.t.sol @@ -79,14 +79,24 @@ contract AttestationBase is Test, DcapTestUtils, V3JsonUtils { AutomataDcapV3Attestation(_attestationAddress).setMrSigner(_mrSigner, true); } - function configureQeIdentityJson(address _attestationAddress, string memory _enclaveIdJson ) internal { + function configureQeIdentityJson( + address _attestationAddress, + string memory _enclaveIdJson + ) + internal + { (bool qeIdParsedSuccess, EnclaveIdStruct.EnclaveId memory parsedEnclaveId) = parseEnclaveIdentityJson(_enclaveIdJson); AutomataDcapV3Attestation(_attestationAddress).configureQeIdentityJson(parsedEnclaveId); console.log("qeIdParsedSuccess: %s", qeIdParsedSuccess); } - function configureTcbInfoJson(address _attestationAddress, string memory _tcbInfoJson) internal { + function configureTcbInfoJson( + address _attestationAddress, + string memory _tcbInfoJson + ) + internal + { (bool tcbParsedSuccess, TCBInfoStruct.TCBInfo memory parsedTcbInfo) = parseTcbInfoJson(_tcbInfoJson); string memory fmspc = parsedTcbInfo.fmspc; @@ -94,7 +104,12 @@ contract AttestationBase is Test, DcapTestUtils, V3JsonUtils { console.log("tcbParsedSuccess: %s", tcbParsedSuccess); } - function registerSgxInstanceWithQuote(address _sgxVerifier, string memory _v3QuoteJsonStr) internal { + function registerSgxInstanceWithQuote( + address _sgxVerifier, + string memory _v3QuoteJsonStr + ) + internal + { console.log("[LOG] v3QuoteJsonStr: %s", _v3QuoteJsonStr); bytes memory v3QuotePacked = vm.parseJson(_v3QuoteJsonStr); console.logBytes(v3QuotePacked); From 4c4eb3a18c25d833127a6379a113f6d7286e0b2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 1 Feb 2024 13:40:30 +0530 Subject: [PATCH 42/44] rename --- .../protocol/contracts/L1/verifiers/SgxVerifier.sol | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index c1dcefc1973..9aebab93b9d 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -34,7 +34,7 @@ contract SgxVerifier is EssentialContract, IVerifier { /// bootstrapping the network with trustworthy instances. struct Instance { address addr; - uint64 validFrom; + uint64 validSince; } uint64 public constant INSTANCE_EXPIRY = 180 days; @@ -185,16 +185,16 @@ contract SgxVerifier is EssentialContract, IVerifier { { ids = new uint256[](_instances.length); - uint64 validFrom = uint64(block.timestamp); + uint64 validSince = uint64(block.timestamp); if (!instantValid) { - validFrom += INSTANCE_VALIDITY_DELAY; + validSince += INSTANCE_VALIDITY_DELAY; } for (uint256 i; i < _instances.length; ++i) { if (_instances[i] == address(0)) revert SGX_INVALID_INSTANCE(); - instances[nextInstanceId] = Instance(_instances[i], validFrom); + instances[nextInstanceId] = Instance(_instances[i], validSince); ids[i] = nextInstanceId; emit InstanceAdded(nextInstanceId, _instances[i], address(0), block.timestamp); @@ -213,7 +213,7 @@ contract SgxVerifier is EssentialContract, IVerifier { function _isInstanceValid(uint256 id, address instance) private view returns (bool) { if (instance == address(0)) return false; if (instance != instances[id].addr) return false; - if (instances[id].validFrom > block.timestamp) return false; - return instances[id].validFrom + INSTANCE_EXPIRY > block.timestamp; + if (instances[id].validSince > block.timestamp) return false; + return instances[id].validSince + INSTANCE_EXPIRY > block.timestamp; } } From 1383ff5fee0d95489631d4e0acc3b78f988bd570 Mon Sep 17 00:00:00 2001 From: D <51912515+adaki2004@users.noreply.github.com> Date: Thu, 1 Feb 2024 18:26:18 +0530 Subject: [PATCH 43/44] Update packages/protocol/contracts/L1/verifiers/SgxVerifier.sol Co-authored-by: Brecht Devos --- packages/protocol/contracts/L1/verifiers/SgxVerifier.sol | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 9aebab93b9d..1e706fd5071 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -213,7 +213,6 @@ contract SgxVerifier is EssentialContract, IVerifier { function _isInstanceValid(uint256 id, address instance) private view returns (bool) { if (instance == address(0)) return false; if (instance != instances[id].addr) return false; - if (instances[id].validSince > block.timestamp) return false; - return instances[id].validSince + INSTANCE_EXPIRY > block.timestamp; + return instances[id].validSince <= block.timestamp && block.timestamp <= instances[id].validSince + INSTANCE_EXPIRY; } } From 4c96e7ef3d1d527b0ff1518b9de3cf2c9de3e33a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Keszey=20D=C3=A1niel?= Date: Thu, 1 Feb 2024 18:30:33 +0530 Subject: [PATCH 44/44] rename event var --- packages/protocol/contracts/L1/verifiers/SgxVerifier.sol | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol index 1e706fd5071..ab44c3638c4 100644 --- a/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol +++ b/packages/protocol/contracts/L1/verifiers/SgxVerifier.sol @@ -56,7 +56,7 @@ contract SgxVerifier is EssentialContract, IVerifier { uint256[48] private __gap; event InstanceAdded( - uint256 indexed id, address indexed instance, address replaced, uint256 timstamp + uint256 indexed id, address indexed instance, address replaced, uint256 validSince ); event InstanceDeleted(uint256 indexed id, address indexed instance); @@ -197,7 +197,7 @@ contract SgxVerifier is EssentialContract, IVerifier { instances[nextInstanceId] = Instance(_instances[i], validSince); ids[i] = nextInstanceId; - emit InstanceAdded(nextInstanceId, _instances[i], address(0), block.timestamp); + emit InstanceAdded(nextInstanceId, _instances[i], address(0), validSince); nextInstanceId++; }