Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TOB] DEV-3793: Content Hash Getters Added to PCCSRouter #25

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
[submodule "lib/automata-on-chain-pccs"]
path = lib/automata-on-chain-pccs
url = https://github.com/automata-network/automata-on-chain-pccs
branch = main
branch = DEV-3793
4 changes: 4 additions & 0 deletions contracts/AttestationEntrypointBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,11 @@ abstract contract AttestationEntrypointBase is Ownable {
* @notice verifies an attestation using SNARK proofs
*
* @param output - The output of the Guest program, this includes:
* - uint16 VerifiedOutput bytes length
* - VerifiedOutput struct
* - uint64 timestamp (in seconds)
* - FMSPC TCB Info content hash
* - QEIdentity content hash
* - RootCA hash
* - TCB Signing CA hash
* - Root CRL hash
Expand Down
22 changes: 22 additions & 0 deletions contracts/PCCSRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,17 @@ contract PCCSRouter is IPCCSRouter, Ownable {
}
}

function getQeIdentityContentHash(EnclaveId id, uint256 quoteVersion)
external
view
override
returns (bytes32 contentHash)
{
EnclaveIdentityDao enclaveIdDao = EnclaveIdentityDao(qeIdDaoAddr);
bytes32 key = enclaveIdDao.ENCLAVE_ID_KEY(uint256(id), quoteVersion);
contentHash = enclaveIdDao.getIdentityContentHash(key);
}

function getFmspcTcbV2(bytes6 fmspc)
external
view
Expand Down Expand Up @@ -182,6 +193,17 @@ contract PCCSRouter is IPCCSRouter, Ownable {
}
}

function getFmspcTcbContentHash(TcbId id, bytes6 fmspc, uint32 version)
external
view
override
returns (bytes32)
{
FmspcTcbDao tcbDao = FmspcTcbDao(fmspcTcbDaoAddr);
bytes32 key = tcbDao.FMSPC_TCB_KEY(uint8(id), fmspc, version);
return tcbDao.getTcbInfoContentHash(key);
}

function getPckCert(
string calldata qeid,
string calldata platformCpuSvn,
Expand Down
41 changes: 34 additions & 7 deletions contracts/bases/QuoteVerifierBase.sol
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {TCBStatus} from "@automata-network/on-chain-pccs/helpers/FmspcTcbHelper.sol";
import {TCBStatus, TcbId} from "@automata-network/on-chain-pccs/helpers/FmspcTcbHelper.sol";
import {EnclaveId} from "@automata-network/on-chain-pccs/helpers/EnclaveIdentityHelper.sol";

import {IQuoteVerifier, IPCCSRouter} from "../interfaces/IQuoteVerifier.sol";
import {BytesUtils} from "../utils/BytesUtils.sol";
Expand Down Expand Up @@ -152,19 +153,45 @@ abstract contract QuoteVerifierBase is IQuoteVerifier, EnclaveIdBase, X509ChainB
}

