src/securityPolicy.c
security_policy_t policyForSignTxOutputAddressParams(
        sign_tx_signingmode_t txSigningMode,
        const addressParams_t* params,
        const uint8_t networkId, const uint32_t protocolMagic,
        bool includeDatumHash
)
{
	DENY_UNLESS(isValidAddressParams(params));

	// only allow valid address types
	// and check network identification as appropriate
	switch (params->type) {

	case BYRON:
		DENY_IF(params->protocolMagic != protocolMagic);
		break;

	case REWARD_KEY:
	case REWARD_SCRIPT:
		// outputs must not contain reward addresses (true not only for HW wallets)
		DENY();
		break;

	default: // all Shelley types allowed in output
		DENY_IF(params->networkId != networkId);
		break;
	}

	{
		// outputs to a different account within this HW wallet,
		// or to a different wallet, should be given as raw address bytes

		// this captures the essence of a change output: money stays
		// on an address where payment is fully controlled by this device
		DENY_UNLESS(determineSpendingChoice(params->type) == SPENDING_PATH);
		// Note: if we allowed script hash in spending part, we must add a warning
		// for missing datum (see policyForSignTxOutputAddressBytes)

		ASSERT(determineSpendingChoice(params->type) == SPENDING_PATH);
		DENY_IF(violatesSingleAccountOrStoreIt(&params->spendingKeyPath));
	}

	if (includeDatumHash) {
		// together with the above requirement on SPENDING_PATH,
		// this forbids datum in change outputs entirely
		DENY_UNLESS(allows_datum_hash(params->type));

		// no Plutus elements for pool registration, only allow in other modes
		DENY_UNLESS(
		        txSigningMode == SIGN_TX_SIGNINGMODE_ORDINARY_TX ||
		        txSigningMode == SIGN_TX_SIGNINGMODE_MULTISIG_TX ||
		        txSigningMode == SIGN_TX_SIGNINGMODE_PLUTUS_TX
		);
	}

	switch (txSigningMode) {

	case SIGN_TX_SIGNINGMODE_POOL_REGISTRATION_OPERATOR:
	case SIGN_TX_SIGNINGMODE_ORDINARY_TX: {
		// unusual paths or spending and staking path mismatch
		SHOW_UNLESS(is_standard_base_address(params));

		// outputs (eUTXOs) with datum hash are not interchangeable
		SHOW_IF(includeDatumHash);

		// it is safe to hide the remaining change outputs
		ALLOW();
		break;
	}

	case SIGN_TX_SIGNINGMODE_MULTISIG_TX: {
		// for simplicity, all outputs should be given as external addresses;
		// generally, more than one party is needed to sign
		// spending from a multisig address, so we do not expect
		// there will be 1852 outputs (that would be considered change)
		DENY();
		break;
	}

	case SIGN_TX_SIGNINGMODE_PLUTUS_TX: {
		// the output could affect script validation so it must not be entirely hidden
		// Note: if we relax this, some of the above restrictions may apply
		SHOW();
		break;
	}

	case SIGN_TX_SIGNINGMODE_POOL_REGISTRATION_OWNER: {
		// we forbid these to avoid leaking information
		// (since the outputs are not shown, the user is unaware of what addresses are being derived)
		// it also makes the tx signing faster if all outputs are given as addresses
		DENY();
		break;
	}

	default:
		ASSERT(false);
	}

	DENY(); // should not be reached
}
// For each output given by payment derivation path
For each output given by payment derivation path
For each output given by payment derivation path
security_policy_t policyForSignTxOutputAddressParams(
        sign_tx_signingmode_t txSigningMode,
        const addressParams_t* params,
        const uint8_t networkId, const uint32_t protocolMagic,
        bool includeDatumHash
)
{
	DENY_UNLESS(isValidAddressParams(params));
	switch (params->type) {
	case BYRON:
		DENY_IF(params->protocolMagic != protocolMagic);
		break;
	case REWARD_KEY:
	case REWARD_SCRIPT:
		DENY();
		break;
	default: 
		DENY_IF(params->networkId != networkId);
		break;
	}
	{
		DENY_UNLESS(determineSpendingChoice(params->type) == SPENDING_PATH);
		ASSERT(determineSpendingChoice(params->type) == SPENDING_PATH);
		DENY_IF(violatesSingleAccountOrStoreIt(&params->spendingKeyPath));
	}
	if (includeDatumHash) {
		DENY_UNLESS(allows_datum_hash(params->type));
		DENY_UNLESS(
		        txSigningMode == SIGN_TX_SIGNINGMODE_ORDINARY_TX ||
		        txSigningMode == SIGN_TX_SIGNINGMODE_MULTISIG_TX ||
		        txSigningMode == SIGN_TX_SIGNINGMODE_PLUTUS_TX
		);
	}
	switch (txSigningMode) {
	case SIGN_TX_SIGNINGMODE_POOL_REGISTRATION_OPERATOR:
	case SIGN_TX_SIGNINGMODE_ORDINARY_TX: {
		SHOW_UNLESS(is_standard_base_address(params));
		SHOW_IF(includeDatumHash);
		ALLOW();
		break;
	}
	case SIGN_TX_SIGNINGMODE_MULTISIG_TX: {
		DENY();
		break;
	}
	case SIGN_TX_SIGNINGMODE_PLUTUS_TX: {
		SHOW();
		break;
	}
	case SIGN_TX_SIGNINGMODE_POOL_REGISTRATION_OWNER: {
		DENY();
		break;
	}
	default:
		ASSERT(false);
	}
	DENY(); 
}
security_policy_t policyForSignTxOutputAddressParams ( sign_tx_signingmode_t txSigningMode , const addressParams_t * params , const uint8_t networkId , const uint32_t protocolMagic , bool includeDatumHash ) { DENY_UNLESS ( isValidAddressParams ( params ) ) ; switch ( params -> type ) { case BYRON : DENY_IF ( params -> protocolMagic != protocolMagic ) ; break ; case REWARD_KEY : case REWARD_SCRIPT : DENY ( ) ; break ; default : DENY_IF ( params -> networkId != networkId ) ; break ; } { DENY_UNLESS ( determineSpendingChoice ( params -> type ) == SPENDING_PATH ) ; ASSERT ( determineSpendingChoice ( params -> type ) == SPENDING_PATH ) ; DENY_IF ( violatesSingleAccountOrStoreIt ( & params -> spendingKeyPath ) ) ; } if ( includeDatumHash ) { DENY_UNLESS ( allows_datum_hash ( params -> type ) ) ; DENY_UNLESS ( txSigningMode == SIGN_TX_SIGNINGMODE_ORDINARY_TX || txSigningMode == SIGN_TX_SIGNINGMODE_MULTISIG_TX || txSigningMode == SIGN_TX_SIGNINGMODE_PLUTUS_TX ) ; } switch ( txSigningMode ) { case SIGN_TX_SIGNINGMODE_POOL_REGISTRATION_OPERATOR : case SIGN_TX_SIGNINGMODE_ORDINARY_TX : { SHOW_UNLESS ( is_standard_base_address ( params ) ) ; SHOW_IF ( includeDatumHash ) ; ALLOW ( ) ; break ; } case SIGN_TX_SIGNINGMODE_MULTISIG_TX : { DENY ( ) ; break ; } case SIGN_TX_SIGNINGMODE_PLUTUS_TX : { SHOW ( ) ; break ; } case SIGN_TX_SIGNINGMODE_POOL_REGISTRATION_OWNER : { DENY ( ) ; break ; } default : ASSERT ( false ) ; } DENY ( ) ; }
For each output given by payment derivation path
For each output given by payment derivation path
// only allow valid address types // and check network identification as appropriate // outputs must not contain reward addresses (true not only for HW wallets) // all Shelley types allowed in output // outputs to a different account within this HW wallet, // or to a different wallet, should be given as raw address bytes // this captures the essence of a change output: money stays // on an address where payment is fully controlled by this device // Note: if we allowed script hash in spending part, we must add a warning // for missing datum (see policyForSignTxOutputAddressBytes) // together with the above requirement on SPENDING_PATH, // this forbids datum in change outputs entirely // no Plutus elements for pool registration, only allow in other modes // unusual paths or spending and staking path mismatch // outputs (eUTXOs) with datum hash are not interchangeable // it is safe to hide the remaining change outputs // for simplicity, all outputs should be given as external addresses; // generally, more than one party is needed to sign // spending from a multisig address, so we do not expect // there will be 1852 outputs (that would be considered change) // the output could affect script validation so it must not be entirely hidden // Note: if we relax this, some of the above restrictions may apply // we forbid these to avoid leaking information // (since the outputs are not shown, the user is unaware of what addresses are being derived) // it also makes the tx signing faster if all outputs are given as addresses // should not be reached