function checkCollateralHashes(uint256 offset, bytes calldata journal) internal view returns (bool) {
bytes32 rootCaHash = bytes32(journal[offset:offset + 32]);
bytes32 tcbSigningHash = bytes32(journal[offset + 32:offset + 64]);
bytes32 rootCaCrlHash = bytes32(journal[offset + 64:offset + 96]);
bytes32 pckCrlHash = bytes32(journal[offset + 96:offset + 128]);
uint64 timestamp = uint64(bytes8(journal[offset:offset + 8]));
bytes32 tcbInfoContentHash = bytes32(journal[offset + 8:offset + 40]);
bytes32 identityContentHash = bytes32(journal[offset + 40:offset + 72]);
bytes32 rootCaHash = bytes32(journal[offset + 72:offset + 104]);
bytes32 tcbSigningHash = bytes32(journal[offset + 104:offset + 136]);
bytes32 rootCaCrlHash = bytes32(journal[offset + 136:offset + 168]);
bytes32 pckCrlHash = bytes32(journal[offset + 168:offset + 200]);

bytes4 tee = bytes4(journal[4:8]);
bytes6 fmspc = bytes6(journal[9:15]);
bytes32 expectedTcbInfoContentHash =
pccsRouter.getFmspcTcbContentHash(
tee == SGX_TEE ? TcbId.SGX : TcbId.TDX,
fmspc,
quoteVersion < 4 ? 2 : 3
);
if (tcbInfoContentHash != expectedTcbInfoContentHash) {
return false;
}

(bool tcbSigningFound, bytes32 expectedTcbSigningHash) = pccsRouter.getCertHash(CA.SIGNING);
if (!tcbSigningFound || tcbSigningHash != expectedTcbSigningHash) {
bytes32 expectedIdentityContentHash =
pccsRouter.getQeIdentityContentHash(
tee == SGX_TEE ? EnclaveId.QE : EnclaveId.TD_QE,
quoteVersion
);
if (identityContentHash != expectedIdentityContentHash) {
return false;
}

(bool rootCaFound, bytes32 expectedRootCaHash) = pccsRouter.getCertHash(CA.ROOT);
if (!rootCaFound || rootCaHash != expectedRootCaHash) {
return false;
}

(bool tcbSigningFound, bytes32 expectedTcbSigningHash) = pccsRouter.getCertHash(CA.SIGNING);
if (!tcbSigningFound || tcbSigningHash != expectedTcbSigningHash) {
return false;
}

(bool rootCrlFound, bytes32 expectedRootCrlHash) = pccsRouter.getCrlHash(CA.ROOT);
if (!rootCrlFound || rootCaCrlHash != expectedRootCrlHash) {
return false;
Expand Down
4 changes: 4 additions & 0 deletions contracts/interfaces/IPCCSRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,17 @@ interface IPCCSRouter {

function getQeIdentity(EnclaveId id, uint256 quoteVersion) external view returns (bool, IdentityObj memory);

function getQeIdentityContentHash(EnclaveId id, uint256 version) external view returns (bytes32);

function getFmspcTcbV2(bytes6 fmspc) external view returns (bool, TCBLevelsObj[] memory);

function getFmspcTcbV3(TcbId id, bytes6 fmspc)
external
view
returns (bool, TCBLevelsObj[] memory, TDXModule memory, TDXModuleIdentity[] memory);

function getFmspcTcbContentHash(TcbId id, bytes6 fmspc, uint32 version) external view returns (bytes32);

function getPckCert(
string calldata qeid,
string calldata platformCpuSvn,
Expand Down
2 changes: 1 addition & 1 deletion contracts/verifiers/V3QuoteVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ contract V3QuoteVerifier is QuoteVerifierBase, TCBInfoV2Base {
returns (bool success, bytes memory output)
{
uint256 offset = 2 + uint16(bytes2(outputBytes[0:2]));
success = checkCollateralHashes(offset + 72, outputBytes);
success = checkCollateralHashes(offset, outputBytes);
if (success) {
output = outputBytes[2:offset];
} else {
Expand Down
2 changes: 1 addition & 1 deletion contracts/verifiers/V4QuoteVerifier.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ contract V4QuoteVerifier is QuoteVerifierBase, TCBInfoV3Base, TDXModuleBase {

uint256 offset = 2 + uint16(bytes2(outputBytes[0:2]));

success = checkCollateralHashes(offset + 72, outputBytes);
success = checkCollateralHashes(offset, outputBytes);
if (success) {
output = outputBytes[2:offset];
} else {
Expand Down
2 changes: 1 addition & 1 deletion forge-test/utils/PCCSSetupBase.sol
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ abstract contract PCCSSetupBase is Test {

function qeIdDaoUpsert(uint256 quoteVersion, string memory path) internal {
EnclaveIdentityJsonObj memory identityJson = _readIdentityJson(path);
IdentityObj memory identity = enclaveIdHelper.parseIdentityString(identityJson.identityStr);
(IdentityObj memory identity,) = enclaveIdHelper.parseIdentityString(identityJson.identityStr);
enclaveIdDao.upsertEnclaveIdentity(uint256(identity.id), quoteVersion, identityJson);
}

Expand Down
Loading